Clarify point in some jsonfuncs.c operator functions
authorPeter Geoghegan <[email protected]>
Sat, 15 Mar 2014 08:45:59 +0000 (01:45 -0700)
committerPeter Geoghegan <[email protected]>
Sat, 15 Mar 2014 08:45:59 +0000 (01:45 -0700)
The danger of this error message causing confusion is quite acute if we
assume that expressional indexing will be used extensively, because the
restriction on, say, calling the "jsonb -> text" operator only on what
jsonb internally knows to be an object effectively makes every such
expressional index a constraint on same (at least without some further
care).

Note this general risk in the documentation, too.

doc/src/sgml/json.sgml
src/backend/utils/adt/jsonfuncs.c
src/test/regress/expected/jsonb.out
src/test/regress/expected/jsonb_1.out

index 2cc906122113bf78f515bc910bd15ce88ed9e408..9c5fb4d005431e9888fc8830397f60afdf632b5b 100644 (file)
@@ -266,6 +266,9 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
     high cardinality across all documents, defining an index as
     follows is an effective approach to indexing:
   <programlisting>
+-- Note that the "jsonb -> text" operator can only be called on an
+-- object, and as a consequence the root "jdoc" datum must be an
+-- object.  This is enforced during insertion.
 CREATE INDEX idxgin ON api USING GIN ((jdoc -> 'tags'));
   </programlisting>
   </para>
index 75d44367a5cd097b3f028873c5811557df99e01e..244022bbc91614c982f0bf8706932cb57adf33ff 100644 (file)
@@ -259,7 +259,7 @@ jsonb_object_keys(PG_FUNCTION_ARGS)
        bool        skipNested = false;
        JsonbIterator *it;
        JsonbValue  v;
-       int         r = 0;
+       int         r;
 
        if (JB_ROOT_IS_SCALAR(jb))
            ereport(ERROR,
@@ -464,17 +464,17 @@ jsonb_object_field(PG_FUNCTION_ARGS)
    int         klen = strlen(key);
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = WJB_DONE;
+   int         r;
    bool        skipNested = false;
 
    if (JB_ROOT_IS_SCALAR(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_object_field on a scalar")));
+                errmsg("cannot call jsonb_object_field (jsonb -> text operator) on a scalar")));
    else if (JB_ROOT_IS_ARRAY(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_object_field on an array")));
+                errmsg("cannot call jsonb_object_field (jsonb -> text operator) on an array")));
 
    Assert(JB_ROOT_IS_OBJECT(jb));
 
@@ -525,17 +525,17 @@ jsonb_object_field_text(PG_FUNCTION_ARGS)
    int         klen = strlen(key);
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = 0;
+   int         r;
    bool        skipNested = false;
 
    if (JB_ROOT_IS_SCALAR(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_object_field_text on a scalar")));
+                errmsg("cannot call jsonb_object_field_text (jsonb ->> text operator) on a scalar")));
    else if (JB_ROOT_IS_ARRAY(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_object_field_text on an array")));
+                errmsg("cannot call jsonb_object_field_text (jsonb ->> text operator) on an array")));
 
    Assert(JB_ROOT_IS_OBJECT(jb));
 
@@ -607,18 +607,18 @@ jsonb_array_element(PG_FUNCTION_ARGS)
    int         element = PG_GETARG_INT32(1);
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = WJB_DONE;
+   int         r;
    bool        skipNested = false;
    int         element_number = 0;
 
    if (JB_ROOT_IS_SCALAR(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_array_element on a scalar")));
+                errmsg("cannot call jsonb_array_element (jsonb -> int operator) on a scalar")));
    else if (JB_ROOT_IS_OBJECT(jb))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                errmsg("cannot call jsonb_array_element on an object")));
+                errmsg("cannot call jsonb_array_element (jsonb -> int operator) on an object")));
 
    Assert(JB_ROOT_IS_ARRAY(jb));
 
@@ -660,7 +660,7 @@ jsonb_array_element_text(PG_FUNCTION_ARGS)
    int         element = PG_GETARG_INT32(1);
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = 0;
+   int         r;
    bool        skipNested = false;
    int         element_number = 0;
 
@@ -1397,7 +1397,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, bool as_text)
    bool        skipNested = false;
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = 0;
+   int         r;
 
    if (!JB_ROOT_IS_OBJECT(jb))
        ereport(ERROR,
@@ -1722,7 +1722,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, bool as_text)
    bool        skipNested = false;
    JsonbIterator *it;
    JsonbValue  v;
-   int         r = 0;
+   int         r;
 
    if (JB_ROOT_IS_SCALAR(jb))
        ereport(ERROR,
index 709219658daf898ea3aba113a7ab32a1266a6bd4..18c702886cbc42f32a5e6f84af09ea4cddfc5969 100644 (file)
@@ -311,9 +311,9 @@ INSERT INTO test_jsonb VALUES
 ('array','["zero", "one","two",null,"four","five"]'),
 ('object','{"field1":"val1","field2":"val2","field3":null}');
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_object_field on a scalar
+ERROR:  cannot call jsonb_object_field (jsonb -> text operator) on a scalar
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array';
-ERROR:  cannot call jsonb_object_field on an array
+ERROR:  cannot call jsonb_object_field (jsonb -> text operator) on an array
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object';
  ?column? 
 ----------
@@ -327,9 +327,9 @@ SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object';
 (1 row)
 
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_object_field_text on a scalar
+ERROR:  cannot call jsonb_object_field_text (jsonb ->> text operator) on a scalar
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array';
-ERROR:  cannot call jsonb_object_field_text on an array
+ERROR:  cannot call jsonb_object_field_text (jsonb ->> text operator) on an array
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object';
  ?column? 
 ----------
@@ -337,7 +337,7 @@ SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object';
 (1 row)
 
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_array_element on a scalar
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on a scalar
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array';
  ?column? 
 ----------
@@ -351,7 +351,7 @@ SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array';
 (1 row)
 
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object';
-ERROR:  cannot call jsonb_array_element on an object
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on an object
 SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar';
 ERROR:  cannot call jsonb_array_element_text on a scalar
 SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array';
@@ -1780,7 +1780,7 @@ SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'e';
 (1 row)
 
 SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 0; --expecting error
-ERROR:  cannot call jsonb_array_element on an object
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on an object
 SELECT '["a","b","c",[1,2],null]'::jsonb -> 0;
  ?column? 
 ----------
index 56e3240d82e61a668ea4aacec304f0b7c9fe1aa3..7cd34dbf4e7803d43d41a4711e638af8ca58e443 100644 (file)
@@ -311,9 +311,9 @@ INSERT INTO test_jsonb VALUES
 ('array','["zero", "one","two",null,"four","five"]'),
 ('object','{"field1":"val1","field2":"val2","field3":null}');
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_object_field on a scalar
+ERROR:  cannot call jsonb_object_field (jsonb -> text operator) on a scalar
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'array';
-ERROR:  cannot call jsonb_object_field on an array
+ERROR:  cannot call jsonb_object_field (jsonb -> text operator) on an array
 SELECT test_json -> 'x' FROM test_jsonb WHERE json_type = 'object';
  ?column? 
 ----------
@@ -327,9 +327,9 @@ SELECT test_json -> 'field2' FROM test_jsonb WHERE json_type = 'object';
 (1 row)
 
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_object_field_text on a scalar
+ERROR:  cannot call jsonb_object_field_text (jsonb ->> text operator) on a scalar
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'array';
-ERROR:  cannot call jsonb_object_field_text on an array
+ERROR:  cannot call jsonb_object_field_text (jsonb ->> text operator) on an array
 SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object';
  ?column? 
 ----------
@@ -337,7 +337,7 @@ SELECT test_json ->> 'field2' FROM test_jsonb WHERE json_type = 'object';
 (1 row)
 
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'scalar';
-ERROR:  cannot call jsonb_array_element on a scalar
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on a scalar
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'array';
  ?column? 
 ----------
@@ -351,7 +351,7 @@ SELECT test_json -> 9 FROM test_jsonb WHERE json_type = 'array';
 (1 row)
 
 SELECT test_json -> 2 FROM test_jsonb WHERE json_type = 'object';
-ERROR:  cannot call jsonb_array_element on an object
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on an object
 SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'scalar';
 ERROR:  cannot call jsonb_array_element_text on a scalar
 SELECT test_json ->> 2 FROM test_jsonb WHERE json_type = 'array';
@@ -1780,7 +1780,7 @@ SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 'e';
 (1 row)
 
 SELECT '{"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}}'::jsonb -> 0; --expecting error
-ERROR:  cannot call jsonb_array_element on an object
+ERROR:  cannot call jsonb_array_element (jsonb -> int operator) on an object
 SELECT '["a","b","c",[1,2],null]'::jsonb -> 0;
  ?column? 
 ----------