On Fri, Jun 5, 2015 at 10:51 AM, Andrew Dunstan <and...@dunslane.net> wrote:
>>> Also, what about negative array subscripting (making the 9.4-era
>>> "operator jsonb -> integer" operator support that for consistency with
>>> the new "operator jsonb - integer" operator)? Should I write the
>>> patch? Will you commit it if I do?

> Send the first one, I'm still thinking about the second one.

The first patch is attached.

Regardless of anything else, I see no reason to delay applying my
documentation patch for "operator jsonb - text" [1].

Thanks

[1] 
http://www.postgresql.org/message-id/cam3swzqfswmi2avi-lun_jbyh-rfhq3-0fm8txpw8olc+v8...@mail.gmail.com
-- 
Peter Geoghegan
From 6513017eabbd4bdd4980056ed73ca8e3fbe58d1b Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <peter.geoghega...@gmail.com>
Date: Fri, 5 Jun 2015 13:55:48 -0700
Subject: [PATCH] Desupport jsonb subscript deletion on objects

Supporting deletion of JSON pairs within jsonb objects using an
array-style integer subscript allowed for surprising outcomes.  This was
mostly due to the implementation-defined ordering of pairs within
objects for jsonb.

It also seems desirable to make jsonb integer subscript deletion
consistent with the 9.4 era general purpose integer subscripting
operator for jsonb (although that operator returns NULL when an object
is encountered, while we prefer to throw an error).
---
 doc/src/sgml/func.sgml                |  5 ++--
 src/backend/utils/adt/jsonfuncs.c     |  5 ++++
 src/test/regress/expected/jsonb.out   | 56 ++---------------------------------
 src/test/regress/expected/jsonb_1.out | 56 ++---------------------------------
 src/test/regress/sql/jsonb.sql        | 11 +------
 5 files changed, 13 insertions(+), 120 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index c6e3540..be0c3d6 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -10309,8 +10309,9 @@ table2-mapping
        <row>
         <entry><literal>-</literal></entry>
         <entry><type>integer</type></entry>
-        <entry>Delete the field or element with specified index (Negative
-        integers count from the end)</entry>
+        <entry>Delete the array element with specified index (Negative
+        integers count from the end).  Throws an error if top level
+        container is not an array.</entry>
         <entry><literal>'["a", "b"]'::jsonb - 1 </literal></entry>
        </row>
        <row>
diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c
index f87ba77..c14d3f7 100644
--- a/src/backend/utils/adt/jsonfuncs.c
+++ b/src/backend/utils/adt/jsonfuncs.c
@@ -3400,6 +3400,11 @@ jsonb_delete_idx(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("cannot delete from scalar")));
 
+	if (JB_ROOT_IS_OBJECT(in))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("cannot delete from object using integer subscript")));
+
 	if (JB_ROOT_COUNT(in) == 0)
 		PG_RETURN_JSONB(in);
 
diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out
index 412bf97..e6654d4 100644
--- a/src/test/regress/expected/jsonb.out
+++ b/src/test/regress/expected/jsonb.out
@@ -3031,54 +3031,6 @@ select '["a","b","c"]'::jsonb - -4;
  ["a", "b", "c"]
 (1 row)
 
-select '{"a":1, "b":2, "c":3}'::jsonb - 3;
-         ?column?         
---------------------------
- {"a": 1, "b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 2;
-     ?column?     
-------------------
- {"a": 1, "b": 2}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 1;
-     ?column?     
-------------------
- {"a": 1, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 0;
-     ?column?     
-------------------
- {"b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -1;
-     ?column?     
-------------------
- {"a": 1, "b": 2}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -2;
-     ?column?     
-------------------
- {"a": 1, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -3;
-     ?column?     
-------------------
- {"b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -4;
-         ?column?         
---------------------------
- {"a": 1, "b": 2, "c": 3}
-(1 row)
-
 select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]');
                                 jsonb_set                                 
 --------------------------------------------------------------------------
@@ -3192,12 +3144,8 @@ select '[]'::jsonb - 'a';
 
 select '"a"'::jsonb - 1; -- error
 ERROR:  cannot delete from scalar
-select '{}'::jsonb -  1 ;
- ?column? 
-----------
- {}
-(1 row)
-
+select '{}'::jsonb -  1; -- error
+ERROR:  cannot delete from object using integer subscript
 select '[]'::jsonb - 1;
  ?column? 
 ----------
diff --git a/src/test/regress/expected/jsonb_1.out b/src/test/regress/expected/jsonb_1.out
index 4ead74b..0a1ec93 100644
--- a/src/test/regress/expected/jsonb_1.out
+++ b/src/test/regress/expected/jsonb_1.out
@@ -3031,54 +3031,6 @@ select '["a","b","c"]'::jsonb - -4;
  ["a", "b", "c"]
 (1 row)
 
-select '{"a":1, "b":2, "c":3}'::jsonb - 3;
-         ?column?         
---------------------------
- {"a": 1, "b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 2;
-     ?column?     
-------------------
- {"a": 1, "b": 2}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 1;
-     ?column?     
-------------------
- {"a": 1, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - 0;
-     ?column?     
-------------------
- {"b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -1;
-     ?column?     
-------------------
- {"a": 1, "b": 2}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -2;
-     ?column?     
-------------------
- {"a": 1, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -3;
-     ?column?     
-------------------
- {"b": 2, "c": 3}
-(1 row)
-
-select '{"a":1, "b":2, "c":3}'::jsonb - -4;
-         ?column?         
---------------------------
- {"a": 1, "b": 2, "c": 3}
-(1 row)
-
 select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]');
                                 jsonb_set                                 
 --------------------------------------------------------------------------
@@ -3192,12 +3144,8 @@ select '[]'::jsonb - 'a';
 
 select '"a"'::jsonb - 1; -- error
 ERROR:  cannot delete from scalar
-select '{}'::jsonb -  1 ;
- ?column? 
-----------
- {}
-(1 row)
-
+select '{}'::jsonb -  1; -- error
+ERROR:  cannot delete from object using integer subscript
 select '[]'::jsonb - 1;
  ?column? 
 ----------
diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql
index 2abec22..29c82a2 100644
--- a/src/test/regress/sql/jsonb.sql
+++ b/src/test/regress/sql/jsonb.sql
@@ -738,15 +738,6 @@ select '["a","b","c"]'::jsonb - -2;
 select '["a","b","c"]'::jsonb - -3;
 select '["a","b","c"]'::jsonb - -4;
 
-select '{"a":1, "b":2, "c":3}'::jsonb - 3;
-select '{"a":1, "b":2, "c":3}'::jsonb - 2;
-select '{"a":1, "b":2, "c":3}'::jsonb - 1;
-select '{"a":1, "b":2, "c":3}'::jsonb - 0;
-select '{"a":1, "b":2, "c":3}'::jsonb - -1;
-select '{"a":1, "b":2, "c":3}'::jsonb - -2;
-select '{"a":1, "b":2, "c":3}'::jsonb - -3;
-select '{"a":1, "b":2, "c":3}'::jsonb - -4;
-
 select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{n}', '[1,2,3]');
 select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{b,-1}', '[1,2,3]');
 select jsonb_set('{"n":null, "a":1, "b":[1,2], "c":{"1":2}, "d":{"1":[2,3]}}'::jsonb, '{d,1,0}', '[1,2,3]');
@@ -775,7 +766,7 @@ select '"a"'::jsonb - 'a'; -- error
 select '{}'::jsonb - 'a';
 select '[]'::jsonb - 'a';
 select '"a"'::jsonb - 1; -- error
-select '{}'::jsonb -  1 ;
+select '{}'::jsonb -  1; -- error
 select '[]'::jsonb - 1;
 select '"a"'::jsonb - '{a}'::text[]; -- error
 select '{}'::jsonb - '{a}'::text[];
-- 
1.9.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to