2727#include "access/relation.h"
2828#include "utils/varlena.h"
2929#include "rum.h"
30+ #include "tsearch/ts_type.h"
3031
3132PG_FUNCTION_INFO_V1 (rum_metapage_info );
3233PG_FUNCTION_INFO_V1 (rum_page_opaque_info );
@@ -115,6 +116,8 @@ static Datum category_get_datum_text(RumNullCategory category);
115116static Oid find_add_info_oid (RumState * rum_state_ptr );
116117static OffsetNumber find_add_info_atrr_num (RumState * rum_state_ptr );
117118
119+ static Datum get_positions_to_text_datum (Datum add_info );
120+
118121/*
119122 * The rum_metapage_info() function is used to retrieve
120123 * information stored on the meta page of the rum index.
@@ -386,12 +389,6 @@ rum_leaf_data_page_items(PG_FUNCTION_ARGS)
386389 /* Allocating memory for a long-lived structure */
387390 inter_call_data = palloc (sizeof (rum_page_items_state ));
388391
389- /* Initializing the RumState structure */
390- inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
391- initRumState (inter_call_data -> rum_state_ptr , rel );
392-
393- relation_close (rel , AccessShareLock );
394-
395392 /* Getting a copy of the page from the raw page */
396393 page = get_page_from_raw (raw_page );
397394
@@ -422,6 +419,12 @@ rum_leaf_data_page_items(PG_FUNCTION_ARGS)
422419 errdetail ("Flags %04X, expected %04X" ,
423420 opaq -> flags , (RUM_DATA | RUM_LEAF ))));
424421
422+ /* Initializing the RumState structure */
423+ inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
424+ initRumState (inter_call_data -> rum_state_ptr , rel );
425+
426+ relation_close (rel , AccessShareLock );
427+
425428 /* Build a tuple descriptor for our result type */
426429 if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
427430 elog (ERROR , "return type must be a row type" );
@@ -494,9 +497,24 @@ rum_leaf_data_page_items(PG_FUNCTION_ARGS)
494497 values [2 ] = BoolGetDatum (high_key_ptr -> addInfoIsNull );
495498
496499 /* Returning add info */
497- if (!high_key_ptr -> addInfoIsNull && inter_call_data -> add_info_oid != 0 )
500+ if (!(high_key_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
501+ && inter_call_data -> add_info_oid != BYTEAOID )
502+ {
498503 values [3 ] = get_datum_text_by_oid (high_key_ptr -> addInfo ,
499504 inter_call_data -> add_info_oid );
505+ }
506+
507+ /*
508+ * In this case, we are dealing with the positions
509+ * of tokens and they need to be decoded.
510+ */
511+ else if (!(high_key_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
512+ && inter_call_data -> add_info_oid == BYTEAOID )
513+ {
514+ /* values[3] = get_positions_to_text_datum(high_key_ptr->addInfo); */
515+ values [3 ] = CStringGetTextDatum ("high key positions in posting tree is not supported" );
516+ }
517+
500518 else nulls [3 ] = true;
501519
502520 /* Forming the returned tuple */
@@ -536,8 +554,23 @@ rum_leaf_data_page_items(PG_FUNCTION_ARGS)
536554 values [2 ] = BoolGetDatum (rum_item_ptr -> addInfoIsNull );
537555
538556 /* Returning add info */
539- if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0 )
540- values [3 ] = get_datum_text_by_oid (rum_item_ptr -> addInfo , inter_call_data -> add_info_oid );
557+ if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
558+ && inter_call_data -> add_info_oid != BYTEAOID )
559+ {
560+ values [3 ] = get_datum_text_by_oid (rum_item_ptr -> addInfo ,
561+ inter_call_data -> add_info_oid );
562+ }
563+
564+ /*
565+ * In this case, we are dealing with the positions
566+ * of tokens and they need to be decoded.
567+ */
568+ else if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
569+ && inter_call_data -> add_info_oid == BYTEAOID )
570+ {
571+ values [3 ] = get_positions_to_text_datum (rum_item_ptr -> addInfo );
572+ }
573+
541574 else nulls [3 ] = true;
542575
543576 /* Forming the returned tuple */
@@ -619,12 +652,6 @@ rum_internal_data_page_items(PG_FUNCTION_ARGS)
619652 /* Allocating memory for a long-lived structure */
620653 inter_call_data = palloc (sizeof (rum_page_items_state ));
621654
622- /* Initializing the RumState structure */
623- inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
624- initRumState (inter_call_data -> rum_state_ptr , rel );
625-
626- relation_close (rel , AccessShareLock );
627-
628655 /* Getting a copy of the page from the raw page */
629656 page = get_page_from_raw (raw_page );
630657
@@ -655,6 +682,12 @@ rum_internal_data_page_items(PG_FUNCTION_ARGS)
655682 errdetail ("Flags %04X, expected %04X" ,
656683 opaq -> flags , (RUM_DATA & ~RUM_LEAF ))));
657684
685+ /* Initializing the RumState structure */
686+ inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
687+ initRumState (inter_call_data -> rum_state_ptr , rel );
688+
689+ relation_close (rel , AccessShareLock );
690+
658691 /* Build a tuple descriptor for our result type */
659692 if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
660693 elog (ERROR , "return type must be a row type" );
@@ -721,9 +754,24 @@ rum_internal_data_page_items(PG_FUNCTION_ARGS)
721754 values [3 ] = BoolGetDatum (high_key_ptr -> addInfoIsNull );
722755
723756 /* Returning add info */
724- if (!high_key_ptr -> addInfoIsNull && inter_call_data -> add_info_oid != 0 )
757+ if (!(high_key_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
758+ && inter_call_data -> add_info_oid != BYTEAOID )
759+ {
725760 values [4 ] = get_datum_text_by_oid (high_key_ptr -> addInfo ,
726761 inter_call_data -> add_info_oid );
762+ }
763+
764+ /*
765+ * In this case, we are dealing with the positions
766+ * of tokens and they need to be decoded.
767+ */
768+ else if (!(high_key_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
769+ && inter_call_data -> add_info_oid == BYTEAOID )
770+ {
771+ /* values[4] = get_positions_to_text_datum(high_key_ptr->addInfo); */
772+ values [4 ] = CStringGetTextDatum ("high key positions in posting tree is not supported" );
773+ }
774+
727775 else nulls [4 ] = true;
728776
729777 /* Forming the returned tuple */
@@ -745,9 +793,24 @@ rum_internal_data_page_items(PG_FUNCTION_ARGS)
745793 values [3 ] = BoolGetDatum (posting_item_ptr -> item .addInfoIsNull );
746794
747795 /* Returning add info */
748- if (!posting_item_ptr -> item .addInfoIsNull && inter_call_data -> add_info_oid != 0 )
796+ if (!posting_item_ptr -> item .addInfoIsNull && inter_call_data -> add_info_oid != 0
797+ && inter_call_data -> add_info_oid != BYTEAOID )
798+ {
749799 values [4 ] = get_datum_text_by_oid (posting_item_ptr -> item .addInfo ,
750800 inter_call_data -> add_info_oid );
801+ }
802+
803+ /*
804+ * In this case, we are dealing with the positions
805+ * of tokens and they need to be decoded.
806+ */
807+ else if (!posting_item_ptr -> item .addInfoIsNull && inter_call_data -> add_info_oid != 0
808+ && inter_call_data -> add_info_oid == BYTEAOID )
809+ {
810+ /* values[4] = get_positions_to_text_datum(posting_item_ptr->item.addInfo); */
811+ values [4 ] = CStringGetTextDatum ("high key positions in posting tree is not supported" );
812+ }
813+
751814 else nulls [4 ] = true;
752815
753816 /* Forming the returned tuple */
@@ -833,12 +896,6 @@ rum_leaf_entry_page_items(PG_FUNCTION_ARGS)
833896 /* Allocating memory for a long-lived structure */
834897 inter_call_data = palloc (sizeof (rum_page_items_state ));
835898
836- /* Initializing the RumState structure */
837- inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
838- initRumState (inter_call_data -> rum_state_ptr , rel );
839-
840- relation_close (rel , AccessShareLock );
841-
842899 /* Getting a copy of the page from the raw page */
843900 page = get_page_from_raw (raw_page );
844901
@@ -869,6 +926,12 @@ rum_leaf_entry_page_items(PG_FUNCTION_ARGS)
869926 errdetail ("Flags %04X, expected %04X" ,
870927 opaq -> flags , RUM_LEAF )));
871928
929+ /* Initializing the RumState structure */
930+ inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
931+ initRumState (inter_call_data -> rum_state_ptr , rel );
932+
933+ relation_close (rel , AccessShareLock );
934+
872935 /* Build a tuple descriptor for our result type */
873936 if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
874937 elog (ERROR , "return type must be a row type" );
@@ -1008,10 +1071,23 @@ rum_leaf_entry_page_items(PG_FUNCTION_ARGS)
10081071 values [3 ] = ItemPointerGetDatum (& (rum_item_ptr -> iptr ));
10091072 values [4 ] = BoolGetDatum (rum_item_ptr -> addInfoIsNull );
10101073
1011-
10121074 /* Returning add info */
1013- if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0 )
1075+ if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0 &&
1076+ inter_call_data -> add_info_oid != BYTEAOID )
1077+ {
10141078 values [5 ] = get_datum_text_by_oid (rum_item_ptr -> addInfo , inter_call_data -> add_info_oid );
1079+ }
1080+
1081+ /*
1082+ * In this case, we are dealing with the positions
1083+ * of tokens and they need to be decoded.
1084+ */
1085+ else if (!(rum_item_ptr -> addInfoIsNull ) && inter_call_data -> add_info_oid != 0
1086+ && inter_call_data -> add_info_oid == BYTEAOID )
1087+ {
1088+ values [5 ] = get_positions_to_text_datum (rum_item_ptr -> addInfo );
1089+ }
1090+
10151091 else nulls [5 ] = true;
10161092
10171093 /* The current IndexTuple does not contain a posting tree */
@@ -1101,12 +1177,6 @@ rum_internal_entry_page_items(PG_FUNCTION_ARGS)
11011177 /* Allocating memory for a long-lived structure */
11021178 inter_call_data = palloc (sizeof (rum_page_items_state ));
11031179
1104- /* Initializing the RumState structure */
1105- inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
1106- initRumState (inter_call_data -> rum_state_ptr , rel );
1107-
1108- relation_close (rel , AccessShareLock );
1109-
11101180 /* Getting a copy of the page from the raw page */
11111181 page = get_page_from_raw (raw_page );
11121182
@@ -1137,6 +1207,12 @@ rum_internal_entry_page_items(PG_FUNCTION_ARGS)
11371207 errdetail ("Flags %04X, expected %04X" ,
11381208 opaq -> flags , 0 )));
11391209
1210+ /* Initializing the RumState structure */
1211+ inter_call_data -> rum_state_ptr = palloc (sizeof (RumState ));
1212+ initRumState (inter_call_data -> rum_state_ptr , rel );
1213+
1214+ relation_close (rel , AccessShareLock );
1215+
11401216 /* Build a tuple descriptor for our result type */
11411217 if (get_call_result_type (fcinfo , NULL , & tupdesc ) != TYPEFUNC_COMPOSITE )
11421218 elog (ERROR , "return type must be a row type" );
@@ -1355,7 +1431,7 @@ get_page_from_raw(bytea *raw_page)
13551431 * TODO: All types accepted by rum must be checked, but
13561432 * perhaps some types are missing or some are superfluous.
13571433 */
1358- static Datum
1434+ static Datum
13591435get_datum_text_by_oid (Datum info , Oid info_oid )
13601436{
13611437 char * str_info = NULL ;
@@ -1602,3 +1678,69 @@ find_add_info_atrr_num(RumState *rum_state_ptr)
16021678 /* Need to add 1 because the attributes are numbered from 1 */
16031679 return add_info_attr_num + 1 ;
16041680}
1681+
1682+ #define POS_STR_BUF_LENGHT 1024
1683+ #define POS_MAX_VAL_LENGHT 6
1684+
1685+ /*
1686+ * A function for extracting the positions of tokens from additional
1687+ * information. Returns a string in which the positions of the tokens
1688+ * are recorded. The memory that the string occupies must be cleared later.
1689+ */
1690+ static Datum
1691+ get_positions_to_text_datum (Datum add_info )
1692+ {
1693+ bytea * positions ;
1694+ char * ptrt ;
1695+ WordEntryPos position = 0 ;
1696+ int32 npos ;
1697+
1698+ Datum res ;
1699+ char * positions_str ;
1700+ char * positions_str_cur_ptr ;
1701+ int cur_max_str_lenght ;
1702+
1703+ positions = DatumGetByteaP (add_info );
1704+ ptrt = (char * ) VARDATA_ANY (positions );
1705+ npos = count_pos (VARDATA_ANY (positions ),
1706+ VARSIZE_ANY_EXHDR (positions ));
1707+
1708+ /* Initialize the string */
1709+ positions_str = (char * ) palloc (POS_STR_BUF_LENGHT * sizeof (char ));
1710+ positions_str [0 ] = '\0' ;
1711+ cur_max_str_lenght = POS_STR_BUF_LENGHT ;
1712+ positions_str_cur_ptr = positions_str ;
1713+
1714+ /* Extract the positions of the tokens and put them in the string */
1715+ for (int i = 0 ; i < npos ; i ++ )
1716+ {
1717+ /* At each iteration decode the position */
1718+ ptrt = decompress_pos (ptrt , & position );
1719+
1720+ /* Write this position in the string */
1721+ sprintf (positions_str_cur_ptr , "%d," , position );
1722+
1723+ /* Moving the pointer forward */
1724+ positions_str_cur_ptr += strlen (positions_str_cur_ptr );
1725+
1726+ /*
1727+ * Check that there is not too little left to the
1728+ * end of the line and, if necessary, overspend
1729+ * the memory.
1730+ */
1731+ if (cur_max_str_lenght - (positions_str_cur_ptr - positions_str ) <= POS_MAX_VAL_LENGHT )
1732+ {
1733+ cur_max_str_lenght += POS_STR_BUF_LENGHT ;
1734+ positions_str = (char * ) repalloc (positions_str , cur_max_str_lenght * sizeof (char ));
1735+ positions_str_cur_ptr = positions_str + strlen (positions_str );
1736+ }
1737+ }
1738+
1739+ /* Delete the last comma if there has been at least one iteration of the loop */
1740+ if (npos > 0 )
1741+ positions_str [strlen (positions_str ) - 1 ] = '\0' ;
1742+
1743+ res = CStringGetTextDatum (positions_str );
1744+ pfree (positions_str );
1745+ return res ;
1746+ }
0 commit comments