@@ -149,6 +149,41 @@ calc_wraps(QueryItemWrap *wrap, int *num)
149149 return result ;
150150}
151151
152+ static bool
153+ check_allnegative (QueryItemWrap * wrap )
154+ {
155+ if (wrap -> type == QI_VAL )
156+ {
157+ return wrap -> not ;
158+ }
159+ else if (wrap -> oper == OP_AND )
160+ {
161+ int i ;
162+ for (i = 0 ; i < wrap -> operandsCount ; i ++ )
163+ {
164+ if (!check_allnegative (& wrap -> operands [i ]))
165+ return false;
166+ }
167+ return true;
168+ }
169+ else if (wrap -> oper == OP_OR )
170+ {
171+ int i ;
172+ for (i = 0 ; i < wrap -> operandsCount ; i ++ )
173+ {
174+ if (check_allnegative (& wrap -> operands [i ]))
175+ return true;
176+ }
177+ return false;
178+ }
179+ else
180+ {
181+ elog (ERROR , "check_allnegative: invalid node" );
182+ return false;
183+ }
184+
185+ }
186+
152187#define MAX_ENCODED_LEN 5
153188
154189/*
@@ -221,12 +256,12 @@ extract_wraps(QueryItemWrap *wrap, ExtractContext *context, int level)
221256{
222257 if (wrap -> type == QI_VAL )
223258 {
224- bytea * addinfo = (bytea * ) palloc (VARHDRSZ + level * MAX_ENCODED_LEN );
259+ bytea * addinfo = (bytea * ) palloc (VARHDRSZ + Max ( level , 1 ) * MAX_ENCODED_LEN );
225260 unsigned char * ptr = (unsigned char * )VARDATA (addinfo );
226261 int index = context -> index ;
227262
228263 context -> entries [index ] = PointerGetDatum (cstring_to_text_with_len (context -> operand + wrap -> distance , wrap -> length ));
229- elog (NOTICE , "%s" , text_to_cstring (DatumGetPointer (context -> entries [index ])));
264+ elog (NOTICE , "%s" , text_to_cstring (DatumGetTextP (context -> entries [index ])));
230265
231266 while (wrap -> parent )
232267 {
@@ -243,6 +278,11 @@ extract_wraps(QueryItemWrap *wrap, ExtractContext *context, int level)
243278 encode_varbyte (sum , & ptr );
244279 wrap = parent ;
245280 }
281+ if (level == 0 && wrap -> not )
282+ {
283+ encode_varbyte (1 , & ptr );
284+ encode_varbyte (4 | 1 , & ptr );
285+ }
246286 SET_VARSIZE (addinfo , ptr - (unsigned char * )addinfo );
247287
248288 context -> addInfo [index ] = PointerGetDatum (addinfo );
@@ -278,20 +318,34 @@ ruminv_extract_tsquery(PG_FUNCTION_ARGS)
278318{
279319 TSQuery query = PG_GETARG_TSQUERY (0 );
280320 int32 * nentries = (int32 * ) PG_GETARG_POINTER (1 );
321+ bool * * nullFlags = (bool * * ) PG_GETARG_POINTER (2 );
281322 Datum * * addInfo = (Datum * * ) PG_GETARG_POINTER (3 );
282323 bool * * addInfoIsNull = (bool * * ) PG_GETARG_POINTER (4 );
283324 Datum * entries = NULL ;
284325 QueryItem * item = GETQUERY (query );
285326 QueryItemWrap * wrap ;
286327 ExtractContext context ;
287328 int num = 1 ;
329+ bool extractNull ;
288330
289331 wrap = make_query_item_wrap (item , NULL , false);
290332 * nentries = calc_wraps (wrap , & num );
333+ extractNull = check_allnegative (wrap );
334+ if (extractNull )
335+ (* nentries )++ ;
291336
292337 entries = (Datum * ) palloc (sizeof (Datum ) * (* nentries ));
293338 * addInfo = (Datum * ) palloc (sizeof (Datum ) * (* nentries ));
294339 * addInfoIsNull = (bool * ) palloc (sizeof (bool ) * (* nentries ));
340+ if (extractNull )
341+ {
342+ int i ;
343+ * nullFlags = (bool * ) palloc (sizeof (bool ) * (* nentries ));
344+ for (i = 0 ; i < * nentries - 1 ; i ++ )
345+ (* nullFlags )[i ] = false;
346+ (* nullFlags )[* nentries - 1 ] = true;
347+ (* addInfoIsNull )[* nentries - 1 ] = true;
348+ }
295349
296350 context .addInfo = * addInfo ;
297351 context .addInfoIsNull = * addInfoIsNull ;
@@ -322,29 +376,32 @@ ruminv_extract_tsvector(PG_FUNCTION_ARGS)
322376 bool * * ptr_partialmatch = (bool * * ) PG_GETARG_POINTER (3 );
323377 Pointer * * extra_data = (Pointer * * ) PG_GETARG_POINTER (4 );
324378
325- /* bool **nullFlags = (bool **) PG_GETARG_POINTER(5); */
379+ bool * * nullFlags = (bool * * ) PG_GETARG_POINTER (5 );
326380 int32 * searchMode = (int32 * ) PG_GETARG_POINTER (6 );
327381 Datum * entries = NULL ;
328382
329- * nentries = vector -> size ;
383+ * nentries = vector -> size + 1 ;
384+ * extra_data = NULL ;
385+ * ptr_partialmatch = NULL ;
386+ * searchMode = GIN_SEARCH_MODE_DEFAULT ;
387+
388+ entries = (Datum * ) palloc (sizeof (Datum ) * (* nentries ));
389+ * nullFlags = (bool * ) palloc (sizeof (bool ) * (* nentries ));
330390 if (vector -> size > 0 )
331391 {
332392 int i ;
333393 WordEntry * we = ARRPTR (vector );
334394
335- * extra_data = NULL ;
336- * ptr_partialmatch = NULL ;
337- * searchMode = GIN_SEARCH_MODE_DEFAULT ;
338-
339- entries = (Datum * ) palloc (sizeof (Datum ) * vector -> size );
340395 for (i = 0 ; i < vector -> size ; i ++ )
341396 {
342397 text * txt ;
343398
344399 txt = cstring_to_text_with_len (STRPTR (vector ) + we [i ].pos , we [i ].len );
345400 entries [i ] = PointerGetDatum (txt );
401+ (* nullFlags )[i ] = false;
346402 }
347403 }
404+ (* nullFlags )[* nentries - 1 ] = true;
348405 PG_FREE_IF_COPY (vector , 0 );
349406 PG_RETURN_POINTER (entries );
350407}
@@ -368,14 +425,15 @@ ruminv_tsvector_consistent(PG_FUNCTION_ARGS)
368425 bool * recheck = (bool * ) PG_GETARG_POINTER (5 );
369426 Datum * addInfo = (Datum * ) PG_GETARG_POINTER (8 );
370427 bool * addInfoIsNull = (bool * ) PG_GETARG_POINTER (9 );
371- bool res = false;
428+ bool res = false,
429+ allFalse = true;
372430 int i ,
373431 lastIndex = 0 ;
374432 TmpNode nodes [256 ];
375433
376434 * recheck = false;
377435
378- for (i = 0 ; i < nkeys ; i ++ )
436+ for (i = 0 ; i < nkeys - 1 ; i ++ )
379437 {
380438 unsigned char * ptr ,
381439 * ptrEnd ;
@@ -385,6 +443,8 @@ ruminv_tsvector_consistent(PG_FUNCTION_ARGS)
385443 if (!check [i ])
386444 continue ;
387445
446+ allFalse = false;
447+
388448 if (addInfoIsNull [i ])
389449 elog (ERROR , "Unexpected addInfoIsNull" );
390450
@@ -445,26 +505,33 @@ ruminv_tsvector_consistent(PG_FUNCTION_ARGS)
445505 }
446506 }
447507
448- /* for (i = 0; i < lastIndex; i++ )
508+ if ( allFalse && check [ nkeys - 1 ] )
449509 {
450- elog(NOTICE, "s %d %d %d %d", i, nodes[i].sum, nodes[i].parent, nodes[i].not);
451- }*/
452-
453- for (i = lastIndex - 1 ; i >= 0 ; i -- )
510+ res = true;
511+ }
512+ else
454513 {
455- if ( nodes [ i ]. parent != -2 )
514+ /* for (i = 0; i < lastIndex; i++ )
456515 {
457- if (nodes [i ].sum > 0 )
516+ elog(NOTICE, "s %d %d %d %d", i, nodes[i].sum, nodes[i].parent, nodes[i].not);
517+ }*/
518+
519+ for (i = lastIndex - 1 ; i >= 0 ; i -- )
520+ {
521+ if (nodes [i ].parent != -2 )
458522 {
459- if (nodes [i ].parent == -1 )
460- {
461- res = true;
462- break ;
463- }
464- else
523+ if (nodes [i ].sum > 0 )
465524 {
466- int parent = nodes [i ].parent ;
467- nodes [parent ].sum += nodes [i ].not ? -1 : 1 ;
525+ if (nodes [i ].parent == -1 )
526+ {
527+ res = true;
528+ break ;
529+ }
530+ else
531+ {
532+ int parent = nodes [i ].parent ;
533+ nodes [parent ].sum += nodes [i ].not ? -1 : 1 ;
534+ }
468535 }
469536 }
470537 }
0 commit comments