2323PG_MODULE_MAGIC ;
2424
2525static int
26- flattenJsQueryParseItem (StringInfo buf , JsQueryParseItem * item )
26+ flattenJsQueryParseItem (StringInfo buf , JsQueryParseItem * item , bool onlyCurrentInPath )
2727{
2828 int32 pos = buf -> len - VARHDRSZ ; /* position from begining of jsquery data */
2929 int32 chld , next ;
@@ -42,6 +42,8 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item)
4242 switch (item -> type )
4343 {
4444 case jqiKey :
45+ if (onlyCurrentInPath )
46+ elog (ERROR ,"Array length should be last in path" );
4547 case jqiString :
4648 appendBinaryStringInfo (buf , (char * )& item -> string .len , sizeof (item -> string .len ));
4749 appendBinaryStringInfo (buf , item -> string .val , item -> string .len );
@@ -69,7 +71,7 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item)
6971
7072 for (i = 0 ; i < item -> array .nelems ; i ++ )
7173 {
72- chld = flattenJsQueryParseItem (buf , item -> array .elems [i ]);
74+ chld = flattenJsQueryParseItem (buf , item -> array .elems [i ], onlyCurrentInPath );
7375 * (int32 * )(buf -> data + arrayStart + i * sizeof (i )) = chld ;
7476 }
7577
@@ -85,9 +87,9 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item)
8587 right = buf -> len ;
8688 appendBinaryStringInfo (buf , (char * )& right /* fake value */ , sizeof (right ));
8789
88- chld = flattenJsQueryParseItem (buf , item -> args .left );
90+ chld = flattenJsQueryParseItem (buf , item -> args .left , onlyCurrentInPath );
8991 * (int32 * )(buf -> data + left ) = chld ;
90- chld = flattenJsQueryParseItem (buf , item -> args .right );
92+ chld = flattenJsQueryParseItem (buf , item -> args .right , onlyCurrentInPath );
9193 * (int32 * )(buf -> data + right ) = chld ;
9294 }
9395 break ;
@@ -107,25 +109,30 @@ flattenJsQueryParseItem(StringInfo buf, JsQueryParseItem *item)
107109 arg = buf -> len ;
108110 appendBinaryStringInfo (buf , (char * )& arg /* fake value */ , sizeof (arg ));
109111
110- chld = flattenJsQueryParseItem (buf , item -> arg );
112+ chld = flattenJsQueryParseItem (buf , item -> arg , onlyCurrentInPath );
111113 * (int32 * )(buf -> data + arg ) = chld ;
112114 }
113115 break ;
114- case jqiNull :
115- case jqiCurrent :
116116 case jqiAny :
117117 case jqiAnyArray :
118118 case jqiAnyKey :
119119 case jqiAll :
120120 case jqiAllArray :
121121 case jqiAllKey :
122+ if (onlyCurrentInPath )
123+ elog (ERROR ,"Array length should be last in path" );
124+ case jqiCurrent :
125+ case jqiNull :
126+ break ;
127+ case jqiLength :
128+ onlyCurrentInPath = true;
122129 break ;
123130 default :
124131 elog (ERROR , "Unknown type: %d" , item -> type );
125132 }
126133
127134 if (item -> next )
128- * (int32 * )(buf -> data + next ) = flattenJsQueryParseItem (buf , item -> next );
135+ * (int32 * )(buf -> data + next ) = flattenJsQueryParseItem (buf , item -> next , onlyCurrentInPath );
129136
130137 return pos ;
131138}
@@ -137,8 +144,8 @@ jsquery_in(PG_FUNCTION_ARGS)
137144 char * in = PG_GETARG_CSTRING (0 );
138145 int32 len = strlen (in );
139146 JsQueryParseItem * jsquery = parsejsquery (in , len );
140- JsQuery * res ;
141- StringInfoData buf ;
147+ JsQuery * res ;
148+ StringInfoData buf ;
142149
143150 initStringInfo (& buf );
144151 enlargeStringInfo (& buf , 4 * len /* estimation */ );
@@ -147,7 +154,7 @@ jsquery_in(PG_FUNCTION_ARGS)
147154
148155 if (jsquery != NULL )
149156 {
150- flattenJsQueryParseItem (& buf , jsquery );
157+ flattenJsQueryParseItem (& buf , jsquery , false );
151158
152159 res = (JsQuery * )buf .data ;
153160 SET_VARSIZE (res , buf .len );
@@ -318,6 +325,12 @@ printJsQueryItem(StringInfo buf, JsQueryItem *v, bool inKey, bool printBracketes
318325 appendStringInfoChar (buf , '.' );
319326 appendStringInfoChar (buf , '$' );
320327 break ;
328+ case jqiLength :
329+ if (inKey )
330+ appendStringInfoChar (buf , '.' );
331+ appendStringInfoChar (buf , '@' );
332+ appendStringInfoChar (buf , '#' );
333+ break ;
321334 case jqiAny :
322335 if (inKey )
323336 appendStringInfoChar (buf , '.' );
0 commit comments