2 * interface functions to dictionary
3 * Teodor Sigaev <teodor@sigaev.ru>
9 #include "catalog/pg_type.h"
10 #include "executor/spi.h"
12 #include "utils/array.h"
13 #include "utils/memutils.h"
19 /*********top interface**********/
22 init_dict(Oid id, DictInfo * dict)
30 char *nsp = get_namespace(TSNSP_FunctionOid);
33 pars[0] = ObjectIdGetDatum(id);
35 memset(dict, 0, sizeof(DictInfo));
37 sprintf(buf, "select dict_init, dict_initoption, dict_lexize from %s.pg_ts_dict where oid = $1", nsp);
39 plan = SPI_prepare(buf, 1, arg);
41 ts_error(ERROR, "SPI_prepare() failed");
43 stat = SPI_execp(plan, pars, " ", 1);
45 ts_error(ERROR, "SPI_execp return %d", stat);
46 if (SPI_processed > 0)
51 oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
52 if (!(isnull || oid == InvalidOid))
54 opt = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull);
55 dict->dictionary = (void *) DatumGetPointer(OidFunctionCall1(oid, opt));
57 oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 3, &isnull));
58 if (isnull || oid == InvalidOid)
59 ts_error(ERROR, "Null dict_lexize for dictonary %d", id);
60 fmgr_info_cxt(oid, &(dict->lexize_info), TopMemoryContext);
64 ts_error(ERROR, "No dictionary with id %d", id);
78 static DictList DList = {NULL, 0, 0, NULL, {0, 0, NULL}};
83 freeSNMap(&(DList.name2id_map));
84 /* XXX need to free DList.list[*].dictionary */
87 memset(&DList, 0, sizeof(DictList));
92 comparedict(const void *a, const void *b)
94 if (((DictInfo *) a)->dict_id == ((DictInfo *) b)->dict_id)
96 return (((DictInfo *) a)->dict_id < ((DictInfo *) b)->dict_id) ? -1 : 1;
103 if (DList.last_dict && DList.last_dict->dict_id == id)
104 return DList.last_dict;
107 /* already used dict */
113 DList.last_dict = bsearch(&key, DList.list, DList.len, sizeof(DictInfo), comparedict);
114 if (DList.last_dict != NULL)
115 return DList.last_dict;
119 if (DList.len == DList.reallen)
122 int reallen = (DList.reallen) ? 2 * DList.reallen : 16;
124 tmp = (DictInfo *) realloc(DList.list, sizeof(DictInfo) * reallen);
126 ts_error(ERROR, "No memory");
127 DList.reallen = reallen;
130 DList.last_dict = &(DList.list[DList.len]);
131 init_dict(id, DList.last_dict);
134 qsort(DList.list, DList.len, sizeof(DictInfo), comparedict);
135 return finddict(id); /* qsort changed order!! */ ;
139 name2id_dict(text *name)
145 Oid id = findSNMap_t(&(DList.name2id_map), name);
151 pars[0] = PointerGetDatum(name);
156 nsp = get_namespace(TSNSP_FunctionOid);
158 sprintf(buf, "select oid from %s.pg_ts_dict where dict_name = $1", nsp);
160 plan = SPI_prepare(buf, 1, arg);
162 ts_error(ERROR, "SPI_prepare() failed");
164 stat = SPI_execp(plan, pars, " ", 1);
166 ts_error(ERROR, "SPI_execp return %d", stat);
167 if (SPI_processed > 0)
168 id = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
170 ts_error(ERROR, "No dictionary with name '%s'", text2char(name));
173 addSNMap_t(&(DList.name2id_map), name, id);
178 /******sql-level interface******/
179 PG_FUNCTION_INFO_V1(lexize);
180 Datum lexize(PG_FUNCTION_ARGS);
183 lexize(PG_FUNCTION_ARGS)
185 text *in = PG_GETARG_TEXT_P(1);
193 dict = finddict(PG_GETARG_OID(0));
195 ptr = res = (TSLexeme *) DatumGetPointer(
196 FunctionCall3(&(dict->lexize_info),
197 PointerGetDatum(dict->dictionary),
198 PointerGetDatum(VARDATA(in)),
199 Int32GetDatum(VARSIZE(in) - VARHDRSZ)
202 PG_FREE_IF_COPY(in, 1);
206 PG_RETURN_POINTER(NULL);
213 da = (Datum *) palloc(sizeof(Datum) * (ptr - res + 1));
217 da[ptr - res] = PointerGetDatum(char2text(ptr->lexeme));
233 pfree(DatumGetPointer(da[ptr - res]));
240 PG_RETURN_POINTER(a);
243 PG_FUNCTION_INFO_V1(lexize_byname);
244 Datum lexize_byname(PG_FUNCTION_ARGS);
246 lexize_byname(PG_FUNCTION_ARGS)
248 text *dictname = PG_GETARG_TEXT_P(0);
253 res = DirectFunctionCall3(
255 ObjectIdGetDatum(name2id_dict(dictname)),
259 PG_FREE_IF_COPY(dictname, 0);
261 PG_RETURN_DATUM(res);
266 static Oid currect_dictionary_id = 0;
268 PG_FUNCTION_INFO_V1(set_curdict);
269 Datum set_curdict(PG_FUNCTION_ARGS);
271 set_curdict(PG_FUNCTION_ARGS)
274 finddict(PG_GETARG_OID(0));
275 currect_dictionary_id = PG_GETARG_OID(0);
279 PG_FUNCTION_INFO_V1(set_curdict_byname);
280 Datum set_curdict_byname(PG_FUNCTION_ARGS);
282 set_curdict_byname(PG_FUNCTION_ARGS)
284 text *dictname = PG_GETARG_TEXT_P(0);
289 ObjectIdGetDatum(name2id_dict(dictname))
291 PG_FREE_IF_COPY(dictname, 0);
295 PG_FUNCTION_INFO_V1(lexize_bycurrent);
296 Datum lexize_bycurrent(PG_FUNCTION_ARGS);
298 lexize_bycurrent(PG_FUNCTION_ARGS)
303 if (currect_dictionary_id == 0)
305 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
306 errmsg("no currect dictionary"),
307 errhint("Execute select set_curdict().")));
309 res = DirectFunctionCall3(
311 ObjectIdGetDatum(currect_dictionary_id),
316 PG_RETURN_DATUM(res);