12
12
#include "catalog/namespace.h"
13
13
#include "catalog/pg_statistic.h"
14
14
#include "catalog/pg_type.h"
15
+ #include "nodes/nodeFuncs.h"
15
16
#include "utils/builtins.h"
16
17
#include "utils/lsyscache.h"
17
18
#include "utils/memutils.h"
20
21
21
22
#include "rum.h"
22
23
24
+ /*
25
+ * FIXME:
26
+ * * cache IDF
27
+ * * handle prefix search
28
+ */
29
+
23
30
/* lookup table type for binary searching through MCELEMs */
24
31
typedef struct
25
32
{
@@ -77,7 +84,6 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
77
84
Oid namespaceId ;
78
85
Oid relId ;
79
86
Relation rel = NULL ;
80
- TupleDesc tupDesc ;
81
87
AttrNumber attrno ;
82
88
int i ;
83
89
RelAttrInfo * myextra ;
@@ -119,17 +125,27 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
119
125
EXIT_CHECK_TF_IDF_SOURCE ("relation not found" );
120
126
121
127
rel = RelationIdGetRelation (relId );
122
- tupDesc = rel -> rd_att ;
123
128
if (rel -> rd_rel -> relkind == RELKIND_INDEX )
124
129
{
130
+ int exprnum = 0 ;
131
+
125
132
attrno = pg_atoi (attname , sizeof (attrno ), 10 );
126
133
if (attrno <= 0 || attrno > rel -> rd_index -> indnatts )
127
134
EXIT_CHECK_TF_IDF_SOURCE ("wrong index attribute number" );
128
135
if (rel -> rd_index -> indkey .values [attrno - 1 ] != InvalidAttrNumber )
129
136
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" );
130
144
}
131
145
else
132
146
{
147
+ TupleDesc tupDesc = rel -> rd_att ;
148
+
133
149
attrno = InvalidAttrNumber ;
134
150
for (i = 0 ; i < tupDesc -> natts ; i ++ )
135
151
{
@@ -139,13 +155,12 @@ check_tf_idf_source(char **newval, void **extra, GucSource source)
139
155
break ;
140
156
}
141
157
}
142
-
143
158
if (attrno == InvalidAttrNumber )
144
159
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" );
145
162
}
146
163
147
- if (tupDesc -> attrs [attrno - 1 ]-> atttypid != TSVECTOROID )
148
- EXIT_CHECK_TF_IDF_SOURCE ("attribute should be of tsvector type" );
149
164
150
165
myextra = (RelAttrInfo * ) malloc (sizeof (RelAttrInfo ));
151
166
myextra -> relId = relId ;
@@ -164,7 +179,16 @@ assign_tf_idf_source(const char *newval, void *extra)
164
179
{
165
180
RelAttrInfo * myextra = (RelAttrInfo * ) extra ;
166
181
167
- TFIDFSourceParsed = * myextra ;
182
+ if (myextra )
183
+ {
184
+ TFIDFSourceParsed = * myextra ;
185
+ }
186
+ else
187
+ {
188
+ TFIDFSourceParsed .relId = InvalidOid ;
189
+ TFIDFSourceParsed .attrno = InvalidAttrNumber ;
190
+ }
191
+
168
192
forget_tf_idf_stats ();
169
193
}
170
194
@@ -181,6 +205,15 @@ load_tf_idf_source(void)
181
205
"Memory context for TF/IDF statistics" ,
182
206
ALLOCSET_DEFAULT_SIZES );
183
207
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
+
184
217
statsTuple = SearchSysCache3 (STATRELATTINH ,
185
218
ObjectIdGetDatum (TFIDFSourceParsed .relId ),
186
219
Int16GetDatum (TFIDFSourceParsed .attrno ),
@@ -228,6 +261,8 @@ load_tf_idf_source(void)
228
261
229
262
MemoryContextSwitchTo (oldContext );
230
263
264
+ TDIDFLoaded = true;
265
+
231
266
ReleaseSysCache (statsTuple );
232
267
}
233
268
@@ -241,7 +276,8 @@ check_load_tf_idf_source(void)
241
276
static void
242
277
forget_tf_idf_stats (void )
243
278
{
244
- MemoryContextReset (TFIDFContext );
279
+ if (TFIDFContext )
280
+ MemoryContextReset (TFIDFContext );
245
281
TDIDFLoaded = false;
246
282
}
247
283
0 commit comments