1 /*-------------------------------------------------------------------------
2  *
3  * dict.c
4  *		Standard interface to dictionary
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  *
8  *
9  * IDENTIFICATION
10  *	  src/backend/tsearch/dict.c
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15 
16 #include "catalog/pg_type.h"
17 #include "tsearch/ts_cache.h"
18 #include "tsearch/ts_utils.h"
19 #include "utils/builtins.h"
20 
21 
22 /*
23  * Lexize one word by dictionary, mostly debug function
24  */
25 Datum
ts_lexize(PG_FUNCTION_ARGS)26 ts_lexize(PG_FUNCTION_ARGS)
27 {
28 	Oid			dictId = PG_GETARG_OID(0);
29 	text	   *in = PG_GETARG_TEXT_PP(1);
30 	ArrayType  *a;
31 	TSDictionaryCacheEntry *dict;
32 	TSLexeme   *res,
33 			   *ptr;
34 	Datum	   *da;
35 	DictSubState dstate = {false, false, NULL};
36 
37 	dict = lookup_ts_dictionary_cache(dictId);
38 
39 	res = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
40 													 PointerGetDatum(dict->dictData),
41 													 PointerGetDatum(VARDATA_ANY(in)),
42 													 Int32GetDatum(VARSIZE_ANY_EXHDR(in)),
43 													 PointerGetDatum(&dstate)));
44 
45 	if (dstate.getnext)
46 	{
47 		dstate.isend = true;
48 		ptr = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
49 														 PointerGetDatum(dict->dictData),
50 														 PointerGetDatum(VARDATA_ANY(in)),
51 														 Int32GetDatum(VARSIZE_ANY_EXHDR(in)),
52 														 PointerGetDatum(&dstate)));
53 		if (ptr != NULL)
54 			res = ptr;
55 	}
56 
57 	if (!res)
58 		PG_RETURN_NULL();
59 
60 	ptr = res;
61 	while (ptr->lexeme)
62 		ptr++;
63 	da = (Datum *) palloc(sizeof(Datum) * (ptr - res));
64 	ptr = res;
65 	while (ptr->lexeme)
66 	{
67 		da[ptr - res] = CStringGetTextDatum(ptr->lexeme);
68 		ptr++;
69 	}
70 
71 	a = construct_array(da,
72 						ptr - res,
73 						TEXTOID,
74 						-1,
75 						false,
76 						TYPALIGN_INT);
77 
78 	ptr = res;
79 	while (ptr->lexeme)
80 	{
81 		pfree(DatumGetPointer(da[ptr - res]));
82 		pfree(ptr->lexeme);
83 		ptr++;
84 	}
85 	pfree(res);
86 	pfree(da);
87 
88 	PG_RETURN_POINTER(a);
89 }
90