Skip to content

Commit f0c5735

Browse files
committed
$="XXX" for scalars
1 parent c69a4df commit f0c5735

File tree

3 files changed

+69
-17
lines changed

3 files changed

+69
-17
lines changed

expected/jsquery.out

Lines changed: 12 additions & 0 deletions
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

Lines changed: 54 additions & 17 deletions
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

Lines changed: 3 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy