Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9bac660

Browse files
committed
Fix core dump in jsonb #> operator, and add regression test cases.
jsonb's #> operator segfaulted (dereferencing a null pointer) if the RHSwas a zero-length array, as reported in bug #11207 from Justin Van Winkle.json's #> operator returns NULL in such cases, so for the moment let'smake jsonb act likewise.Also add a bunch of regression test queries memorializing the -> and #>operators' behavior for this and other corner cases.There is a good argument for changing some of these behaviors, as theyare not very consistent with each other, and throwing an error isn'tnecessarily a desirable behavior for operators that are likely to beused in indexes. However, everybody can agree that a core dump is theWrong Thing, and we need test cases even if we decide to change theirexpected output later.
1 parent7567d94 commit9bac660

File tree

7 files changed

+711
-119
lines changed

7 files changed

+711
-119
lines changed

‎src/backend/utils/adt/jsonfuncs.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,13 @@ get_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
726726
deconstruct_array(path,TEXTOID,-1, false,'i',
727727
&pathtext,&pathnulls,&npath);
728728

729+
/*
730+
* If the array is empty, return NULL; this is dubious but it's what 9.3
731+
* did.
732+
*/
733+
if (npath <=0)
734+
PG_RETURN_NULL();
735+
729736
tpath=palloc(npath*sizeof(char*));
730737
ipath=palloc(npath*sizeof(int));
731738

@@ -1100,11 +1107,11 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
11001107
{
11011108
Jsonb*jb=PG_GETARG_JSONB(0);
11021109
ArrayType*path=PG_GETARG_ARRAYTYPE_P(1);
1110+
Jsonb*res;
11031111
Datum*pathtext;
11041112
bool*pathnulls;
11051113
intnpath;
11061114
inti;
1107-
Jsonb*res;
11081115
boolhave_object= false,
11091116
have_array= false;
11101117
JsonbValue*jbvp=NULL;
@@ -1120,6 +1127,13 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, const char *funcname, bool as_text)
11201127
deconstruct_array(path,TEXTOID,-1, false,'i',
11211128
&pathtext,&pathnulls,&npath);
11221129

1130+
/*
1131+
* If the array is empty, return NULL; this is dubious but it's what 9.3
1132+
* did.
1133+
*/
1134+
if (npath <=0)
1135+
PG_RETURN_NULL();
1136+
11231137
if (JB_ROOT_IS_OBJECT(jb))
11241138
have_object= true;
11251139
elseif (JB_ROOT_IS_ARRAY(jb)&& !JB_ROOT_IS_SCALAR(jb))

‎src/test/regress/expected/json.out

Lines changed: 166 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,45 @@ where json_type = 'array';
653653
t
654654
(1 row)
655655

656+
-- corner cases
657+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::text;
658+
?column?
659+
----------
660+
661+
(1 row)
662+
663+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> null::int;
664+
?column?
665+
----------
666+
667+
(1 row)
668+
669+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 1;
670+
ERROR: cannot extract array element from a non-array
671+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json -> 'z';
672+
?column?
673+
----------
674+
675+
(1 row)
676+
677+
select '[{"b": "c"}, {"b": "cc"}]'::json -> 1;
678+
?column?
679+
-------------
680+
{"b": "cc"}
681+
(1 row)
682+
683+
select '[{"b": "c"}, {"b": "cc"}]'::json -> 3;
684+
?column?
685+
----------
686+
687+
(1 row)
688+
689+
select '[{"b": "c"}, {"b": "cc"}]'::json -> 'z';
690+
ERROR: cannot extract field from a non-object
691+
select '"foo"'::json -> 1;
692+
ERROR: cannot extract element from a scalar
693+
select '"foo"'::json -> 'z';
694+
ERROR: cannot extract element from a scalar
656695
-- array length
657696
SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]');
658697
json_array_length
@@ -831,53 +870,161 @@ select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>array['f2','1'];
831870
1
832871
(1 row)
833872

