11/* -------------------------------------------------------------------------
22 *
33 * jsquery_gram.y
4- * Grammar definitions for jsquery datatype
4+ * Grammar definitions for jsquery datatype
55 *
66 * Copyright (c) 2014, PostgreSQL Global Development Group
77 * Author: Teodor Sigaev <teodor@sigaev.ru>
88 *
99 * IDENTIFICATION
10- * contrib/jsquery/jsquery_gram.y
10+ * contrib/jsquery/jsquery_gram.y
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -43,8 +43,8 @@ fprintf_to_ereport(const char *fmt, const char *msg)
4343
4444/* struct string is shared between scan and gram */
4545typedef struct string {
46- char *val;
47- int len;
46+ char *val;
47+ int len;
4848 int total;
4949} string;
5050#include < jsquery_gram.h>
@@ -188,6 +188,9 @@ makeItemList(List *list) {
188188
189189 head = end = (JsQueryParseItem*)linitial (list);
190190
191+ while (end->next )
192+ end = end->next ;
193+
191194 foreach (cell, list)
192195 {
193196 JsQueryParseItem *c = (JsQueryParseItem*)lfirst (cell);
@@ -197,6 +200,9 @@ makeItemList(List *list) {
197200
198201 end->next = c;
199202 end = c;
203+
204+ while (end->next )
205+ end = end->next ;
200206 }
201207
202208 return head;
@@ -212,7 +218,7 @@ makeItemList(List *list) {
212218%parse-param {JsQueryParseItem **result}
213219
214220%union {
215- string str;
221+ string str;
216222 List *elems; /* list of JsQueryParseItem */
217223
218224 JsQueryParseItem *value;
@@ -225,25 +231,26 @@ makeItemList(List *list) {
225231
226232%token <str> STRING_P NUMERIC_P INT_P
227233
228- %type <value> result scalar_value
234+ %type <value> result scalar_value
229235
230236%type <elems> path value_list
231237
232- %type <value> key key_any right_expr expr array numeric
238+ %type <value> key key_any right_expr expr array numeric
233239
234240%token <hint> HINT_P
235241
236- %left OR_P
237- %left AND_P
238- %right NOT_P
239- %nonassoc IN_P IS_P
242+ %left OR_P
243+ %left AND_P
244+ %right NOT_P
245+ %nonassoc IN_P IS_P
240246%nonassoc ' (' ' )'
241247
242248/* Grammar follows */
243249%%
244250
245- result :
246- expr { *result = $1 ; }
251+ result :
252+ expr { *result = $1 ; }
253+ | path { *result = makeItemList($1 ); }
247254 | /* EMPTY */ { *result = NULL ; }
248255 ;
249256
@@ -271,8 +278,8 @@ scalar_value:
271278 ;
272279
273280value_list :
274- scalar_value { $$ = lappend(NIL, $1 ); }
275- | value_list ' ,' scalar_value { $$ = lappend($1 , $3 ); }
281+ scalar_value { $$ = lappend(NIL, $1 ); }
282+ | value_list ' ,' scalar_value { $$ = lappend($1 , $3 ); }
276283 ;
277284
278285numeric :
@@ -289,20 +296,20 @@ right_expr:
289296 | ' >' numeric { $$ = makeItemUnary(jqiGreater, $2 ); }
290297 | ' <' ' =' numeric { $$ = makeItemUnary(jqiLessOrEqual, $3 ); }
291298 | ' >' ' =' numeric { $$ = makeItemUnary(jqiGreaterOrEqual, $3 ); }
292- | ' @' ' >' array { $$ = makeItemUnary(jqiContains, $3 ); }
293- | ' <' ' @' array { $$ = makeItemUnary(jqiContained, $3 ); }
299+ | ' @' ' >' array { $$ = makeItemUnary(jqiContains, $3 ); }
300+ | ' <' ' @' array { $$ = makeItemUnary(jqiContained, $3 ); }
294301 | ' &' ' &' array { $$ = makeItemUnary(jqiOverlap, $3 ); }
295- | IS_P ARRAY_T { $$ = makeItemIs(jbvArray); }
296- | IS_P NUMERIC_T { $$ = makeItemIs(jbvNumeric); }
297- | IS_P OBJECT_T { $$ = makeItemIs(jbvObject); }
298- | IS_P STRING_T { $$ = makeItemIs(jbvString); }
299- | IS_P BOOLEAN_T { $$ = makeItemIs(jbvBool); }
302+ | IS_P ARRAY_T { $$ = makeItemIs(jbvArray); }
303+ | IS_P NUMERIC_T { $$ = makeItemIs(jbvNumeric); }
304+ | IS_P OBJECT_T { $$ = makeItemIs(jbvObject); }
305+ | IS_P STRING_T { $$ = makeItemIs(jbvString); }
306+ | IS_P BOOLEAN_T { $$ = makeItemIs(jbvBool); }
300307 ;
301308
302309expr :
303310 path right_expr { $$ = makeItemList(lappend($1 , $2 )); }
304311 | path HINT_P right_expr { $3 ->hint = $2 ; $$ = makeItemList(lappend($1 , $3 )); }
305- | NOT_P expr { $$ = makeItemUnary(jqiNot, $2 ); }
312+ | NOT_P expr { $$ = makeItemUnary(jqiNot, $2 ); }
306313 /*
307314 * In next two lines NOT_P is a path actually, not a an
308315 * logical expression.
@@ -346,15 +353,17 @@ key:
346353 ;
347354
348355/*
349- * NOT keyword needs separate processing
356+ * NOT keyword needs separate processing
350357 */
351358key_any :
352359 key { $$ = $$ ; }
360+ | ' ?' ' (' expr ' )' { $$ = makeItemUnary(jqiFilter, $3 ); }
353361 | NOT_P { $$ = makeItemKey(&$1 ); }
354362 ;
355363
356364path :
357365 key { $$ = lappend(NIL, $1 ); }
366+ | ' ?' ' (' expr ' )' { $$ = lappend(NIL, makeItemUnary(jqiFilter, $3 )); }
358367 | path ' .' key_any { $$ = lappend($1 , $3 ); }
359368 | NOT_P ' .' key_any { $$ = lappend(lappend(NIL, makeItemKey(&$1 )), $3 ); }
360369 ;
0 commit comments