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