Skip to content

Commit 26d3607

Browse files
committed
Merge branch 'master' into vodka
2 parents 597eb3e + f0c5735 commit 26d3607

File tree

3 files changed

+69
-17
lines changed

3 files changed

+69
-17
lines changed

expected/jsquery.out

+12
Original file line numberDiff line numberDiff line change
@@ -816,3 +816,15 @@ select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%=[5,6]';
816816
t
817817
(1 row)
818818

819+
select '"XXX"'::jsonb @@ '$="XXX"';
820+
?column?
821+
----------
822+
t
823+
(1 row)
824+
825+
select '"XXX"'::jsonb @@ '#.$="XXX"';
826+
?column?
827+
----------
828+
f
829+
(1 row)
830+

jsquery_op.c

+54-17
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@ compareNumeric(Numeric a, Numeric b)
3636

3737
}
3838

39+
#define jbvScalar jbvBinary
40+
static int
41+
JsonbType(JsonbValue *jb)
42+
{
43+
int type = jb->type;
44+
45+
if (jb->type == jbvBinary)
46+
{
47+
JsonbContainer *jbc = jb->val.binary.data;
48+
49+
if (jbc->header & JB_FSCALAR)
50+
type = jbvScalar;
51+
else if (jbc->header & JB_FOBJECT)
52+
type = jbvObject;
53+
else if (jbc->header & JB_FARRAY)
54+
type = jbvArray;
55+
else
56+
elog(ERROR, "Unknown container type: 0x%08x", jbc->header);
57+
}
58+
59+
return type;
60+
}
61+
3962
static bool
4063
recursiveAny(char *jqBase, int32 jqPos, JsonbValue *jb)
4164
{
@@ -46,7 +69,6 @@ recursiveAny(char *jqBase, int32 jqPos, JsonbValue *jb)
4669

4770
check_stack_depth();
4871

49-
5072
it = JsonbIteratorInit(jb->val.binary.data);
5173

5274
while(res == false && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
@@ -108,7 +130,7 @@ checkArrayEquality(char *jqBase, int32 jqPos, int32 type, JsonbValue *jb)
108130
JsonbIterator *it;
109131
JsonbValue v;
110132

111-
if (!(type == jqiArray && jb->type == jbvBinary))
133+
if (!(type == jqiArray && JsonbType(jb) == jbvArray))
112134
return false;
113135

114136
read_int32(nelems, jqBase, jqPos);
@@ -117,9 +139,7 @@ checkArrayEquality(char *jqBase, int32 jqPos, int32 type, JsonbValue *jb)
117139
it = JsonbIteratorInit(jb->val.binary.data);
118140

119141
r = JsonbIteratorNext(&it, &v, true);
120-
121-
if (r != WJB_BEGIN_ARRAY)
122-
return false;
142+
Assert(r == WJB_BEGIN_ARRAY);
123143

124144
if (v.val.array.nElems != nelems)
125145
return false;
@@ -168,7 +188,7 @@ executeArrayOp(char *jqBase, int32 jqPos, int32 type, int32 op, JsonbValue *jb)
168188
JsonbValue v;
169189
int32 nres = 0, nval = 0;
170190

171-
if (jb->type != jbvBinary)
191+
if (JsonbType(jb) != jbvArray)
172192
return false;
173193
if (type != jqiArray)
174194
return false;
@@ -280,7 +300,7 @@ executeExpr(char *jqBase, int32 jqPos, int32 op, JsonbValue *jb)
280300
switch(op)
281301
{
282302
case jqiEqual:
283-
if (jb->type == jbvBinary && type == jqiArray)
303+
if (JsonbType(jb) == jbvArray && type == jqiArray)
284304
return checkArrayEquality(jqBase, jqPos, type, jb);
285305
return checkEquality(jqBase, jqPos, type, jb);
286306
case jqiIn:
@@ -332,7 +352,7 @@ recursiveExecute(char *jqBase, int32 jqPos, JsonbValue *jb)
332352
res = ! recursiveExecute(jqBase, arg, jb);
333353
break;
334354
case jqiKey:
335-
if (jb->type == jbvBinary) {
355+
if (JsonbType(jb) == jbvObject) {
336356
int32 len;
337357
JsonbValue *v, key;
338358

@@ -356,11 +376,33 @@ recursiveExecute(char *jqBase, int32 jqPos, JsonbValue *jb)
356376
res = recursiveAny(jqBase, nextPos, jb);
357377
break;
358378
case jqiCurrent:
359-
res = recursiveExecute(jqBase, nextPos, jb);
379+
if (JsonbType(jb) == jbvScalar)
380+
{
381+
JsonbIterator *it;
382+
int32 r;
383+
JsonbValue v;
384+
385+
it = JsonbIteratorInit(jb->val.binary.data);
386+
387+
r = JsonbIteratorNext(&it, &v, true);
388+
Assert(r == WJB_BEGIN_ARRAY);
389+
Assert(v.val.array.rawScalar == 1);
390+
Assert(v.val.array.nElems == 1);
391+
392+
r = JsonbIteratorNext(&it, &v, true);
393+
Assert(r == WJB_ELEM);
394+
395+
res = recursiveExecute(jqBase, nextPos, &v);
396+
}
397+
else
398+
{
399+
res = recursiveExecute(jqBase, nextPos, jb);
400+
}
360401
break;
361402
case jqiAnyArray:
362403
Assert(nextPos != 0);
363-
if (jb->type == jbvBinary) {
404+
if (JsonbType(jb) == jbvArray)
405+
{
364406
JsonbIterator *it;
365407
int32 r;
366408
JsonbValue v;
@@ -369,17 +411,15 @@ recursiveExecute(char *jqBase, int32 jqPos, JsonbValue *jb)
369411

370412
while(res == false && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
371413
{
372-
if (r == WJB_BEGIN_OBJECT || r == WJB_KEY)
373-
break;
374-
375414
if (r == WJB_ELEM)
376415
res = recursiveExecute(jqBase, nextPos, &v);
377416
}
378417
}
379418
break;
380419
case jqiAnyKey:
381420
Assert(nextPos != 0);
382-
if (jb->type == jbvBinary) {
421+
if (JsonbType(jb) == jbvObject)
422+
{
383423
JsonbIterator *it;
384424
int32 r;
385425
JsonbValue v;
@@ -388,9 +428,6 @@ recursiveExecute(char *jqBase, int32 jqPos, JsonbValue *jb)
388428

389429
while(res == false && (r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE)
390430
{
391-
if (r == WJB_BEGIN_ARRAY || r == WJB_ELEM)
392-
break;
393-
394431
if (r == WJB_VALUE)
395432
res = recursiveExecute(jqBase, nextPos, &v);
396433
}

sql/jsquery.sql

+3
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,6 @@ select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ 'a.%=3';
160160
select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%.%="hey"';
161161
select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%="hey"';
162162
select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%=[5,6]';
163+
164+
select '"XXX"'::jsonb @@ '$="XXX"';
165+
select '"XXX"'::jsonb @@ '#.$="XXX"';

0 commit comments

Comments
 (0)