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

Commitd57758a

Browse files
author
Nikita Glukhov
committed
fixup! add array/object length as @#
1 parentc624498 commitd57758a

File tree

3 files changed

+115
-106
lines changed

3 files changed

+115
-106
lines changed

‎expected/jsquery.out

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,30 @@ select '{"a":[1,2]}' @@ '@# = 1'::jsquery;
13911391
t
13921392
(1 row)
13931393

1394+
select '[]' @@ '@# is numeric'::jsquery;
1395+
?column?
1396+
----------
1397+
t
1398+
(1 row)
1399+
1400+
select '{}' @@ '@# is numeric'::jsquery;
1401+
?column?
1402+
----------
1403+
t
1404+
(1 row)
1405+
1406+
select '0' @@ '@# is numeric'::jsquery;
1407+
?column?
1408+
----------
1409+
f
1410+
(1 row)
1411+
1412+
select '0' @@ '@# = 1'::jsquery;
1413+
?column?
1414+
----------
1415+
f
1416+
(1 row)
1417+
13941418
--ALL
13951419
select 'a.*: = 4'::jsquery;
13961420
jsquery

‎jsquery_op.c

Lines changed: 87 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
#include"jsquery.h"
3131

32-
staticboolrecursiveExecute(JsQueryItem*jsq,JsonbValue*jb,JsQueryItem*jsqLeftArg);
32+
staticboolrecursiveExecute(JsQueryItem*jsq,JsonbValue*jb);
3333

3434
staticint
3535
compareNumeric(Numerica,Numericb)
@@ -59,6 +59,43 @@ JsonbType(JsonbValue *jb)
5959
returntype;
6060
}
6161

62+
staticJsonbValue*
63+
JsonbSize(JsonbValue*jb,JsonbValue*size)
64+
{
65+
JsonbValuev;
66+
JsonbIterator*it;
67+
JsonbIteratorTokenr;
68+
int32length;
69+
inttype=JsonbType(jb);
70+
71+
if (type!=jbvArray&&type!=jbvObject)
72+
returnNULL;
73+
74+
Assert(jb->type==jbvBinary);
75+
76+
it=JsonbIteratorInit(jb->val.binary.data);
77+
r=JsonbIteratorNext(&it,&v, true);
78+
Assert(r==WJB_BEGIN_ARRAY||r==WJB_BEGIN_OBJECT);
79+
80+
if (r==WJB_BEGIN_ARRAY)
81+
{
82+
length=v.val.array.nElems;
83+
if (length<0)
84+
length=JsonGetArraySize(jb->val.binary.data);
85+
}
86+
else
87+
{
88+
length=v.val.object.nPairs;
89+
if (length<0)
90+
length=JsonGetObjectSize(jb->val.binary.data);
91+
}
92+
93+
size->type=jbvNumeric;
94+
size->val.numeric=DatumGetNumeric(DirectFunctionCall1(
95+
int4_numeric,Int32GetDatum(length)));
96+
returnsize;
97+
}
98+
6299
staticbool
63100
recursiveAny(JsQueryItem*jsq,JsonbValue*jb)
64101
{
@@ -81,7 +118,7 @@ recursiveAny(JsQueryItem *jsq, JsonbValue *jb)
81118

82119
if (r==WJB_VALUE||r==WJB_ELEM)
83120
{
84-
res=recursiveExecute(jsq,&v,NULL);
121+
res=recursiveExecute(jsq,&v);
85122

86123
if (res== false&&v.type==jbvBinary)
87124
res=recursiveAny(jsq,&v);
@@ -113,7 +150,7 @@ recursiveAll(JsQueryItem *jsq, JsonbValue *jb)
113150

114151
if (r==WJB_VALUE||r==WJB_ELEM)
115152
{
116-
if ((res=recursiveExecute(jsq,&v,NULL))== true)
153+
if ((res=recursiveExecute(jsq,&v))== true)
117154
{
118155
if (v.type==jbvBinary)
119156
res=recursiveAll(jsq,&v);
@@ -312,7 +349,7 @@ makeCompare(JsQueryItem *jsq, int32 op, JsonbValue *jb)
312349
}
313350

314351
staticbool
315-
executeExpr(JsQueryItem*jsq,int32op,JsonbValue*jb,JsQueryItem*jsqLeftArg)
352+
executeExpr(JsQueryItem*jsq,int32op,JsonbValue*jb)
316353
{
317354
boolres= false;
318355
/*
@@ -322,100 +359,37 @@ executeExpr(JsQueryItem *jsq, int32 op, JsonbValue *jb, JsQueryItem *jsqLeftArg)
322359
Assert(jsq->type==jqiAny||jsq->type==jqiString||jsq->type==jqiNumeric||
323360
jsq->type==jqiNull||jsq->type==jqiBool||jsq->type==jqiArray);
324361

325-
if (jsqLeftArg&&jsqLeftArg->type==jqiLength)
362+
switch(op)
326363
{
327-
if (JsonbType(jb)==jbvArray||JsonbType(jb)==jbvObject)
328-
{
329-
int32length;
330-
JsonbIterator*it;
331-
JsonbValuev;
332-
intr;
333-
334-
it=JsonbIteratorInit(jb->val.binary.data);
335-
r=JsonbIteratorNext(&it,&v, true);
336-
Assert(r==WJB_BEGIN_ARRAY||r==WJB_BEGIN_OBJECT);
337-
338-
if (r==WJB_BEGIN_ARRAY)
339-
{
340-
length=v.val.array.nElems;
341-
342-
if (length<0)
343-
length=JsonGetArraySize(jb->val.binary.data);
344-
}
364+
casejqiEqual:
365+
if (JsonbType(jb)==jbvArray&&jsq->type==jqiArray)
366+
res=checkArrayEquality(jsq,jb);
345367
else
346-
{
347-
length=v.val.object.nPairs;
348-
349-
if (length<0)
350-
{
351-
length=0;
352-
353-
while ((r=JsonbIteratorNext(&it,&v, true))!=WJB_DONE)
354-
{
355-
if (r==WJB_KEY)
356-
length++;
357-
}
358-
}
359-
}
360-
361-
v.type=jbvNumeric;
362-
v.val.numeric=DatumGetNumeric(DirectFunctionCall1(int4_numeric,Int32GetDatum(length)));
363-
364-
switch(op)
365-
{
366-
casejqiEqual:
367-
casejqiLess:
368-
casejqiGreater:
369-
casejqiLessOrEqual:
370-
casejqiGreaterOrEqual:
371-
res=makeCompare(jsq,op,&v);
372-
break;
373-
casejqiIn:
374-
res=checkScalarIn(jsq,&v);
375-
break;
376-
casejqiOverlap:
377-
casejqiContains:
378-
casejqiContained:
379-
break;
380-
default:
381-
elog(ERROR,"Unknown operation");
382-
}
383-
}
384-
}
385-
else
386-
{
387-
switch(op)
388-
{
389-
casejqiEqual:
390-
if (JsonbType(jb)==jbvArray&&jsq->type==jqiArray)
391-
res=checkArrayEquality(jsq,jb);
392-
else
393-
res=checkScalarEquality(jsq,jb);
394-
break;
395-
casejqiIn:
396-
res=checkScalarIn(jsq,jb);
397-
break;
398-
casejqiOverlap:
399-
casejqiContains:
400-
casejqiContained:
401-
res=executeArrayOp(jsq,op,jb);
402-
break;
403-
casejqiLess:
404-
casejqiGreater:
405-
casejqiLessOrEqual:
406-
casejqiGreaterOrEqual:
407-
res=makeCompare(jsq,op,jb);
408-
break;
409-
default:
410-
elog(ERROR,"Unknown operation");
411-
}
368+
res=checkScalarEquality(jsq,jb);
369+
break;
370+
casejqiIn:
371+
res=checkScalarIn(jsq,jb);
372+
break;
373+
casejqiOverlap:
374+
casejqiContains:
375+
casejqiContained:
376+
res=executeArrayOp(jsq,op,jb);
377+
break;
378+
casejqiLess:
379+
casejqiGreater:
380+
casejqiLessOrEqual:
381+
casejqiGreaterOrEqual:
382+
res=makeCompare(jsq,op,jb);
383+
break;
384+
default:
385+
elog(ERROR,"Unknown operation");
412386
}
413387

414388
returnres;
415389
}
416390

417391
staticbool
418-
recursiveExecute(JsQueryItem*jsq,JsonbValue*jb,JsQueryItem*jsqLeftArg)
392+
recursiveExecute(JsQueryItem*jsq,JsonbValue*jb)
419393
{
420394
JsQueryItemelem;
421395
boolres= false;
@@ -425,25 +399,25 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
425399
switch(jsq->type) {
426400
casejqiAnd:
427401
jsqGetLeftArg(jsq,&elem);
428-
res=recursiveExecute(&elem,jb,jsqLeftArg);
402+
res=recursiveExecute(&elem,jb);
429403
if (res== true)
430404
{
431405
jsqGetRightArg(jsq,&elem);
432-
res=recursiveExecute(&elem,jb,jsqLeftArg);
406+
res=recursiveExecute(&elem,jb);
433407
}
434408
break;
435409
casejqiOr:
436410
jsqGetLeftArg(jsq,&elem);
437-
res=recursiveExecute(&elem,jb,jsqLeftArg);
411+
res=recursiveExecute(&elem,jb);
438412
if (res== false)
439413
{
440414
jsqGetRightArg(jsq,&elem);
441-
res=recursiveExecute(&elem,jb,jsqLeftArg);
415+
res=recursiveExecute(&elem,jb);
442416
}
443417
break;
444418
casejqiNot:
445419
jsqGetArg(jsq,&elem);
446-
res= !recursiveExecute(&elem,jb,jsqLeftArg);
420+
res= !recursiveExecute(&elem,jb);
447421
break;
448422
casejqiKey:
449423
if (JsonbType(jb)==jbvObject) {
@@ -457,7 +431,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
457431
if (v!=NULL)
458432
{
459433
jsqGetNext(jsq,&elem);
460-
res=recursiveExecute(&elem,v,NULL);
434+
res=recursiveExecute(&elem,v);
461435
pfree(v);
462436
}
463437
}
@@ -480,23 +454,23 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
480454
r=JsonbIteratorNext(&it,&v, true);
481455
Assert(r==WJB_ELEM);
482456

483-
res=recursiveExecute(&elem,&v,jsqLeftArg);
457+
res=recursiveExecute(&elem,&v);
484458
}
485459
else
486460
{
487-
res=recursiveExecute(&elem,jb,jsqLeftArg);
461+
res=recursiveExecute(&elem,jb);
488462
}
489463
break;
490464
casejqiAny:
491465
jsqGetNext(jsq,&elem);
492-
if (recursiveExecute(&elem,jb,NULL))
466+
if (recursiveExecute(&elem,jb))
493467
res= true;
494468
elseif (jb->type==jbvBinary)
495469
res=recursiveAny(&elem,jb);
496470
break;
497471
casejqiAll:
498472
jsqGetNext(jsq,&elem);
499-
if ((res=recursiveExecute(&elem,jb,NULL))== true)
473+
if ((res=recursiveExecute(&elem,jb))== true)
500474
{
501475
if (jb->type==jbvBinary)
502476
res=recursiveAll(&elem,jb);
@@ -520,7 +494,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
520494
{
521495
if (r==WJB_ELEM)
522496
{
523-
res=recursiveExecute(&elem,&v,NULL);
497+
res=recursiveExecute(&elem,&v);
524498

525499
if (jsq->type==jqiAnyArray)
526500
{
@@ -554,7 +528,7 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
554528
{
555529
if (r==WJB_VALUE)
556530
{
557-
res=recursiveExecute(&elem,&v,NULL);
531+
res=recursiveExecute(&elem,&v);
558532

559533
if (jsq->type==jqiAnyKey)
560534
{
@@ -580,12 +554,19 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
580554
casejqiContained:
581555
casejqiOverlap:
582556
jsqGetArg(jsq,&elem);
583-
res=executeExpr(&elem,jsq->type,jb,jsqLeftArg);
557+
res=executeExpr(&elem,jsq->type,jb);
584558
break;
585559
casejqiLength:
560+
{
561+
JsonbValuesize;
586562
jsqGetNext(jsq,&elem);
587-
res=recursiveExecute(&elem,jb,jsq);
563+
if (JsonbSize(jb,&size))
564+
{
565+
res=recursiveExecute(&elem,&size);
566+
pfree(size.val.numeric);
567+
}
588568
break;
569+
}
589570
casejqiIs:
590571
if (JsonbType(jb)==jbvScalar)
591572
{
@@ -631,7 +612,7 @@ jsquery_json_exec(PG_FUNCTION_ARGS)
631612

632613
jsqInit(&jsq,jq);
633614

634-
res=recursiveExecute(&jsq,&jbv,NULL);
615+
res=recursiveExecute(&jsq,&jbv);
635616

636617
PG_FREE_IF_COPY(jq,0);
637618
PG_FREE_IF_COPY_JSONB(jb,1);
@@ -653,7 +634,7 @@ json_jsquery_exec(PG_FUNCTION_ARGS)
653634

654635
jsqInit(&jsq,jq);
655636

656-
res=recursiveExecute(&jsq,&jbv,NULL);
637+
res=recursiveExecute(&jsq,&jbv);
657638

658639
PG_FREE_IF_COPY_JSONB(jb,0);
659640
PG_FREE_IF_COPY(jq,1);

‎sql/jsquery.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ select '{"a":[1,2]}' @@ '%.@# in (2, 4)'::jsquery;
283283
select'{"a":[1,2]}' @@'*.@# in (2, 4)'::jsquery;
284284
select'{"a":[1,2]}' @@'*.@# ($ = 4 or $ = 2)'::jsquery;
285285
select'{"a":[1,2]}' @@'@# = 1'::jsquery;
286+
select'[]' @@'@# is numeric'::jsquery;
287+
select'{}' @@'@# is numeric'::jsquery;
288+
select'0' @@'@# is numeric'::jsquery;
289+
select'0' @@'@# = 1'::jsquery;
286290

287291
--ALL
288292
select'a.*: = 4'::jsquery;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp