diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out index 34db7f5..58325d7 100644 --- a/contrib/hstore/expected/hstore.out +++ b/contrib/hstore/expected/hstore.out @@ -712,137 +712,137 @@ select pg_column_size(''::hstore || 'aa=>1, b=>2'::hstore) t (1 row) --- => -select 'a=>g, b=>c'::hstore || ( 'asd'=>'gf' ); +-- ==> +select 'a=>g, b=>c'::hstore || ( 'asd'==>'gf' ); ?column? --------------------------------- "a"=>"g", "b"=>"c", "asd"=>"gf" (1 row) -select 'a=>g, b=>c'::hstore || ( 'b'=>'gf' ); +select 'a=>g, b=>c'::hstore || ( 'b'==>'gf' ); ?column? --------------------- "a"=>"g", "b"=>"gf" (1 row) -select 'a=>g, b=>c'::hstore || ( 'b'=>'NULL' ); +select 'a=>g, b=>c'::hstore || ( 'b'==>'NULL' ); ?column? ----------------------- "a"=>"g", "b"=>"NULL" (1 row) -select 'a=>g, b=>c'::hstore || ( 'b'=>NULL ); +select 'a=>g, b=>c'::hstore || ( 'b'==>NULL ); ?column? --------------------- "a"=>"g", "b"=>NULL (1 row) -select ('a=>g, b=>c'::hstore || ( NULL=>'b' )) is null; +select ('a=>g, b=>c'::hstore || ( NULL==>'b' )) is null; ?column? ---------- t (1 row) -select pg_column_size(('b'=>'gf')) +select pg_column_size(('b'==>'gf')) = pg_column_size('b=>gf'::hstore); ?column? ---------- t (1 row) -select pg_column_size('a=>g, b=>c'::hstore || ('b'=>'gf')) +select pg_column_size('a=>g, b=>c'::hstore || ('b'==>'gf')) = pg_column_size('a=>g, b=>gf'::hstore); ?column? ---------- t (1 row) --- => arrays -select ARRAY['a','b','asd'] => ARRAY['g','h','i']; +-- ==> arrays +select ARRAY['a','b','asd'] ==> ARRAY['g','h','i']; ?column? -------------------------------- "a"=>"g", "b"=>"h", "asd"=>"i" (1 row) -select ARRAY['a','b','asd'] => ARRAY['g','h',NULL]; +select ARRAY['a','b','asd'] ==> ARRAY['g','h',NULL]; ?column? --------------------------------- "a"=>"g", "b"=>"h", "asd"=>NULL (1 row) -select ARRAY['z','y','x'] => ARRAY['1','2','3']; +select ARRAY['z','y','x'] ==> ARRAY['1','2','3']; ?column? ------------------------------ "x"=>"3", "y"=>"2", "z"=>"1" (1 row) -select ARRAY['aaa','bb','c','d'] => ARRAY[null::text,null,null,null]; +select ARRAY['aaa','bb','c','d'] ==> ARRAY[null::text,null,null,null]; ?column? ----------------------------------------------- "c"=>NULL, "d"=>NULL, "bb"=>NULL, "aaa"=>NULL (1 row) -select ARRAY['aaa','bb','c','d'] => null; +select ARRAY['aaa','bb','c','d'] ==> null; ?column? ----------------------------------------------- "c"=>NULL, "d"=>NULL, "bb"=>NULL, "aaa"=>NULL (1 row) -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['g','h','i']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['g','h','i']; ?column? ---------- (1 row) -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b']; ?column? -------------------- "b"=>"2", "c"=>"3" (1 row) -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['aa','b']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['aa','b']; ?column? --------------------- "b"=>"2", "aa"=>"1" (1 row) -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b','aa']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b','aa']; ?column? ------------------------------- "b"=>"2", "c"=>"3", "aa"=>"1" (1 row) -select quote_literal('{}'::text[] => '{}'::text[]); +select quote_literal('{}'::text[] ==> '{}'::text[]); quote_literal --------------- '' (1 row) -select quote_literal('{}'::text[] => null); +select quote_literal('{}'::text[] ==> null); quote_literal --------------- '' (1 row) -select ARRAY['a'] => '{}'::text[]; -- error +select ARRAY['a'] ==> '{}'::text[]; -- error ERROR: arrays must have same bounds -select '{}'::text[] => ARRAY['a']; -- error +select '{}'::text[] ==> ARRAY['a']; -- error ERROR: arrays must have same bounds -select pg_column_size(ARRAY['a','b','asd'] => ARRAY['g','h','i']) +select pg_column_size(ARRAY['a','b','asd'] ==> ARRAY['g','h','i']) = pg_column_size('a=>g, b=>h, asd=>i'::hstore); ?column? ---------- t (1 row) -select pg_column_size(hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b']) +select pg_column_size(hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b']) = pg_column_size('b=>2, c=>3'::hstore); ?column? ---------- t (1 row) -select pg_column_size(hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b','aa']) +select pg_column_size(hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b','aa']) = pg_column_size('aa=>1, b=>2, c=>3'::hstore); ?column? ---------- @@ -948,45 +948,45 @@ select pg_column_size(hstore(v)) t (1 row) -select populate_record(v, ('c' => '3.45')) from testhstore1 v; +select populate_record(v, ('c' ==> '3.45')) from testhstore1 v; populate_record ------------------ (1,foo,3.45,3,0) (1 row) -select populate_record(v, ('d' => '3.45')) from testhstore1 v; +select populate_record(v, ('d' ==> '3.45')) from testhstore1 v; populate_record -------------------- (1,foo,1.2,3.45,0) (1 row) -select populate_record(v, ('e' => '123')) from testhstore1 v; +select populate_record(v, ('e' ==> '123')) from testhstore1 v; populate_record ------------------- (1,foo,1.2,3,123) (1 row) -select populate_record(v, ('e' => null)) from testhstore1 v; +select populate_record(v, ('e' ==> null)) from testhstore1 v; ERROR: domain hstestdom1 does not allow null values -select populate_record(v, ('c' => null)) from testhstore1 v; +select populate_record(v, ('c' ==> null)) from testhstore1 v; populate_record ----------------- (1,foo,,3,0) (1 row) -select populate_record(v, ('b' => 'foo') || ('a' => '123')) from testhstore1 v; +select populate_record(v, ('b' ==> 'foo') || ('a' ==> '123')) from testhstore1 v; populate_record ------------------- (123,foo,1.2,3,0) (1 row) -select populate_record(v, ('b' => 'foo') || ('e' => null)) from testhstore0 v; +select populate_record(v, ('b' ==> 'foo') || ('e' ==> null)) from testhstore0 v; populate_record ----------------- (1,foo,1.2,3) (1 row) -select populate_record(v, ('b' => 'foo') || ('e' => null)) from testhstore1 v; +select populate_record(v, ('b' ==> 'foo') || ('e' ==> null)) from testhstore1 v; ERROR: domain hstestdom1 does not allow null values select populate_record(v, '') from testhstore0 v; populate_record @@ -1000,9 +1000,9 @@ select populate_record(v, '') from testhstore1 v; (1,foo,1.2,3,0) (1 row) -select populate_record(null::testhstore1, ('c' => '3.45') || ('a' => '123')); +select populate_record(null::testhstore1, ('c' ==> '3.45') || ('a' ==> '123')); ERROR: domain hstestdom1 does not allow null values -select populate_record(null::testhstore1, ('c' => '3.45') || ('e' => '123')); +select populate_record(null::testhstore1, ('c' ==> '3.45') || ('e' ==> '123')); populate_record ----------------- (,,3.45,,123) @@ -1016,45 +1016,45 @@ select populate_record(null::testhstore0, ''); select populate_record(null::testhstore1, ''); ERROR: domain hstestdom1 does not allow null values -select v #= ('c' => '3.45') from testhstore1 v; +select v #= ('c' ==> '3.45') from testhstore1 v; ?column? ------------------ (1,foo,3.45,3,0) (1 row) -select v #= ('d' => '3.45') from testhstore1 v; +select v #= ('d' ==> '3.45') from testhstore1 v; ?column? -------------------- (1,foo,1.2,3.45,0) (1 row) -select v #= ('e' => '123') from testhstore1 v; +select v #= ('e' ==> '123') from testhstore1 v; ?column? ------------------- (1,foo,1.2,3,123) (1 row) -select v #= ('c' => null) from testhstore1 v; +select v #= ('c' ==> null) from testhstore1 v; ?column? -------------- (1,foo,,3,0) (1 row) -select v #= ('e' => null) from testhstore0 v; +select v #= ('e' ==> null) from testhstore0 v; ?column? --------------- (1,foo,1.2,3) (1 row) -select v #= ('e' => null) from testhstore1 v; +select v #= ('e' ==> null) from testhstore1 v; ERROR: domain hstestdom1 does not allow null values -select v #= (('b' => 'foo') || ('a' => '123')) from testhstore1 v; +select v #= (('b' ==> 'foo') || ('a' ==> '123')) from testhstore1 v; ?column? ------------------- (123,foo,1.2,3,0) (1 row) -select v #= (('b' => 'foo') || ('e' => '123')) from testhstore1 v; +select v #= (('b' ==> 'foo') || ('e' ==> '123')) from testhstore1 v; ?column? ------------------- (1,foo,1.2,3,123) @@ -1072,9 +1072,9 @@ select v #= hstore '' from testhstore1 v; (1,foo,1.2,3,0) (1 row) -select null::testhstore1 #= (('c' => '3.45') || ('a' => '123')); +select null::testhstore1 #= (('c' ==> '3.45') || ('a' ==> '123')); ERROR: domain hstestdom1 does not allow null values -select null::testhstore1 #= (('c' => '3.45') || ('e' => '123')); +select null::testhstore1 #= (('c' ==> '3.45') || ('e' ==> '123')); ?column? --------------- (,,3.45,,123) diff --git a/contrib/hstore/hstore.sql.in b/contrib/hstore/hstore.sql.in index 972557a..61e048f 100644 --- a/contrib/hstore/hstore.sql.in +++ b/contrib/hstore/hstore.sql.in @@ -66,6 +66,13 @@ RETURNS hstore AS 'MODULE_PATHNAME','hstore_slice_to_hstore' LANGUAGE C STRICT IMMUTABLE; +CREATE OPERATOR ==> ( + LEFTARG = hstore, + RIGHTARG = text[], + PROCEDURE = slice_hstore +); + +-- Deprecated. For backward compatibility. CREATE OPERATOR => ( LEFTARG = hstore, RIGHTARG = text[], @@ -227,6 +234,13 @@ RETURNS hstore AS 'MODULE_PATHNAME','hstore_from_text' LANGUAGE C IMMUTABLE; -- not STRICT; needs to allow (key,NULL) +CREATE OPERATOR ==> ( + LEFTARG = text, + RIGHTARG = text, + PROCEDURE = hstore +); + +-- Deprecated. For backward compatibility. CREATE OPERATOR => ( LEFTARG = text, RIGHTARG = text, @@ -238,6 +252,13 @@ RETURNS hstore AS 'MODULE_PATHNAME', 'hstore_from_arrays' LANGUAGE C IMMUTABLE; -- not STRICT; allows (keys,null) +CREATE OPERATOR ==> ( + LEFTARG = text[], + RIGHTARG = text[], + PROCEDURE = hstore +); + +-- Deprecated. For backward compatibility. CREATE OPERATOR => ( LEFTARG = text[], RIGHTARG = text[], diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql index a88ff1d..68f9033 100644 --- a/contrib/hstore/sql/hstore.sql +++ b/contrib/hstore/sql/hstore.sql @@ -160,36 +160,36 @@ select pg_column_size('aa=>1, b=>2'::hstore || ''::hstore) select pg_column_size(''::hstore || 'aa=>1, b=>2'::hstore) = pg_column_size('aa=>1, b=>2'::hstore); --- => -select 'a=>g, b=>c'::hstore || ( 'asd'=>'gf' ); -select 'a=>g, b=>c'::hstore || ( 'b'=>'gf' ); -select 'a=>g, b=>c'::hstore || ( 'b'=>'NULL' ); -select 'a=>g, b=>c'::hstore || ( 'b'=>NULL ); -select ('a=>g, b=>c'::hstore || ( NULL=>'b' )) is null; -select pg_column_size(('b'=>'gf')) +-- ==> +select 'a=>g, b=>c'::hstore || ( 'asd'==>'gf' ); +select 'a=>g, b=>c'::hstore || ( 'b'==>'gf' ); +select 'a=>g, b=>c'::hstore || ( 'b'==>'NULL' ); +select 'a=>g, b=>c'::hstore || ( 'b'==>NULL ); +select ('a=>g, b=>c'::hstore || ( NULL==>'b' )) is null; +select pg_column_size(('b'==>'gf')) = pg_column_size('b=>gf'::hstore); -select pg_column_size('a=>g, b=>c'::hstore || ('b'=>'gf')) +select pg_column_size('a=>g, b=>c'::hstore || ('b'==>'gf')) = pg_column_size('a=>g, b=>gf'::hstore); --- => arrays -select ARRAY['a','b','asd'] => ARRAY['g','h','i']; -select ARRAY['a','b','asd'] => ARRAY['g','h',NULL]; -select ARRAY['z','y','x'] => ARRAY['1','2','3']; -select ARRAY['aaa','bb','c','d'] => ARRAY[null::text,null,null,null]; -select ARRAY['aaa','bb','c','d'] => null; -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['g','h','i']; -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b']; -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['aa','b']; -select hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b','aa']; -select quote_literal('{}'::text[] => '{}'::text[]); -select quote_literal('{}'::text[] => null); -select ARRAY['a'] => '{}'::text[]; -- error -select '{}'::text[] => ARRAY['a']; -- error -select pg_column_size(ARRAY['a','b','asd'] => ARRAY['g','h','i']) +-- ==> arrays +select ARRAY['a','b','asd'] ==> ARRAY['g','h','i']; +select ARRAY['a','b','asd'] ==> ARRAY['g','h',NULL]; +select ARRAY['z','y','x'] ==> ARRAY['1','2','3']; +select ARRAY['aaa','bb','c','d'] ==> ARRAY[null::text,null,null,null]; +select ARRAY['aaa','bb','c','d'] ==> null; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['g','h','i']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['aa','b']; +select hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b','aa']; +select quote_literal('{}'::text[] ==> '{}'::text[]); +select quote_literal('{}'::text[] ==> null); +select ARRAY['a'] ==> '{}'::text[]; -- error +select '{}'::text[] ==> ARRAY['a']; -- error +select pg_column_size(ARRAY['a','b','asd'] ==> ARRAY['g','h','i']) = pg_column_size('a=>g, b=>h, asd=>i'::hstore); -select pg_column_size(hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b']) +select pg_column_size(hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b']) = pg_column_size('b=>2, c=>3'::hstore); -select pg_column_size(hstore 'aa=>1, b=>2, c=>3' => ARRAY['c','b','aa']) +select pg_column_size(hstore 'aa=>1, b=>2, c=>3' ==> ARRAY['c','b','aa']) = pg_column_size('aa=>1, b=>2, c=>3'::hstore); -- array input @@ -221,32 +221,32 @@ select hstore(null::testhstore1); select pg_column_size(hstore(v)) = pg_column_size('a=>1, b=>"foo", c=>"1.2", d=>"3", e=>"0"'::hstore) from testhstore1 v; -select populate_record(v, ('c' => '3.45')) from testhstore1 v; -select populate_record(v, ('d' => '3.45')) from testhstore1 v; -select populate_record(v, ('e' => '123')) from testhstore1 v; -select populate_record(v, ('e' => null)) from testhstore1 v; -select populate_record(v, ('c' => null)) from testhstore1 v; -select populate_record(v, ('b' => 'foo') || ('a' => '123')) from testhstore1 v; -select populate_record(v, ('b' => 'foo') || ('e' => null)) from testhstore0 v; -select populate_record(v, ('b' => 'foo') || ('e' => null)) from testhstore1 v; +select populate_record(v, ('c' ==> '3.45')) from testhstore1 v; +select populate_record(v, ('d' ==> '3.45')) from testhstore1 v; +select populate_record(v, ('e' ==> '123')) from testhstore1 v; +select populate_record(v, ('e' ==> null)) from testhstore1 v; +select populate_record(v, ('c' ==> null)) from testhstore1 v; +select populate_record(v, ('b' ==> 'foo') || ('a' ==> '123')) from testhstore1 v; +select populate_record(v, ('b' ==> 'foo') || ('e' ==> null)) from testhstore0 v; +select populate_record(v, ('b' ==> 'foo') || ('e' ==> null)) from testhstore1 v; select populate_record(v, '') from testhstore0 v; select populate_record(v, '') from testhstore1 v; -select populate_record(null::testhstore1, ('c' => '3.45') || ('a' => '123')); -select populate_record(null::testhstore1, ('c' => '3.45') || ('e' => '123')); +select populate_record(null::testhstore1, ('c' ==> '3.45') || ('a' ==> '123')); +select populate_record(null::testhstore1, ('c' ==> '3.45') || ('e' ==> '123')); select populate_record(null::testhstore0, ''); select populate_record(null::testhstore1, ''); -select v #= ('c' => '3.45') from testhstore1 v; -select v #= ('d' => '3.45') from testhstore1 v; -select v #= ('e' => '123') from testhstore1 v; -select v #= ('c' => null) from testhstore1 v; -select v #= ('e' => null) from testhstore0 v; -select v #= ('e' => null) from testhstore1 v; -select v #= (('b' => 'foo') || ('a' => '123')) from testhstore1 v; -select v #= (('b' => 'foo') || ('e' => '123')) from testhstore1 v; +select v #= ('c' ==> '3.45') from testhstore1 v; +select v #= ('d' ==> '3.45') from testhstore1 v; +select v #= ('e' ==> '123') from testhstore1 v; +select v #= ('c' ==> null) from testhstore1 v; +select v #= ('e' ==> null) from testhstore0 v; +select v #= ('e' ==> null) from testhstore1 v; +select v #= (('b' ==> 'foo') || ('a' ==> '123')) from testhstore1 v; +select v #= (('b' ==> 'foo') || ('e' ==> '123')) from testhstore1 v; select v #= hstore '' from testhstore0 v; select v #= hstore '' from testhstore1 v; -select null::testhstore1 #= (('c' => '3.45') || ('a' => '123')); -select null::testhstore1 #= (('c' => '3.45') || ('e' => '123')); +select null::testhstore1 #= (('c' ==> '3.45') || ('a' ==> '123')); +select null::testhstore1 #= (('c' ==> '3.45') || ('e' ==> '123')); select null::testhstore0 #= hstore ''; select null::testhstore1 #= hstore ''; select v #= h from testhstore1 v, (values (hstore 'a=>123',1),('b=>foo,c=>3.21',2),('a=>null',3),('e=>123',4),('f=>blah',5)) x(h,i) order by i; diff --git a/contrib/hstore/uninstall_hstore.sql b/contrib/hstore/uninstall_hstore.sql index 27463b9..a273bf6 100644 --- a/contrib/hstore/uninstall_hstore.sql +++ b/contrib/hstore/uninstall_hstore.sql @@ -21,6 +21,9 @@ DROP OPERATOR @> ( hstore, hstore ); DROP OPERATOR <@ ( hstore, hstore ); DROP OPERATOR @ ( hstore, hstore ); DROP OPERATOR ~ ( hstore, hstore ); +DROP OPERATOR ==> ( text, text ); +DROP OPERATOR ==> ( text[], text[] ); +DROP OPERATOR ==> ( hstore, text[] ); DROP OPERATOR => ( text, text ); DROP OPERATOR => ( text[], text[] ); DROP OPERATOR => ( hstore, text[] ); diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 9c07cf3..83d68f8 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -88,6 +88,16 @@ DefineOperator(List *names, List *parameters) /* Convert list of names to a name and namespace */ oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName); + /* + * The SQL standard committee has decided that => should be used for + * named parameters; therefore, a future release of PostgreSQL will + * no longer allow this to be used as the name of a user-defined + * operator. For now, we just emit a warning. + */ + if (!strcmp(oprName, "=>")) + ereport(WARNING, + (errmsg("The use of => as an operator name is deprecated and may be disallowed in a future release."))); + /* Check we have creation rights in target namespace */ aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK)