@@ -216,63 +216,112 @@ makeTSQuerySign(TSQuery a)
216
216
return sign ;
217
217
}
218
218
219
- Datum
220
- tsq_mcontains ( PG_FUNCTION_ARGS )
219
+ static char * *
220
+ collectTSQueryValues ( TSQuery a , int * nvalues_p )
221
221
{
222
- TSQuery query = PG_GETARG_TSQUERY (0 );
223
- TSQuery ex = PG_GETARG_TSQUERY (1 );
224
- TSQuerySign sq ,
225
- se ;
226
- int i ,
227
- j ;
228
- QueryItem * iq ,
229
- * ie ;
230
-
231
- if (query -> size < ex -> size )
222
+ QueryItem * ptr = GETQUERY (a );
223
+ char * operand = GETOPERAND (a );
224
+ char * * values ;
225
+ int nvalues = 0 ;
226
+ int i ;
227
+
228
+ values = (char * * ) palloc (sizeof (char * ) * a -> size );
229
+
230
+ for (i = 0 ; i < a -> size ; i ++ )
232
231
{
233
- PG_FREE_IF_COPY (query , 0 );
234
- PG_FREE_IF_COPY (ex , 1 );
232
+ if (ptr -> type == QI_VAL )
233
+ {
234
+ int len = ptr -> qoperand .length ;
235
+ char * val ;
236
+
237
+ val = palloc (len + 1 );
238
+ memcpy (val , operand + ptr -> qoperand .distance , len );
239
+ val [len ] = '\0' ;
235
240
236
- PG_RETURN_BOOL (false);
241
+ values [nvalues ++ ] = val ;
242
+ }
243
+ ptr ++ ;
237
244
}
238
245
239
- sq = makeTSQuerySign (query );
240
- se = makeTSQuerySign (ex );
246
+ * nvalues_p = nvalues ;
247
+ return values ;
248
+ }
249
+
250
+ static int
251
+ cmp_string (const void * a , const void * b )
252
+ {
253
+ const char * sa = * ((const char * * ) a );
254
+ const char * sb = * ((const char * * ) b );
255
+ return strcmp (sa , sb );
256
+ }
241
257
242
- if ((sq & se ) != se )
258
+ static int
259
+ remove_duplicates (char * * strings , int n )
260
+ {
261
+ if (n <= 1 )
262
+ return n ;
263
+ else
243
264
{
244
- PG_FREE_IF_COPY (query , 0 );
245
- PG_FREE_IF_COPY (ex , 1 );
265
+ int i ;
266
+ char * prev = strings [0 ];
267
+ int new_n = 1 ;
246
268
247
- PG_RETURN_BOOL (false);
269
+ for (i = 1 ; i < n ; i ++ )
270
+ {
271
+ if (strcmp (strings [i ], prev ) != 0 )
272
+ {
273
+ strings [new_n ++ ] = strings [i ];
274
+ prev = strings [i ];
275
+ }
276
+ }
277
+ return new_n ;
248
278
}
279
+ }
249
280
250
- iq = GETQUERY (query );
251
- ie = GETQUERY (ex );
252
-
253
- for (i = 0 ; i < ex -> size ; i ++ )
281
+ Datum
282
+ tsq_mcontains (PG_FUNCTION_ARGS )
283
+ {
284
+ TSQuery query = PG_GETARG_TSQUERY (0 );
285
+ TSQuery ex = PG_GETARG_TSQUERY (1 );
286
+ char * * query_values ;
287
+ int query_nvalues ;
288
+ char * * ex_values ;
289
+ int ex_nvalues ;
290
+ bool result = true;
291
+
292
+ /* Extract the query terms into arrays */
293
+ query_values = collectTSQueryValues (query , & query_nvalues );
294
+ ex_values = collectTSQueryValues (ex , & ex_nvalues );
295
+
296
+ /* Sort and remove duplicates from both arrays */
297
+ qsort (query_values , query_nvalues , sizeof (char * ), cmp_string );
298
+ query_nvalues = remove_duplicates (query_values , query_nvalues );
299
+ qsort (ex_values , ex_nvalues , sizeof (char * ), cmp_string );
300
+ ex_nvalues = remove_duplicates (ex_values , ex_nvalues );
301
+
302
+ if (ex_nvalues > query_nvalues )
303
+ result = false;
304
+ else
254
305
{
255
- if (ie [i ].type != QI_VAL )
256
- continue ;
257
- for (j = 0 ; j < query -> size ; j ++ )
306
+ int i ;
307
+ int j = 0 ;
308
+
309
+ for (i = 0 ; i < ex_nvalues ; i ++ )
258
310
{
259
- if (iq [j ].type == QI_VAL &&
260
- ie [i ].qoperand .valcrc == iq [j ].qoperand .valcrc )
311
+ for (; j < query_nvalues ; j ++ )
312
+ {
313
+ if (strcmp (ex_values [i ], query_values [j ]) == 0 )
314
+ break ;
315
+ }
316
+ if (j == query_nvalues )
317
+ {
318
+ result = false;
261
319
break ;
262
- }
263
- if (j >= query -> size )
264
- {
265
- PG_FREE_IF_COPY (query , 0 );
266
- PG_FREE_IF_COPY (ex , 1 );
267
-
268
- PG_RETURN_BOOL (false);
320
+ }
269
321
}
270
322
}
271
323
272
- PG_FREE_IF_COPY (query , 0 );
273
- PG_FREE_IF_COPY (ex , 1 );
274
-
275
- PG_RETURN_BOOL (true);
324
+ PG_RETURN_BOOL (result );
276
325
}
277
326
278
327
Datum
0 commit comments