1+ /*-------------------------------------------------------------------------
2+ *
3+ * tf_idf.c
4+ * Implementation of TD/IDF statistics calculation.
5+ *
6+ * Portions Copyright (c) 2017, Postgres Professional
7+ *
8+ *-------------------------------------------------------------------------
9+ */
10+ #include "postgres.h"
11+
12+ #include "catalog/namespace.h"
13+ #include "catalog/pg_type.h"
14+ #include "utils/builtins.h"
15+ #include "utils/lsyscache.h"
16+ #include "utils/varlena.h"
17+
18+ #include "rum.h"
19+
20+ char * TFIDFSource ;
21+
22+ #define EXIT_CHECK_TF_IDF_SOURCE (error ) \
23+ do { \
24+ GUC_check_errdetail(error); \
25+ pfree(rawname); \
26+ list_free(namelist); \
27+ if (rel) \
28+ RelationClose(rel); \
29+ return false; \
30+ } while (false);
31+
32+ bool
33+ check_tf_idf_source (char * * newval , void * * extra , GucSource source )
34+ {
35+ char * rawname ;
36+ char * attname ;
37+ List * namelist ;
38+ Oid namespaceId ;
39+ Oid relId ;
40+ Relation rel = NULL ;
41+ TupleDesc tupDesc ;
42+ AttrNumber attrno ;
43+ int i ;
44+
45+ /* Need a modifiable copy of string */
46+ rawname = pstrdup (* newval );
47+
48+ /* Parse string into list of identifiers */
49+ if (!SplitIdentifierString (rawname , '.' , & namelist ))
50+ {
51+ /* syntax error in name list */
52+ EXIT_CHECK_TF_IDF_SOURCE ("List syntax is invalid." );
53+ }
54+
55+ switch (list_length (namelist ))
56+ {
57+ case 0 :
58+ return true;
59+ case 1 :
60+ EXIT_CHECK_TF_IDF_SOURCE ("improper column name (there should be at least 2 dotted names)" );
61+ case 2 :
62+ relId = RelnameGetRelid (linitial (namelist ));
63+ attname = lsecond (namelist );
64+ break ;
65+ case 3 :
66+ /* use exact schema given */
67+ namespaceId = LookupExplicitNamespace (linitial (namelist ), true);
68+ if (!OidIsValid (namespaceId ))
69+ relId = InvalidOid ;
70+ else
71+ relId = get_relname_relid (lsecond (namelist ), namespaceId );
72+ attname = lthird (namelist );
73+ break ;
74+ default :
75+ EXIT_CHECK_TF_IDF_SOURCE ("improper column name (too many dotted names)" );
76+ }
77+
78+ if (!OidIsValid (relId ))
79+ EXIT_CHECK_TF_IDF_SOURCE ("relation not found" );
80+
81+ rel = RelationIdGetRelation (relId );
82+ tupDesc = rel -> rd_att ;
83+ if (rel -> rd_rel -> relkind == RELKIND_INDEX )
84+ {
85+ attrno = pg_atoi (attname , sizeof (attrno ), 10 );
86+ if (attrno <= 0 || attrno > rel -> rd_index -> indnatts )
87+ EXIT_CHECK_TF_IDF_SOURCE ("wrong index attribute number" );
88+ if (rel -> rd_index -> indkey .values [attrno - 1 ] != InvalidAttrNumber )
89+ EXIT_CHECK_TF_IDF_SOURCE ("regular indexed column is specified" );
90+ }
91+ else
92+ {
93+ attrno = InvalidAttrNumber ;
94+ for (i = 0 ; i < tupDesc -> natts ; i ++ )
95+ {
96+ if (namestrcmp (& (tupDesc -> attrs [i ]-> attname ), attname ) == 0 )
97+ {
98+ attrno = tupDesc -> attrs [i ]-> attnum ;
99+ break ;
100+ }
101+ }
102+
103+ if (attrno == InvalidAttrNumber )
104+ EXIT_CHECK_TF_IDF_SOURCE ("attribute not found" );
105+ }
106+
107+ if (tupDesc -> attrs [attrno - 1 ]-> atttypid != TSVECTOROID )
108+ EXIT_CHECK_TF_IDF_SOURCE ("attribute should be of tsvector type" );
109+
110+ pfree (rawname );
111+ list_free (namelist );
112+ RelationClose (rel );
113+ return true;
114+ }
115+
116+
117+ void
118+ assign_tf_idf_source (const char * newval , void * extra )
119+ {
120+
121+ }
0 commit comments