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

Commitd0166fb

Browse files
committed
implement #N path key - N-th element of array
1 parent058fb69 commitd0166fb

10 files changed

+130
-9
lines changed

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ the simplest case path is just an key name. In general path is key names and
8989
placeholders combined by dot signs. Path can use following placeholders:
9090

9191
*`#` – any index of array;
92+
*`#N` – N-th index of array;
9293
*`%` – any key of object;
9394
*`*` – any sequence of array indexes and object keys;
9495
*`@#` – length of array or object, could be only used as last component of

‎expected/jsquery.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,18 @@ select 'is.not < 1'::jsquery;
517517
"is"."not" < 1
518518
(1 row)
519519

520+
select 'a.b.#4 > 4'::jsquery;
521+
jsquery
522+
----------------
523+
"a"."b".#4 > 4
524+
(1 row)
525+
526+
select 'a.b.#10203.* > 4'::jsquery;
527+
jsquery
528+
----------------------
529+
"a"."b".#10203.* > 4
530+
(1 row)
531+
520532
select '{"a": {"b": null}}'::jsonb @@ 'a.b = 1';
521533
?column?
522534
----------
@@ -997,6 +1009,42 @@ select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%=[5,6]';
9971009
t
9981010
(1 row)
9991011

1012+
select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#1 = 2';
1013+
?column?
1014+
----------
1015+
t
1016+
(1 row)
1017+
1018+
select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#2 = 2';
1019+
?column?
1020+
----------
1021+
f
1022+
(1 row)
1023+
1024+
select '{"a": {"b": [1,2,3]}}'::jsonb @@ 'a.b.#3 = 2';
1025+
?column?
1026+
----------
1027+
f
1028+
(1 row)
1029+
1030+
select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#1.x = 2';
1031+
?column?
1032+
----------
1033+
t
1034+
(1 row)
1035+
1036+
select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#2.x = 2';
1037+
?column?
1038+
----------
1039+
f
1040+
(1 row)
1041+
1042+
select '{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@ 'a.b.#3.x = 2';
1043+
?column?
1044+
----------
1045+
f
1046+
(1 row)
1047+
10001048
select '"XXX"'::jsonb @@ '$="XXX"';
10011049
?column?
10021050
----------

‎jsquery.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ typedef enum JsQueryItemType {
5656
jqiCurrent,
5757
jqiLength,
5858
jqiIn,
59-
jqiIs
59+
jqiIs,
60+
jqiIndexArray
6061
}JsQueryItemType;
6162

6263
/*
@@ -104,6 +105,8 @@ typedef struct JsQueryItem {
104105
intcurrent;
105106
int32*arrayPtr;
106107
}array;
108+
109+
uint32arrayIndex;
107110
};
108111
}JsQueryItem;
109112

@@ -153,6 +156,8 @@ struct JsQueryParseItem {
153156
intnelems;
154157
JsQueryParseItem**elems;
155158
}array;
159+
160+
uint32arrayIndex;
156161
};
157162
};
158163

‎jsquery_extract.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ recursiveExtract(JsQueryItem *jsq, bool not, bool indirect, PathItem *path)
105105
pathItem->parent=path;
106106
jsqGetNext(jsq,&elem);
107107
returnrecursiveExtract(&elem,not, true,pathItem);
108+
casejqiIndexArray:
108109
casejqiAnyArray:
109110
casejqiAllArray:
110111
if ((not&&jsq->type==jqiAnyArray)|| (!not&&jsq->type==jqiAllArray))

‎jsquery_gram.y

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ makeItemType(int type)
6565
return v;
6666
}
6767

68+
static JsQueryParseItem*
69+
makeIndexArray(string *s)
70+
{
71+
JsQueryParseItem* v =makeItemType(jqiIndexArray);
72+
73+
v->arrayIndex =pg_atoi(s->val,4,0);
74+
75+
return v;
76+
}
77+
6878
static JsQueryParseItem*
6979
makeItemString(string *s)
7080
{
@@ -213,13 +223,13 @@ makeItemList(List *list) {
213223
ARRAY_TFALSE_PNUMERIC_TOBJECT_T
214224
STRING_TBOOLEAN_T
215225

216-
%token<str>STRING_PNUMERIC_P
226+
%token<str>STRING_PNUMERIC_PINT_P
217227

218228
%type<value>resultscalar_value
219229

220230
%type<elems>pathvalue_list
221231

222-
%type<value>keykey_anyright_exprexprarray
232+
%type<value>keykey_anyright_exprexprarraynumeric
223233

224234
%token<hint>HINT_P
225235

@@ -257,22 +267,28 @@ scalar_value:
257267
|STRING_T{$$ = makeItemString(&$1); }
258268
|BOOLEAN_T{$$ = makeItemString(&$1); }
259269
|NUMERIC_P{$$ = makeItemNumeric(&$1); }
270+
|INT_P{$$ = makeItemNumeric(&$1); }
260271
;
261272

262273
value_list:
263274
scalar_value {$$ = lappend(NIL,$1); }
264275
|value_list','scalar_value{$$ = lappend($1,$3); }
265276
;
266277

278+
numeric:
279+
NUMERIC_P{$$ = makeItemNumeric(&$1); }
280+
|INT_P{$$ = makeItemNumeric(&$1); }
281+
;
282+
267283
right_expr:
268284
'='scalar_value{$$ = makeItemUnary(jqiEqual,$2); }
269285
|IN_P'('value_list')'{$$ = makeItemUnary(jqiIn, makeItemArray($3)); }
270286
|'='array{$$ = makeItemUnary(jqiEqual,$2); }
271287
|'=''*'{$$ = makeItemUnary(jqiEqual, makeItemType(jqiAny)); }
272-
|'<'NUMERIC_P{$$ = makeItemUnary(jqiLess,makeItemNumeric(&$2)); }
273-
|'>'NUMERIC_P{$$ = makeItemUnary(jqiGreater,makeItemNumeric(&$2)); }
274-
|'<''='NUMERIC_P{$$ = makeItemUnary(jqiLessOrEqual,makeItemNumeric(&$3)); }
275-
|'>''='NUMERIC_P{$$ = makeItemUnary(jqiGreaterOrEqual,makeItemNumeric(&$3)); }
288+
|'<'numeric{$$ = makeItemUnary(jqiLess,$2); }
289+
|'>'numeric{$$ = makeItemUnary(jqiGreater,$2); }
290+
|'<''='numeric{$$ = makeItemUnary(jqiLessOrEqual,$3); }
291+
|'>''='numeric{$$ = makeItemUnary(jqiGreaterOrEqual,$3); }
276292
|'@''>'array{$$ = makeItemUnary(jqiContains,$3); }
277293
|'<''@'array{$$ = makeItemUnary(jqiContained,$3); }
278294
|'&''&'array{$$ = makeItemUnary(jqiOverlap,$3); }
@@ -311,6 +327,7 @@ key:
311327
|'%'':'{$$ = makeItemType(jqiAllKey); }
312328
|'$'{$$ = makeItemType(jqiCurrent); }
313329
|'@''#'{$$ = makeItemType(jqiLength); }
330+
|'#'INT_P{$$ = makeIndexArray(&$2); }
314331
|STRING_P{$$ = makeItemKey(&$1); }
315332
|IN_P{$$ = makeItemKey(&$1); }
316333
|IS_P{$$ = makeItemKey(&$1); }
@@ -325,6 +342,7 @@ key:
325342
|STRING_T{$$ = makeItemKey(&$1); }
326343
|BOOLEAN_T{$$ = makeItemKey(&$1); }
327344
|NUMERIC_P{$$ = makeItemKey(&$1); }
345+
|INT_P{$$ = makeItemKey(&$1); }
328346
;
329347

330348
/*

‎jsquery_io.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item, bool onlyCurrent
113113
*(int32*)(buf->data+arg)=chld;
114114
}
115115
break;
116+
casejqiIndexArray:
117+
appendBinaryStringInfo(buf, (char*)&item->arrayIndex,
118+
sizeof(item->arrayIndex));
116119
casejqiAny:
117120
casejqiAnyArray:
118121
casejqiAnyKey:
@@ -272,7 +275,7 @@ printJsQueryItem(StringInfo buf, JsQueryItem *v, bool inKey, bool printBracketes
272275
break;
273276
casejqiArray:
274277
if (printBracketes)
275-
appendStringInfoChar(buf,'[');
278+
appendStringInfoChar(buf,'[');
276279

277280
while(jsqIterateArray(v,&elem))
278281
{
@@ -364,6 +367,11 @@ printJsQueryItem(StringInfo buf, JsQueryItem *v, bool inKey, bool printBracketes
364367
appendStringInfoChar(buf,'%');
365368
appendStringInfoChar(buf,':');
366369
break;
370+
casejqiIndexArray:
371+
if (inKey)
372+
appendStringInfoChar(buf,'.');
373+
appendStringInfo(buf,"#%u",v->arrayIndex);
374+
break;
367375
default:
368376
elog(ERROR,"Unknown JsQueryItem type: %d",v->type);
369377
}

‎jsquery_op.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,19 @@ recursiveExecute(JsQueryItem *jsq, JsonbValue *jb, JsQueryItem *jsqLeftArg)
518518
}
519519
}
520520
break;
521+
casejqiIndexArray:
522+
if (JsonbType(jb)==jbvArray)
523+
{
524+
JsonbValue*v;
525+
526+
jsqGetNext(jsq,&elem);
527+
528+
v=getIthJsonbValueFromContainer(jb->val.binary.data,
529+
jsq->arrayIndex);
530+
531+
res=v&&recursiveExecute(&elem,v,NULL);
532+
}
533+
break;
521534
casejqiAnyKey:
522535
casejqiAllKey:
523536
if (JsonbType(jb)==jbvObject)
@@ -670,6 +683,10 @@ compareJsQuery(JsQueryItem *v1, JsQueryItem *v2)
670683
casejqiAllArray:
671684
casejqiAllKey:
672685
break;
686+
casejqiIndexArray:
687+
if (v1->arrayIndex!=v2->arrayIndex)
688+
res= (v1->arrayIndex>v2->arrayIndex) ?1 :-1;
689+
break;
673690
casejqiKey:
674691
casejqiString:
675692
{
@@ -964,6 +981,9 @@ hashJsQuery(JsQueryItem *v, pg_crc32 *crc)
964981
casejqiAllArray:
965982
casejqiAllKey:
966983
break;
984+
casejqiIndexArray:
985+
COMP_CRC32(*crc,&v->arrayIndex,sizeof(v->arrayIndex));
986+
break;
967987
default:
968988
elog(ERROR,"Unknown JsQueryItem type: %d",v->type);
969989
}

‎jsquery_scan.l

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,19 @@ unicode \\u[0-9A-Fa-f]{4}
8585
return NUMERIC_P;
8686
}
8787
88-
<INITIAL>[+-]?[0-9]+ {
88+
<INITIAL>[+-][0-9]+ {
8989
addstring(true, yytext, yyleng);
9090
addchar(false, '\0');
9191
yylval->str = scanstring;
9292
return NUMERIC_P;
9393
}
9494
95+
<INITIAL>[0-9]+ {
96+
addstring(true, yytext, yyleng);
97+
addchar(false, '\0');
98+
yylval->str = scanstring;
99+
return INT_P;
100+
}
95101
96102
<INITIAL>{any}+{
97103
addstring(true, yytext, yyleng);

‎jsquery_support.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ jsqInitByBuffer(JsQueryItem *v, char *base, int32 pos)
8080
casejqiAllArray:
8181
casejqiAllKey:
8282
break;
83+
casejqiIndexArray:
84+
read_int32(v->arrayIndex,base,pos);
85+
break;
8386
casejqiKey:
8487
casejqiString:
8588
read_int32(v->value.datalen,base,pos);
@@ -144,6 +147,7 @@ jsqGetNext(JsQueryItem *v, JsQueryItem *a)
144147
Assert(
145148
v->type==jqiKey||
146149
v->type==jqiAny||
150+
v->type==jqiIndexArray||
147151
v->type==jqiAnyArray||
148152
v->type==jqiAnyKey||
149153
v->type==jqiAll||

‎sql/jsquery.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ select 'is.in < 1'::jsquery;
101101
select'is.is < 1'::jsquery;
102102
select'is.not < 1'::jsquery;
103103

104+
select'a.b.#4 > 4'::jsquery;
105+
select'a.b.#10203.* > 4'::jsquery;
106+
104107
select'{"a": {"b": null}}'::jsonb @@'a.b = 1';
105108
select'{"a": {"b": null}}'::jsonb @@'a.b = null';
106109
select'{"a": {"b": null}}'::jsonb @@'a.b = false';
@@ -202,6 +205,13 @@ select '{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@ '%.%="hey"';
202205
select'{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@'%="hey"';
203206
select'{"a": {"b": 3, "c": "hey"}, "x": [5,6]}'::jsonb @@'%=[5,6]';
204207

208+
select'{"a": {"b": [1,2,3]}}'::jsonb @@'a.b.#1 = 2';
209+
select'{"a": {"b": [1,2,3]}}'::jsonb @@'a.b.#2 = 2';
210+
select'{"a": {"b": [1,2,3]}}'::jsonb @@'a.b.#3 = 2';
211+
select'{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@'a.b.#1.x = 2';
212+
select'{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@'a.b.#2.x = 2';
213+
select'{"a": {"b": [{"x":1},{"x":2},{"x":3}]}}'::jsonb @@'a.b.#3.x = 2';
214+
205215
select'"XXX"'::jsonb @@'$="XXX"';
206216
select'"XXX"'::jsonb @@'#.$="XXX"';
207217

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp