2020#include "jsquery.h"
2121
2222static int32
23- copyJsQuery (StringInfo buf ,char * jqBase , int32 jqPos )
23+ copyJsQuery (StringInfo buf ,JsQueryItemR * jsq )
2424{
25- int32 resPos = buf -> len - VARHDRSZ ; /* position from begining of jsquery data */
26- JsQueryItemType type ;
27- int32 nextPos , chld , next ;
25+ JsQueryItemR elem ;
26+ int32 next , chld ;
27+ int32 resPos = buf -> len - VARHDRSZ ; /* position from begining of jsquery data */
2828
2929check_stack_depth ();
3030
31- jqPos = readJsQueryHeader (jqBase ,jqPos ,& type ,& nextPos );
32-
33- appendStringInfoChar (buf , (char )type );
31+ appendStringInfoChar (buf , (char )jsq -> type );
3432alignStringInfoInt (buf );
3533
36- next = (nextPos > 0 ) ?buf -> len :0 ; ;
34+ next = (jsqGetNext ( jsq , NULL )) ?buf -> len :0 ;
3735appendBinaryStringInfo (buf , (char * )& next /* fake value */ ,sizeof (next ));
3836
39- switch (type )
37+ switch (jsq -> type )
4038{
4139case jqiKey :
4240case jqiString :
4341{
44- int32 len ;
42+ int32 len ;
43+ char * s ;
4544
46- read_int32 ( len , jqBase , jqPos );
45+ s = jsqGetString ( jsq , & len );
4746appendBinaryStringInfo (buf , (char * )& len ,sizeof (len ));
48- appendBinaryStringInfo (buf ,jqBase + jqPos ,len + 1 /* \0 */ );
47+ appendBinaryStringInfo (buf ,s ,len + 1 /* \0 */ );
4948}
5049break ;
5150case jqiNumeric :
52- appendBinaryStringInfo (buf ,jqBase + jqPos ,VARSIZE (jqBase + jqPos ));
51+ {
52+ Numeric n = jsqGetNumeric (jsq );
53+
54+ appendBinaryStringInfo (buf , (char * )n ,VARSIZE_ANY (n ));
55+ }
5356break ;
5457case jqiBool :
55- appendBinaryStringInfo (buf ,jqBase + jqPos ,1 );
58+ {
59+ bool v = jsqGetBool (jsq );
60+
61+ appendBinaryStringInfo (buf , (char * )& v ,1 );
62+ }
5663break ;
5764case jqiArray :
5865{
59- int32 i ,nelems , arrayStart , * arrayPosIn ;
66+ int32 i ,arrayStart ;
6067
61- read_int32 ( nelems , jqBase , jqPos );
62- appendBinaryStringInfo ( buf , ( char * ) & nelems /* fake value */ , sizeof (nelems ));
68+ appendBinaryStringInfo ( buf , ( char * ) & jsq -> array . nelems ,
69+ sizeof (jsq -> array . nelems ));
6370
6471arrayStart = buf -> len ;
65- arrayPosIn = (int32 * )(jqBase + jqPos );
6672
6773/* reserve place for "pointers" to array's elements */
68- for (i = 0 ;i < nelems ;i ++ )
74+ for (i = 0 ;i < jsq -> array . nelems ;i ++ )
6975appendBinaryStringInfo (buf , (char * )& i /* fake value */ ,sizeof (i ));
7076
71- for ( i = 0 ; i < nelems ; i ++ )
77+ while ( jsqIterateArray ( jsq , & elem ) )
7278{
73- chld = copyJsQuery (buf ,jqBase , arrayPosIn [ i ] );
79+ chld = copyJsQuery (buf ,& elem );
7480* (int32 * )(buf -> data + arrayStart + i * sizeof (i ))= chld ;
81+ i ++ ;
7582}
7683}
7784break ;
7885case jqiAnd :
7986case jqiOr :
8087{
81- int32 leftIn , rightIn , leftOut ,rightOut ;
88+ int32 leftOut ,rightOut ;
8289
8390leftOut = buf -> len ;
8491appendBinaryStringInfo (buf , (char * )& leftOut /* fake value */ ,sizeof (leftOut ));
8592rightOut = buf -> len ;
8693appendBinaryStringInfo (buf , (char * )& rightOut /* fake value */ ,sizeof (rightOut ));
8794
88- read_int32 ( leftIn , jqBase , jqPos );
89- chld = copyJsQuery (buf ,jqBase , leftIn );
95+ jsqGetLeftArg ( jsq , & elem );
96+ chld = copyJsQuery (buf ,& elem );
9097* (int32 * )(buf -> data + leftOut )= chld ;
9198
92- read_int32 ( rightIn , jqBase , jqPos );
93- chld = copyJsQuery (buf ,jqBase , rightIn );
99+ jsqGetRightArg ( jsq , & elem );
100+ chld = copyJsQuery (buf ,& elem );
94101* (int32 * )(buf -> data + rightOut )= chld ;
95102}
96103break ;
@@ -105,13 +112,12 @@ copyJsQuery(StringInfo buf, char *jqBase, int32 jqPos)
105112case jqiOverlap :
106113case jqiNot :
107114{
108- int32 argIn , argOut ;
115+ int32 argOut = buf -> len ;
109116
110- argOut = buf -> len ;
111117appendBinaryStringInfo (buf , (char * )& argOut /* fake value */ ,sizeof (argOut ));
112118
113- read_int32 ( argIn , jqBase , jqPos );
114- chld = copyJsQuery (buf ,jqBase , argIn );
119+ jsqGetArg ( jsq , & elem );
120+ chld = copyJsQuery (buf ,& elem );
115121* (int32 * )(buf -> data + argOut )= chld ;
116122}
117123break ;
@@ -122,11 +128,11 @@ copyJsQuery(StringInfo buf, char *jqBase, int32 jqPos)
122128case jqiAnyKey :
123129break ;
124130default :
125- elog (ERROR ,"Unknown JsQueryItem type: %d" ,type );
131+ elog (ERROR ,"Unknown JsQueryItem type: %d" ,jsq -> type );
126132}
127133
128- if (nextPos )
129- * (int32 * )(buf -> data + next )= copyJsQuery (buf ,jqBase , nextPos );
134+ if (jsqGetNext ( jsq , & elem ) )
135+ * (int32 * )(buf -> data + next )= copyJsQuery (buf ,& elem );
130136
131137return resPos ;
132138}
@@ -137,27 +143,32 @@ joinJsQuery(JsQueryItemType type, JsQuery *jq1, JsQuery *jq2)
137143JsQuery * out ;
138144StringInfoData buf ;
139145int32 left ,right ,chld ;
146+ JsQueryItemR v ;
140147
141148initStringInfo (& buf );
142149enlargeStringInfo (& buf ,VARSIZE_ANY (jq1 )+ VARSIZE_ANY (jq2 )+ 4 * sizeof (int32 )+ VARHDRSZ );
143150
144151appendStringInfoSpaces (& buf ,VARHDRSZ );
145152
153+ /* form jqiAnd/jqiOr header */
146154appendStringInfoChar (& buf , (char )type );
147155alignStringInfoInt (& buf );
148156
149- /*next */
150- chld = 0 ;
157+ /*nextPos field of header */
158+ chld = 0 ;/* actual value, not a fake */
151159appendBinaryStringInfo (& buf , (char * )& chld ,sizeof (chld ));
152160
153161left = buf .len ;
154162appendBinaryStringInfo (& buf , (char * )& left /* fake value */ ,sizeof (left ));
155163right = buf .len ;
156164appendBinaryStringInfo (& buf , (char * )& right /* fake value */ ,sizeof (right ));
157165
158- chld = copyJsQuery (& buf ,VARDATA (jq1 ),0 );
166+ /* dump left and right subtree */
167+ jsqInit (& v ,jq1 );
168+ chld = copyJsQuery (& buf ,& v );
159169* (int32 * )(buf .data + left )= chld ;
160- chld = copyJsQuery (& buf ,VARDATA (jq2 ),0 );
170+ jsqInit (& v ,jq2 );
171+ chld = copyJsQuery (& buf ,& v );
161172* (int32 * )(buf .data + right )= chld ;
162173
163174out = (JsQuery * )buf .data ;
@@ -206,23 +217,26 @@ jsquery_not(PG_FUNCTION_ARGS)
206217JsQuery * out ;
207218StringInfoData buf ;
208219int32 arg ,chld ;
220+ JsQueryItemR v ;
209221
210222initStringInfo (& buf );
211223enlargeStringInfo (& buf ,VARSIZE_ANY (jq )+ 4 * sizeof (int32 )+ VARHDRSZ );
212224
213225appendStringInfoSpaces (& buf ,VARHDRSZ );
214226
227+ /* form jsquery header */
215228appendStringInfoChar (& buf , (char )jqiNot );
216229alignStringInfoInt (& buf );
217230
218- /*next */
219- chld = 0 ;
231+ /*nextPos field of header */
232+ chld = 0 ;/* actual value, not a fake */
220233appendBinaryStringInfo (& buf , (char * )& chld ,sizeof (chld ));
221234
222235arg = buf .len ;
223236appendBinaryStringInfo (& buf , (char * )& arg /* fake value */ ,sizeof (arg ));
224237
225- chld = copyJsQuery (& buf ,VARDATA (jq ),0 );
238+ jsqInit (& v ,jq );
239+ chld = copyJsQuery (& buf ,& v );
226240* (int32 * )(buf .data + arg )= chld ;
227241
228242out = (JsQuery * )buf .data ;