@@ -524,28 +524,30 @@ rum_extract_tsquery(PG_FUNCTION_ARGS)
524
524
* reconstruct partial tsvector from set of index entries
525
525
*/
526
526
static TSVector
527
- rum_reconstruct_tsvector (bool * check ,TSQuery query ,int * map_item_operand ,
527
+ rum_reconstruct_tsvector (bool * check ,int32 nkeys ,TSQuery query ,
528
+ int * map_item_operand ,
528
529
Datum * addInfo ,bool * addInfoIsNull )
529
530
{
530
531
TSVector tsv ;
531
- int cntwords = 0 ;
532
+ int nWords = 0 , currentWord = 0 ;
532
533
int i = 0 ;
533
534
QueryItem * item = GETQUERY (query );
534
535
char * operandData = GETOPERAND (query );
535
- struct
536
- {
537
- char * word ;
538
- char * posptr ;
539
- int32 npos ;
540
- int32 wordlen ;
541
- }* restoredWordEntry ;
542
536
int len = 0 ,totallen ;
543
537
WordEntry * ptr ;
544
538
char * str ;
545
539
int stroff ;
546
540
541
+ for (i = 0 ;i < nkeys ;i ++ )
542
+ if (check [i ])
543
+ nWords ++ ;
544
+
545
+ totallen = CALCDATASIZE (nWords ,nWords * 16 * sizeof (uint16 ));/* estimation */
546
+ tsv = palloc (totallen );
547
+ tsv -> size = nWords ;
547
548
548
- restoredWordEntry = palloc (sizeof (* restoredWordEntry )* query -> size );
549
+ str = STRPTR (tsv );
550
+ stroff = 0 ;
549
551
550
552
/*
551
553
* go through query to collect lexemes and add to them
@@ -560,84 +562,77 @@ rum_reconstruct_tsvector(bool *check, TSQuery query, int *map_item_operand,
560
562
561
563
if (check [keyN ]== true)
562
564
{
565
+ int npos = 0 ;
566
+ bytea * positions ;
567
+
563
568
/*
564
569
* entries could be repeated in tsquery, do not visit them twice
565
570
* or more. Modifying of check array (entryRes) is safe
566
571
*/
567
572
check [keyN ]= false;
568
573
569
- restoredWordEntry [cntwords ].word = operandData + item -> qoperand .distance ;
570
- restoredWordEntry [cntwords ].wordlen = item -> qoperand .length ;
571
-
572
574
len += item -> qoperand .length ;
573
575
574
576
if (addInfoIsNull [keyN ]== false)
575
577
{
576
- bytea * positions = DatumGetByteaP (addInfo [keyN ]);
578
+ positions = DatumGetByteaP (addInfo [keyN ]);
577
579
578
- restoredWordEntry [cntwords ].npos = count_pos (VARDATA_ANY (positions ),
579
- VARSIZE_ANY_EXHDR (positions ));
580
- restoredWordEntry [cntwords ].posptr = VARDATA_ANY (positions );
580
+ npos = count_pos (VARDATA_ANY (positions ),
581
+ VARSIZE_ANY_EXHDR (positions ));
581
582
582
583
len = SHORTALIGN (len );
583
- len += sizeof (uint16 )+
584
- restoredWordEntry [cntwords ].npos * sizeof (WordEntryPos );
584
+ len += sizeof (uint16 )+ npos * sizeof (WordEntryPos );
585
585
}
586
- else
586
+
587
+ while (CALCDATASIZE (nWords ,len )> totallen )
587
588
{
588
- restoredWordEntry [cntwords ].npos = 0 ;
589
+ totallen *=2 ;
590
+ tsv = repalloc (tsv ,totallen );
591
+ str = STRPTR (tsv );
589
592
}
590
593
591
- cntwords ++ ;
592
- }
593
- }
594
- item ++ ;
595
- }
594
+ ptr = ARRPTR (tsv )+ currentWord ;
596
595
597
- totallen = CALCDATASIZE (cntwords ,len );
598
- tsv = palloc (totallen );
599
- SET_VARSIZE (tsv ,totallen );
600
- tsv -> size = cntwords ;
601
-
602
- ptr = ARRPTR (tsv );
603
- str = STRPTR (tsv );
604
- stroff = 0 ;
596
+ ptr -> len = item -> qoperand .length ;
597
+ ptr -> pos = stroff ;
598
+ memcpy (str + stroff ,operandData + item -> qoperand .distance ,ptr -> len );
599
+ stroff += ptr -> len ;
605
600
606
- for ( i = 0 ; i < cntwords ; i ++ )
607
- {
608
- ptr -> len = restoredWordEntry [ i ]. wordlen ;
609
- ptr -> pos = stroff ;
610
- memcpy ( str + stroff , restoredWordEntry [ i ]. word , ptr -> len ) ;
611
- stroff += ptr -> len ;
601
+ if ( npos )
602
+ {
603
+ WordEntryPos * wptr ,
604
+ posv = 0 ;
605
+ int j ;
606
+ char * posptr = VARDATA_ANY ( positions ) ;
612
607
613
- if (restoredWordEntry [i ].npos )
614
- {
615
- WordEntryPos * wptr ,
616
- post = 0 ;
617
- int j ;
608
+ ptr -> haspos = 1 ;
618
609
619
- ptr -> haspos = 1 ;
610
+ stroff = SHORTALIGN (stroff );
611
+ * (uint16 * ) (str + stroff )= npos ;
612
+ wptr = POSDATAPTR (tsv ,ptr );
620
613
621
- stroff = SHORTALIGN (stroff );
622
- * (uint16 * ) (str + stroff )= restoredWordEntry [i ].npos ;
623
- wptr = POSDATAPTR (tsv ,ptr );
614
+ for (j = 0 ;j < npos ;j ++ )
615
+ {
616
+ posptr = decompress_pos (posptr ,& posv );
617
+ wptr [j ]= posv ;
618
+ }
619
+ stroff += sizeof (uint16 )+ npos * sizeof (WordEntryPos );
620
+ }
621
+ else
622
+ {
623
+ ptr -> haspos = 0 ;
624
+ }
624
625
625
- for (j = 0 ;j < restoredWordEntry [i ].npos ;j ++ )
626
- {
627
- restoredWordEntry [i ].posptr = decompress_pos (restoredWordEntry [i ].posptr ,& post );
628
- wptr [j ]= post ;
626
+ currentWord ++ ;
629
627
}
630
- stroff += sizeof (uint16 )+ restoredWordEntry [i ].npos * sizeof (WordEntryPos );
631
- }
632
- else
633
- {
634
- ptr -> haspos = 0 ;
635
628
}
636
629
637
- ptr ++ ;
630
+ item ++ ;
638
631
}
639
632
640
- pfree (restoredWordEntry );
633
+ Assert (nWords == currentWord );
634
+ totallen = CALCDATASIZE (nWords ,len );
635
+ SET_VARSIZE (tsv ,totallen );
641
636
642
637
return tsv ;
643
638
}
@@ -649,15 +644,15 @@ rum_tsquery_distance(PG_FUNCTION_ARGS)
649
644
650
645
/* StrategyNumber strategy = PG_GETARG_UINT16(1); */
651
646
TSQuery query = PG_GETARG_TSQUERY (2 );
652
- /* int32nkeys = PG_GETARG_INT32(3); */
647
+ int32 nkeys = PG_GETARG_INT32 (3 );
653
648
Pointer * extra_data = (Pointer * )PG_GETARG_POINTER (4 );
654
649
Datum * addInfo = (Datum * )PG_GETARG_POINTER (8 );
655
650
bool * addInfoIsNull = (bool * )PG_GETARG_POINTER (9 );
656
651
float8 res ;
657
652
int * map_item_operand = (int * ) (extra_data [0 ]);
658
653
TSVector tsv ;
659
654
660
- tsv = rum_reconstruct_tsvector (check ,query ,map_item_operand ,
655
+ tsv = rum_reconstruct_tsvector (check ,nkeys , query ,map_item_operand ,
661
656
addInfo ,addInfoIsNull );
662
657
663
658
res = DatumGetFloat4 (DirectFunctionCall2Coll (ts_rank_tt ,