1212#include "catalog/namespace.h"
1313#include "catalog/pg_statistic.h"
1414#include "catalog/pg_type.h"
15+ #include "nodes/nodeFuncs.h"
1516#include "utils/builtins.h"
1617#include "utils/lsyscache.h"
1718#include "utils/memutils.h"
2021
2122#include "rum.h"
2223
24+ /*
25+ * FIXME:
26+ * * cache IDF
27+ * * handle prefix search
28+ */
29+
2330/* lookup table type for binary searching through MCELEMs */
2431typedef struct
2532{
@@ -77,7 +84,6 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
7784 Oid namespaceId ;
7885 Oid relId ;
7986 Relation rel = NULL ;
80- TupleDesc tupDesc ;
8187 AttrNumber attrno ;
8288 int i ;
8389 RelAttrInfo * myextra ;
@@ -119,17 +125,27 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
119125 EXIT_CHECK_TF_IDF_SOURCE ("relation not found" );
120126
121127 rel = RelationIdGetRelation (relId );
122- tupDesc = rel -> rd_att ;
123128 if (rel -> rd_rel -> relkind == RELKIND_INDEX )
124129 {
130+ int exprnum = 0 ;
131+
125132 attrno = pg_atoi (attname , sizeof (attrno ), 10 );
126133 if (attrno <= 0 || attrno > rel -> rd_index -> indnatts )
127134 EXIT_CHECK_TF_IDF_SOURCE ("wrong index attribute number" );
128135 if (rel -> rd_index -> indkey .values [attrno - 1 ] != InvalidAttrNumber )
129136 EXIT_CHECK_TF_IDF_SOURCE ("regular indexed column is specified" );
137+ for (i = 0 ; i < attrno - 1 ; i ++ )
138+ {
139+ if (rel -> rd_index -> indkey .values [i ] == InvalidAttrNumber )
140+ exprnum ++ ;
141+ }
142+ if (exprType ((Node * ) list_nth (rel -> rd_indexprs , exprnum )) != TSVECTOROID )
143+ EXIT_CHECK_TF_IDF_SOURCE ("indexed expression should be of tsvector type" );
130144 }
131145 else
132146 {
147+ TupleDesc tupDesc = rel -> rd_att ;
148+
133149 attrno = InvalidAttrNumber ;
134150 for (i = 0 ; i < tupDesc -> natts ; i ++ )
135151 {
@@ -139,13 +155,12 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
139155 break ;
140156 }
141157 }
142-
143158 if (attrno == InvalidAttrNumber )
144159 EXIT_CHECK_TF_IDF_SOURCE ("attribute not found" );
160+ if (tupDesc -> attrs [attrno - 1 ]-> atttypid != TSVECTOROID )
161+ EXIT_CHECK_TF_IDF_SOURCE ("attribute should be of tsvector type" );
145162 }
146163
147- if (tupDesc -> attrs [attrno - 1 ]-> atttypid != TSVECTOROID )
148- EXIT_CHECK_TF_IDF_SOURCE ("attribute should be of tsvector type" );
149164
150165 myextra = (RelAttrInfo * ) malloc (sizeof (RelAttrInfo ));
151166 myextra -> relId = relId ;
@@ -164,7 +179,16 @@ assign_tf_idf_source(const char *newval, void *extra)
164179{
165180 RelAttrInfo * myextra = (RelAttrInfo * ) extra ;
166181
167- TFIDFSourceParsed = * myextra ;
182+ if (myextra )
183+ {
184+ TFIDFSourceParsed = * myextra ;
185+ }
186+ else
187+ {
188+ TFIDFSourceParsed .relId = InvalidOid ;
189+ TFIDFSourceParsed .attrno = InvalidAttrNumber ;
190+ }
191+
168192 forget_tf_idf_stats ();
169193}
170194
@@ -181,6 +205,15 @@ load_tf_idf_source(void)
181205 "Memory context for TF/IDF statistics" ,
182206 ALLOCSET_DEFAULT_SIZES );
183207
208+ if (!OidIsValid (TFIDFSourceParsed .relId )
209+ || TFIDFSourceParsed .attrno == InvalidAttrNumber )
210+ {
211+ ereport (ERROR ,
212+ (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
213+ errmsg ("statistics for TD/IDF is not defined" ),
214+ errhint ("consider setting tf_idf_source GUC" )));
215+ }
216+
184217 statsTuple = SearchSysCache3 (STATRELATTINH ,
185218 ObjectIdGetDatum (TFIDFSourceParsed .relId ),
186219 Int16GetDatum (TFIDFSourceParsed .attrno ),
@@ -228,6 +261,8 @@ load_tf_idf_source(void)
228261
229262 MemoryContextSwitchTo (oldContext );
230263
264+ TDIDFLoaded = true;
265+
231266 ReleaseSysCache (statsTuple );
232267}
233268
@@ -241,7 +276,8 @@ check_load_tf_idf_source(void)
241276static void
242277forget_tf_idf_stats (void )
243278{
244- MemoryContextReset (TFIDFContext );
279+ if (TFIDFContext )
280+ MemoryContextReset (TFIDFContext );
245281 TDIDFLoaded = false;
246282}
247283
0 commit comments