Comparing nullable column values using "IS NULL" versus "= NULL" I'm dealing with nullable values in a column of a table, i'm wondering why this:

with cte as (
    select 'c1'::text as c1,null::text as c2
    union
    select 'c2'::text as c1,null::text as c2
)
select *
from cte
where c2 is null


returns a result set with the two "rows" having a null value in c2; comparting to this query:

with cte as (
    select 'c1'::text as c1,null::text as c2
    union
    select 'c2'::text as c1,null::text as c2
)
select *
from cte
where c2 = null


that returns an empty result set!!

so it looks like that field is null is actually different from field = null? the question is... is there "null-compatible operator" to use? so i can write the comparision like: column_name = $1 and argument $1 can be a not null or null value. IF $1 is a null value then it will semantically equals to write as IS NULL, ELSE (if $1 is not a null value) then it would be semantically equals to = $1.

P.D: This question also applies to the case is NOT NULL versus &lt;&gt; NULL
As documented in the manual it's not possible to use = to test for NULL values:


  Ordinary comparison operators yield null (signifying “unknown”), not true or false, when either input is null. For example, 7 = NULL yields null, as does 7 &lt;> NULL.


is there "null-compatible operator" to use - Yes, right below the above quote it states:


  When this behavior is not suitable, use the IS [ NOT ] DISTINCT FROM predicates


So you can use 

where c2 is not distinct from $1


One drawback of the IS DISTINCT or IS NOT DISTINCT operator is however, that they can't use an index.