834-
-- same using array literals
835-
select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>'{f4,f6}';
836-
?column?
837-
-----------
838-
"stringy"
873+
-- corner cases for same
874+
select '{"a": {"b":{"c": "foo"}}}'::json #> array[]::text[];
875+
?column?
876+
----------
877+
878+
(1 row)
879+
880+
select '{"a": {"b":{"c": "foo"}}}'::json #> array['a'];
881+
?column?
882+
--------------------
883+
{"b":{"c": "foo"}}
884+
(1 row)
885+
886+
select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b'];
887+
?column?
888+
--------------
889+
{"c": "foo"}
839890
(1 row)
840891

841-
select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>'{f2}';
892+
select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c'];
842893
?column?
843894
----------
844-
{"f3":1}
895+
"foo"
845896
(1 row)
846897

847-
select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>'{f2,0}';
898+
select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','b','c','d'];
848899
?column?
849900
----------
850-
"f3"
901+
851902
(1 row)
852903

853-
select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>'{f2,1}';
904+
select '{"a": {"b":{"c": "foo"}}}'::json #> array['a','z','c'];
854905
?column?
855906
----------
856-
1
907+
857908
(1 row)
858909

859-
select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>'{f4,f6}';
910+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','1','b'];
860911
?column?
861912
----------
862-
stringy
913+
"cc"
863914
(1 row)
864915

865-
select '{"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}}'::json#>>'{f2}';
916+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #> array['a','z','b'];
866917
?column?
867918
----------
868-
{"f3":1}
919+
869920
(1 row)
870921

871-
select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>'{f2,0}';
922+
select '[{"b": "c"}, {"b": "cc"}]'::json #> array['1','b'];
872923
?column?
873924
----------
874-
f3
925+
"cc"
875926
(1 row)
876927

877-
select '{"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}}'::json#>>'{f2,1}';
928+
select '[{"b": "c"}, {"b": "cc"}]'::json #> array['z','b'];
878929
?column?
879930
----------
880-
1
931+
932+
(1 row)
933+
934+
select '"foo"'::json #> array['z'];
935+
?column?
936+
----------
937+
938+
(1 row)
939+
940+
select '42'::json #> array['f2'];
941+
?column?
942+
----------
943+
944+
(1 row)
945+
946+
select '42'::json #> array['0'];
947+
?column?
948+
----------
949+
950+
(1 row)
951+
952+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array[]::text[];
953+
?column?
954+
----------
955+
956+
(1 row)
957+
958+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a'];
959+
?column?
960+
--------------------
961+
{"b":{"c": "foo"}}
962+
(1 row)
963+
964+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b'];
965+
?column?
966+
--------------
967+
{"c": "foo"}
968+
(1 row)
969+
970+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c'];
971+
?column?
972+
----------
973+
foo
974+
(1 row)
975+
976+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','b','c','d'];
977+
?column?
978+
----------
979+
980+
(1 row)
981+
982+
select '{"a": {"b":{"c": "foo"}}}'::json #>> array['a','z','c'];
983+
?column?
984+
----------
985+
986+
(1 row)
987+
988+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','1','b'];
989+
?column?
990+
----------
991+
cc
992+
(1 row)
993+
994+
select '{"a": [{"b": "c"}, {"b": "cc"}]}'::json #>> array['a','z','b'];
995+
?column?
996+
----------
997+
998+
(1 row)
999+
1000+
select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['1','b'];
1001+
?column?
1002+
----------
1003+
cc
1004+
(1 row)
1005+
1006+
select '[{"b": "c"}, {"b": "cc"}]'::json #>> array['z','b'];
1007+
?column?
1008+
----------
1009+
1010+
(1 row)
1011+
1012+
select '"foo"'::json #>> array['z'];
1013+
?column?
1014+
----------
1015+
1016+
(1 row)
1017+
1018+
select '42'::json #>> array['f2'];
1019+
?column?
1020+
----------
1021+
1022+
(1 row)
1023+
1024+
select '42'::json #>> array['0'];
1025+
?column?
1026+
----------
1027+
8811028
(1 row)
8821029

8831030
-- array_elements

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp