@@ -47,18 +47,33 @@ typedef struct
4747
4848typedef struct
4949{
50- QueryItem * * item ;
51- int16 nitem ;
52- QueryItem * item_first ;
53- int32 keyn ;
50+ union
51+ {
52+ /* Used in rum_ts_distance() */
53+ struct
54+ {
55+ QueryItem * * item ;
56+ int16 nitem ;
57+ }item ;
58+ /* Used in rum_tsquery_distance() */
59+ struct
60+ {
61+ QueryItem * item_first ;
62+ int32 keyn ;
63+ }key ;
64+ }data ;
5465uint8 wclass ;
5566int32 pos ;
5667}DocRepresentation ;
5768
5869typedef struct
5970{
6071TSQuery query ;
72+ /* Used in rum_tsquery_distance() */
73+ int * map_item_operand ;
74+
6175bool * operandexist ;
76+ int lenght ;
6277}QueryRepresentation ;
6378
6479typedef struct
@@ -605,15 +620,21 @@ checkcondition_QueryOperand(void *checkval, QueryOperand *val,
605620{
606621QueryRepresentation * qr = (QueryRepresentation * )checkval ;
607622
623+ /* Check for rum_tsquery_distance() */
624+ if (qr -> map_item_operand != NULL )
625+ {
626+ int i = (QueryItem * )val - GETQUERY (qr -> query );
627+ return qr -> operandexist [qr -> map_item_operand [i ]];
628+ }
629+
608630return QR_GET_OPERAND_EXISTS (qr ,val );
609631}
610632
611633static bool
612634Cover (DocRepresentation * doc ,uint32 len ,QueryRepresentation * qr ,
613- int * map_item_operand , Extention * ext )
635+ Extention * ext )
614636{
615637DocRepresentation * ptr ;
616- QueryItem * item = GETQUERY (qr -> query );
617638int lastpos = ext -> pos ;
618639int i ;
619640bool found = false;
@@ -624,7 +645,7 @@ Cover(DocRepresentation *doc, uint32 len, QueryRepresentation *qr,
624645 */
625646check_stack_depth ();
626647
627- memset (qr -> operandexist ,0 ,sizeof (bool )* qr -> query -> size );
648+ memset (qr -> operandexist ,0 ,sizeof (bool )* qr -> lenght );
628649
629650ext -> p = 0x7fffffff ;
630651ext -> q = 0 ;
@@ -633,16 +654,14 @@ Cover(DocRepresentation *doc, uint32 len, QueryRepresentation *qr,
633654/* find upper bound of cover from current position, move up */
634655while (ptr - doc < len )
635656{
636- if (ptr -> item != NULL )
657+ if (qr -> map_item_operand != NULL )
637658{
638- for (i = 0 ;i < ptr -> nitem ;i ++ )
639- QR_SET_OPERAND_EXISTS (qr ,ptr -> item [i ]);
659+ qr -> operandexist [ptr -> data .key .keyn ]= true;
640660}
641661else
642662{
643- for (i = 0 ;i < qr -> query -> size ;i ++ )
644- if (ptr -> keyn == map_item_operand [i ])
645- QR_SET_OPERAND_EXISTS (qr ,item + i );
663+ for (i = 0 ;i < ptr -> data .item .nitem ;i ++ )
664+ QR_SET_OPERAND_EXISTS (qr ,ptr -> data .item .item [i ]);
646665}
647666if (TS_execute (GETQUERY (qr -> query ), (void * )qr , false,
648667checkcondition_QueryOperand ))
@@ -662,23 +681,21 @@ Cover(DocRepresentation *doc, uint32 len, QueryRepresentation *qr,
662681if (!found )
663682return false;
664683
665- memset (qr -> operandexist ,0 ,sizeof (bool )* qr -> query -> size );
684+ memset (qr -> operandexist ,0 ,sizeof (bool )* qr -> lenght );
666685
667686ptr = doc + lastpos ;
668687
669688/* find lower bound of cover from found upper bound, move down */
670689while (ptr >=doc + ext -> pos )
671690{
672- if (ptr -> item != NULL )
691+ if (qr -> map_item_operand != NULL )
673692{
674- for (i = 0 ;i < ptr -> nitem ;i ++ )
675- QR_SET_OPERAND_EXISTS (qr ,ptr -> item [i ]);
693+ qr -> operandexist [ptr -> data .key .keyn ]= true;
676694}
677695else
678696{
679- for (i = 0 ;i < qr -> query -> size ;i ++ )
680- if (ptr -> keyn == map_item_operand [i ])
681- QR_SET_OPERAND_EXISTS (qr ,item + i );
697+ for (i = 0 ;i < ptr -> data .item .nitem ;i ++ )
698+ QR_SET_OPERAND_EXISTS (qr ,ptr -> data .item .item [i ]);
682699}
683700if (TS_execute (GETQUERY (qr -> query ), (void * )qr , true,
684701checkcondition_QueryOperand ))
@@ -704,11 +721,11 @@ Cover(DocRepresentation *doc, uint32 len, QueryRepresentation *qr,
704721}
705722
706723ext -> pos ++ ;
707- return Cover (doc ,len ,qr ,map_item_operand , ext );
724+ return Cover (doc ,len ,qr ,ext );
708725}
709726
710727static DocRepresentation *
711- get_docrep_addinfo (bool * check ,QueryRepresentation * qr ,int * map_item_operand ,
728+ get_docrep_addinfo (bool * check ,QueryRepresentation * qr ,
712729Datum * addInfo ,bool * addInfoIsNull ,uint32 * doclen )
713730{
714731QueryItem * item = GETQUERY (qr -> query );
@@ -730,7 +747,7 @@ get_docrep_addinfo(bool *check, QueryRepresentation *qr, int *map_item_operand,
730747if (item [i ].type != QI_VAL )
731748continue ;
732749
733- keyN = map_item_operand [i ];
750+ keyN = qr -> map_item_operand [i ];
734751if (!check [keyN ])
735752continue ;
736753
@@ -759,9 +776,8 @@ get_docrep_addinfo(bool *check, QueryRepresentation *qr, int *map_item_operand,
759776{
760777ptrt = decompress_pos (ptrt ,& post );
761778
762- doc [cur ].item = NULL ;
763- doc [cur ].item_first = item + i ;
764- doc [cur ].keyn = keyN ;
779+ doc [cur ].data .key .item_first = item + i ;
780+ doc [cur ].data .key .keyn = keyN ;
765781doc [cur ].pos = WEP_GETPOS (post );
766782doc [cur ].wclass = WEP_GETWEIGHT (post );
767783cur ++ ;
@@ -894,8 +910,9 @@ get_docrep(TSVector txt, QueryRepresentation *qr, uint32 *doclen)
894910{
895911int k ;
896912
897- doc [cur ].nitem = 0 ;
898- doc [cur ].item = (QueryItem * * )palloc (sizeof (QueryItem * )* qr -> query -> size );
913+ doc [cur ].data .item .nitem = 0 ;
914+ doc [cur ].data .item .item = (QueryItem * * )palloc (
915+ sizeof (QueryItem * )* qr -> query -> size );
899916
900917for (k = 0 ;k < qr -> query -> size ;k ++ )
901918{
@@ -910,18 +927,18 @@ get_docrep(TSVector txt, QueryRepresentation *qr, uint32 *doclen)
910927 * if k == i, we've already checked above that
911928 * it's type == Q_VAL
912929 */
913- doc [cur ].item [doc [cur ].nitem ]= item + k ;
914- doc [cur ].nitem ++ ;
930+ doc [cur ].data .item .item [doc [cur ].data .item .nitem ]=
931+ item + k ;
932+ doc [cur ].data .item .nitem ++ ;
915933QR_SET_OPERAND_EXISTS (qr ,item + k );
916934}
917935}
918936}
919937else
920938{
921- doc [cur ].nitem = doc [cur - 1 ].nitem ;
922- doc [cur ].item = doc [cur - 1 ].item ;
939+ doc [cur ].data . item . nitem = doc [cur - 1 ]. data . item .nitem ;
940+ doc [cur ].data . item . item = doc [cur - 1 ]. data . item .item ;
923941}
924- doc [cur ].keyn = -1 ;
925942doc [cur ].pos = WEP_GETPOS (post [j ]);
926943doc [cur ].wclass = WEP_GETWEIGHT (post [j ]);
927944cur ++ ;
@@ -945,7 +962,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, uint32 *doclen)
945962
946963static double
947964calc_score_docr (float4 * arrdata ,DocRepresentation * doc ,uint32 doclen ,
948- QueryRepresentation * qr ,int * map_item_operand , int method )
965+ QueryRepresentation * qr ,int method )
949966{
950967int32 i ;
951968Extention ext ;
@@ -962,7 +979,7 @@ calc_score_docr(float4 *arrdata, DocRepresentation *doc, uint32 doclen,
962979int ncovers = 0 ;
963980
964981MemSet (& ext ,0 ,sizeof (Extention ));
965- while (Cover (doc ,doclen ,qr ,map_item_operand , & ext ))
982+ while (Cover (doc ,doclen ,qr ,& ext ))
966983{
967984double Cpos = 0.0 ;
968985double InvSum = 0.0 ;
@@ -971,18 +988,19 @@ calc_score_docr(float4 *arrdata, DocRepresentation *doc, uint32 doclen,
971988/* Added by SK */
972989int new_cover_idx = 0 ;
973990int new_cover_key = 0 ;
974- QueryItem * item = GETQUERY (qr -> query );
975991int nitems = 0 ;
976992
977993while (ptr <=ext .end )
978994{
979995InvSum += arrdata [ptr -> wclass ];
980996/* SK: Quick and dirty hash key. Hope collisions will be not too frequent. */
981997new_cover_key = new_cover_key <<1 ;
982- if (ptr -> item != NULL )
983- new_cover_key += (int )(uintptr_t )ptr -> item ;
998+ /* For rum_ts_distance() */
999+ if (qr -> map_item_operand == NULL )
1000+ new_cover_key += (int )(uintptr_t )ptr -> data .item .item ;
1001+ /* For rum_tsquery_distance() */
9841002else
985- new_cover_key += (int )(uintptr_t )ptr -> item_first ;
1003+ new_cover_key += (int )(uintptr_t )ptr -> data . key . item_first ;
9861004ptr ++ ;
9871005}
9881006
@@ -1013,10 +1031,9 @@ calc_score_docr(float4 *arrdata, DocRepresentation *doc, uint32 doclen,
10131031cover_keys [new_cover_idx ]= new_cover_key ;
10141032
10151033/* Compute the number of query terms in the cover */
1016- for (i = 0 ;i < qr -> query -> size ;i ++ )
1017- if (item [i ].type == QI_VAL &&
1018- QR_GET_OPERAND_EXISTS (qr ,& item [i ]))
1019- nitems ++ ;
1034+ for (i = 0 ;i < qr -> lenght ;i ++ )
1035+ if (qr -> operandexist [i ])
1036+ nitems ++ ;
10201037
10211038Cpos = ((double ) (ext .end - ext .begin + 1 )) /InvSum ;
10221039
@@ -1066,26 +1083,27 @@ calc_score_docr(float4 *arrdata, DocRepresentation *doc, uint32 doclen,
10661083
10671084static float4
10681085calc_score_addinfo (float4 * arrdata ,bool * check ,TSQuery query ,
1069- int * map_item_operand ,Datum * addInfo ,bool * addInfoIsNull )
1086+ int * map_item_operand ,Datum * addInfo ,bool * addInfoIsNull ,
1087+ int nkeys )
10701088{
10711089DocRepresentation * doc ;
10721090uint32 doclen = 0 ;
10731091double Wdoc = 0.0 ;
10741092QueryRepresentation qr ;
10751093
10761094qr .query = query ;
1077- qr .operandexist = (bool * )palloc0 (sizeof (bool )* query -> size );
1095+ qr .map_item_operand = map_item_operand ;
1096+ qr .operandexist = (bool * )palloc0 (sizeof (bool )* nkeys );
1097+ qr .lenght = nkeys ;
10781098
1079- doc = get_docrep_addinfo (check ,& qr ,map_item_operand ,
1080- addInfo ,addInfoIsNull ,& doclen );
1099+ doc = get_docrep_addinfo (check ,& qr ,addInfo ,addInfoIsNull ,& doclen );
10811100if (!doc )
10821101{
10831102pfree (qr .operandexist );
10841103return 0.0 ;
10851104}
10861105
1087- Wdoc = calc_score_docr (arrdata ,doc ,doclen ,& qr ,map_item_operand ,
1088- DEF_NORM_METHOD );
1106+ Wdoc = calc_score_docr (arrdata ,doc ,doclen ,& qr ,DEF_NORM_METHOD );
10891107
10901108pfree (doc );
10911109pfree (qr .operandexist );
@@ -1103,7 +1121,9 @@ calc_score(float4 *arrdata, TSVector txt, TSQuery query, int method)
11031121QueryRepresentation qr ;
11041122
11051123qr .query = query ;
1124+ qr .map_item_operand = NULL ;
11061125qr .operandexist = (bool * )palloc0 (sizeof (bool )* query -> size );
1126+ qr .lenght = query -> size ;
11071127
11081128doc = get_docrep (txt ,& qr ,& doclen );
11091129if (!doc )
@@ -1112,7 +1132,7 @@ calc_score(float4 *arrdata, TSVector txt, TSQuery query, int method)
11121132return 0.0 ;
11131133}
11141134
1115- Wdoc = calc_score_docr (arrdata ,doc ,doclen ,& qr ,NULL , method );
1135+ Wdoc = calc_score_docr (arrdata ,doc ,doclen ,& qr ,method );
11161136
11171137if ((method & RANK_NORM_LOGLENGTH )&& txt -> size > 0 )
11181138Wdoc /=log ((double ) (count_length (txt )+ 1 ));
@@ -1142,14 +1162,15 @@ rum_tsquery_distance(PG_FUNCTION_ARGS)
11421162bool * check = (bool * )PG_GETARG_POINTER (0 );
11431163
11441164TSQuery query = PG_GETARG_TSQUERY (2 );
1165+ int nkeys = PG_GETARG_INT32 (3 );
11451166Pointer * extra_data = (Pointer * )PG_GETARG_POINTER (4 );
11461167Datum * addInfo = (Datum * )PG_GETARG_POINTER (8 );
11471168bool * addInfoIsNull = (bool * )PG_GETARG_POINTER (9 );
11481169float8 res ;
11491170int * map_item_operand = (int * ) (extra_data [0 ]);
11501171
11511172res = calc_score_addinfo (weights ,check ,query ,map_item_operand ,
1152- addInfo ,addInfoIsNull );
1173+ addInfo ,addInfoIsNull , nkeys );
11531174
11541175PG_FREE_IF_COPY (query ,2 );
11551176if (res == 0 )