This is a PostgreSQL error. I submitted your report to the pgsql-bugs list .
What happens when pg_dump sets search_path to public exception when creating tables in your schema. This is normal. When it discards objects that are related to things that are not related to search_path , it explicitly schematizes them for them to work.
It works for the case = , because pg_dump sees that = is actually OPERATOR(public.=) In this case and unloads it in this form:
CREATE VIEW hstore_test_view AS SELECT (hstore_test_table.column1 OPERATOR(public.=) hstore_test_table.column2) AS comparison FROM hstore_test_table;
however, pg_dump does not do this for a statement implicitly used with the nullif nullif . This leads to the following sequence of dummy commands:
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public; ... SET search_path = hstore_test_schema, pg_catalog; ... CREATE VIEW hstore_test_view AS SELECT NULLIF(hstore_test_table.column1, hstore_test_table.column2) AS comparison FROM hstore_test_table;
pg_dump simply uses the pg_catalog.pg_get_viewdef function to dump the output, so this probably requires a fix for the server.
The simplest workaround is to use nullif , replacing it with a more verbose but equivalent case :
CASE WHEN column1 = column2 THEN NULL ELSE column1 END;
The syntax does not provide a way for the circuit to qualify the pseudo-functional nullif operator, as we do with explicit OPERATOR(public.=) , So the correction does not seem trivial.
I expected the same problem to affect GREATEST and LEAST , possibly also DISTINCT , but it is not. Both seem to find their required operators, even if they are not on the search_path at run time, but fail if the operator is not on the search_path during the definition of the view. This suggests that they are probably using a b-tree operator class to search for operators through a type entry in directories found through table attributes. (Update: sources checked and yes what they do). Presumably nullif should also do this, but it is not.
Instead, he dies in:
hstore_test=# \set VERBOSITY verbose hstore_test=# CREATE VIEW hstore_test_schema.hstore_test_view AS SELECT NULLIF(column1, column2) AS comparison FROM hstore_test_schema.hstore_test_table; ERROR: 42883: operator does not exist: public.hstore = public.hstore LINE 2: SELECT NULLIF(column1, column2) AS comparison FROM hstore_te... ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. LOCATION: op_error, parse_oper.c:722
which, when I set a breakpoint there, traps when:
Breakpoint 1, op_error ( pstate=pstate@entry =0x1189f38, op=op@entry =0x1189c10, oprkind=oprkind@entry =98 'b', arg1=arg1@entry =97207, arg2=arg2@entry =97207, fdresult=FUNCDETAIL_NOTFOUND, location=location@entry =58) at parse_oper.c:706 706 { (gdb) bt
so the immediate problem looks like this: transformAExprNullIf cannot find the statement using its operand type via b-tree opclass and typecache.