~ubuntu-branches/ubuntu/precise/postgresql-9.1/precise-security

« back to all changes in this revision

Viewing changes to contrib/tsearch2/tsearch2.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * tsearch2.c
 
4
 *              Backwards-compatibility package for old contrib/tsearch2 API
 
5
 *
 
6
 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
 
7
 *
 
8
 *
 
9
 * IDENTIFICATION
 
10
 *        contrib/tsearch2/tsearch2.c
 
11
 *
 
12
 *-------------------------------------------------------------------------
 
13
 */
 
14
#include "postgres.h"
 
15
 
 
16
#include "catalog/namespace.h"
 
17
#include "catalog/pg_type.h"
 
18
#include "commands/trigger.h"
 
19
#include "fmgr.h"
 
20
#include "tsearch/ts_utils.h"
 
21
#include "utils/builtins.h"
 
22
#include "utils/guc.h"
 
23
#include "utils/syscache.h"
 
24
 
 
25
PG_MODULE_MAGIC;
 
26
 
 
27
static Oid      current_dictionary_oid = InvalidOid;
 
28
static Oid      current_parser_oid = InvalidOid;
 
29
 
 
30
/* insert given value at argument position 0 */
 
31
#define INSERT_ARGUMENT0(argument, isnull)                              \
 
32
        do {                                                                                            \
 
33
                int i;                                                                                  \
 
34
                for (i = fcinfo->nargs; i > 0; i--)                             \
 
35
                {                                                                                               \
 
36
                        fcinfo->arg[i] = fcinfo->arg[i-1];                      \
 
37
                        fcinfo->argnull[i] = fcinfo->argnull[i-1];      \
 
38
                }                                                                                               \
 
39
                fcinfo->arg[0] = (argument);                                    \
 
40
                fcinfo->argnull[0] = (isnull);                                  \
 
41
                fcinfo->nargs++;                                                                \
 
42
        } while (0)
 
43
 
 
44
#define TextGetObjectId(infunction, text) \
 
45
        DatumGetObjectId(DirectFunctionCall1(infunction, \
 
46
                                         CStringGetDatum(text_to_cstring(text))))
 
47
 
 
48
#define UNSUPPORTED_FUNCTION(name)                                              \
 
49
        Datum name(PG_FUNCTION_ARGS);                                           \
 
50
        Datum                                                                                           \
 
51
        name(PG_FUNCTION_ARGS)                                                          \
 
52
        {                                                                                                       \
 
53
                ereport(ERROR,                                                                  \
 
54
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),\
 
55
                                 errmsg("function %s is no longer supported", \
 
56
                                                format_procedure(fcinfo->flinfo->fn_oid)), \
 
57
                                 errhint("Switch to new tsearch functionality."))); \
 
58
                /* keep compiler quiet */                                               \
 
59
                PG_RETURN_NULL();                                                               \
 
60
        }                                                                                                       \
 
61
        PG_FUNCTION_INFO_V1(name)
 
62
 
 
63
static Oid      GetCurrentDict(void);
 
64
static Oid      GetCurrentParser(void);
 
65
 
 
66
Datum           tsa_lexize_byname(PG_FUNCTION_ARGS);
 
67
Datum           tsa_lexize_bycurrent(PG_FUNCTION_ARGS);
 
68
Datum           tsa_set_curdict(PG_FUNCTION_ARGS);
 
69
Datum           tsa_set_curdict_byname(PG_FUNCTION_ARGS);
 
70
Datum           tsa_token_type_current(PG_FUNCTION_ARGS);
 
71
Datum           tsa_set_curprs(PG_FUNCTION_ARGS);
 
72
Datum           tsa_set_curprs_byname(PG_FUNCTION_ARGS);
 
73
Datum           tsa_parse_current(PG_FUNCTION_ARGS);
 
74
Datum           tsa_set_curcfg(PG_FUNCTION_ARGS);
 
75
Datum           tsa_set_curcfg_byname(PG_FUNCTION_ARGS);
 
76
Datum           tsa_to_tsvector_name(PG_FUNCTION_ARGS);
 
77
Datum           tsa_to_tsquery_name(PG_FUNCTION_ARGS);
 
78
Datum           tsa_plainto_tsquery_name(PG_FUNCTION_ARGS);
 
79
Datum           tsa_headline_byname(PG_FUNCTION_ARGS);
 
80
Datum           tsa_ts_stat(PG_FUNCTION_ARGS);
 
81
Datum           tsa_tsearch2(PG_FUNCTION_ARGS);
 
82
Datum           tsa_rewrite_accum(PG_FUNCTION_ARGS);
 
83
Datum           tsa_rewrite_finish(PG_FUNCTION_ARGS);
 
84
 
 
85
PG_FUNCTION_INFO_V1(tsa_lexize_byname);
 
86
PG_FUNCTION_INFO_V1(tsa_lexize_bycurrent);
 
87
PG_FUNCTION_INFO_V1(tsa_set_curdict);
 
88
PG_FUNCTION_INFO_V1(tsa_set_curdict_byname);
 
89
PG_FUNCTION_INFO_V1(tsa_token_type_current);
 
90
PG_FUNCTION_INFO_V1(tsa_set_curprs);
 
91
PG_FUNCTION_INFO_V1(tsa_set_curprs_byname);
 
92
PG_FUNCTION_INFO_V1(tsa_parse_current);
 
93
PG_FUNCTION_INFO_V1(tsa_set_curcfg);
 
94
PG_FUNCTION_INFO_V1(tsa_set_curcfg_byname);
 
95
PG_FUNCTION_INFO_V1(tsa_to_tsvector_name);
 
96
PG_FUNCTION_INFO_V1(tsa_to_tsquery_name);
 
97
PG_FUNCTION_INFO_V1(tsa_plainto_tsquery_name);
 
98
PG_FUNCTION_INFO_V1(tsa_headline_byname);
 
99
PG_FUNCTION_INFO_V1(tsa_ts_stat);
 
100
PG_FUNCTION_INFO_V1(tsa_tsearch2);
 
101
PG_FUNCTION_INFO_V1(tsa_rewrite_accum);
 
102
PG_FUNCTION_INFO_V1(tsa_rewrite_finish);
 
103
 
 
104
 
 
105
/*
 
106
 * List of unsupported functions
 
107
 *
 
108
 * The parser and dictionary functions are defined only so that the former
 
109
 * contents of pg_ts_parser and pg_ts_dict can be loaded into the system,
 
110
 * for ease of reference while creating the new tsearch configuration.
 
111
 */
 
112
 
 
113
UNSUPPORTED_FUNCTION(tsa_dex_init);
 
114
UNSUPPORTED_FUNCTION(tsa_dex_lexize);
 
115
 
 
116
UNSUPPORTED_FUNCTION(tsa_snb_en_init);
 
117
UNSUPPORTED_FUNCTION(tsa_snb_lexize);
 
118
UNSUPPORTED_FUNCTION(tsa_snb_ru_init_koi8);
 
119
UNSUPPORTED_FUNCTION(tsa_snb_ru_init_utf8);
 
120
UNSUPPORTED_FUNCTION(tsa_snb_ru_init);
 
121
 
 
122
UNSUPPORTED_FUNCTION(tsa_spell_init);
 
123
UNSUPPORTED_FUNCTION(tsa_spell_lexize);
 
124
 
 
125
UNSUPPORTED_FUNCTION(tsa_syn_init);
 
126
UNSUPPORTED_FUNCTION(tsa_syn_lexize);
 
127
 
 
128
UNSUPPORTED_FUNCTION(tsa_thesaurus_init);
 
129
UNSUPPORTED_FUNCTION(tsa_thesaurus_lexize);
 
130
 
 
131
UNSUPPORTED_FUNCTION(tsa_prsd_start);
 
132
UNSUPPORTED_FUNCTION(tsa_prsd_getlexeme);
 
133
UNSUPPORTED_FUNCTION(tsa_prsd_end);
 
134
UNSUPPORTED_FUNCTION(tsa_prsd_lextype);
 
135
UNSUPPORTED_FUNCTION(tsa_prsd_headline);
 
136
 
 
137
UNSUPPORTED_FUNCTION(tsa_reset_tsearch);
 
138
UNSUPPORTED_FUNCTION(tsa_get_covers);
 
139
 
 
140
 
 
141
/*
 
142
 * list of redefined functions
 
143
 */
 
144
 
 
145
/* lexize(text, text) */
 
146
Datum
 
147
tsa_lexize_byname(PG_FUNCTION_ARGS)
 
148
{
 
149
        text       *dictname = PG_GETARG_TEXT_PP(0);
 
150
        Datum           arg1 = PG_GETARG_DATUM(1);
 
151
 
 
152
        return DirectFunctionCall2(ts_lexize,
 
153
                                ObjectIdGetDatum(TextGetObjectId(regdictionaryin, dictname)),
 
154
                                                           arg1);
 
155
}
 
156
 
 
157
/* lexize(text) */
 
158
Datum
 
159
tsa_lexize_bycurrent(PG_FUNCTION_ARGS)
 
160
{
 
161
        Datum           arg0 = PG_GETARG_DATUM(0);
 
162
        Oid                     id = GetCurrentDict();
 
163
 
 
164
        return DirectFunctionCall2(ts_lexize,
 
165
                                                           ObjectIdGetDatum(id),
 
166
                                                           arg0);
 
167
}
 
168
 
 
169
/* set_curdict(int) */
 
170
Datum
 
171
tsa_set_curdict(PG_FUNCTION_ARGS)
 
172
{
 
173
        Oid                     dict_oid = PG_GETARG_OID(0);
 
174
 
 
175
        if (!SearchSysCacheExists(TSDICTOID,
 
176
                                                          ObjectIdGetDatum(dict_oid),
 
177
                                                          0, 0, 0))
 
178
                elog(ERROR, "cache lookup failed for text search dictionary %u",
 
179
                         dict_oid);
 
180
 
 
181
        current_dictionary_oid = dict_oid;
 
182
 
 
183
        PG_RETURN_VOID();
 
184
}
 
185
 
 
186
/* set_curdict(text) */
 
187
Datum
 
188
tsa_set_curdict_byname(PG_FUNCTION_ARGS)
 
189
{
 
190
        text       *name = PG_GETARG_TEXT_PP(0);
 
191
        Oid                     dict_oid;
 
192
 
 
193
        dict_oid = get_ts_dict_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
194
 
 
195
        current_dictionary_oid = dict_oid;
 
196
 
 
197
        PG_RETURN_VOID();
 
198
}
 
199
 
 
200
/* token_type() */
 
201
Datum
 
202
tsa_token_type_current(PG_FUNCTION_ARGS)
 
203
{
 
204
        INSERT_ARGUMENT0(ObjectIdGetDatum(GetCurrentParser()), false);
 
205
        return ts_token_type_byid(fcinfo);
 
206
}
 
207
 
 
208
/* set_curprs(int) */
 
209
Datum
 
210
tsa_set_curprs(PG_FUNCTION_ARGS)
 
211
{
 
212
        Oid                     parser_oid = PG_GETARG_OID(0);
 
213
 
 
214
        if (!SearchSysCacheExists(TSPARSEROID,
 
215
                                                          ObjectIdGetDatum(parser_oid),
 
216
                                                          0, 0, 0))
 
217
                elog(ERROR, "cache lookup failed for text search parser %u",
 
218
                         parser_oid);
 
219
 
 
220
        current_parser_oid = parser_oid;
 
221
 
 
222
        PG_RETURN_VOID();
 
223
}
 
224
 
 
225
/* set_curprs(text) */
 
226
Datum
 
227
tsa_set_curprs_byname(PG_FUNCTION_ARGS)
 
228
{
 
229
        text       *name = PG_GETARG_TEXT_PP(0);
 
230
        Oid                     parser_oid;
 
231
 
 
232
        parser_oid = get_ts_parser_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
 
233
 
 
234
        current_parser_oid = parser_oid;
 
235
 
 
236
        PG_RETURN_VOID();
 
237
}
 
238
 
 
239
/* parse(text) */
 
240
Datum
 
241
tsa_parse_current(PG_FUNCTION_ARGS)
 
242
{
 
243
        INSERT_ARGUMENT0(ObjectIdGetDatum(GetCurrentParser()), false);
 
244
        return ts_parse_byid(fcinfo);
 
245
}
 
246
 
 
247
/* set_curcfg(int) */
 
248
Datum
 
249
tsa_set_curcfg(PG_FUNCTION_ARGS)
 
250
{
 
251
        Oid                     arg0 = PG_GETARG_OID(0);
 
252
        char       *name;
 
253
 
 
254
        name = DatumGetCString(DirectFunctionCall1(regconfigout,
 
255
                                                                                           ObjectIdGetDatum(arg0)));
 
256
 
 
257
        set_config_option("default_text_search_config", name,
 
258
                                          PGC_USERSET,
 
259
                                          PGC_S_SESSION,
 
260
                                          GUC_ACTION_SET,
 
261
                                          true);
 
262
 
 
263
        PG_RETURN_VOID();
 
264
}
 
265
 
 
266
/* set_curcfg(text) */
 
267
Datum
 
268
tsa_set_curcfg_byname(PG_FUNCTION_ARGS)
 
269
{
 
270
        text       *arg0 = PG_GETARG_TEXT_PP(0);
 
271
        char       *name;
 
272
 
 
273
        name = text_to_cstring(arg0);
 
274
 
 
275
        set_config_option("default_text_search_config", name,
 
276
                                          PGC_USERSET,
 
277
                                          PGC_S_SESSION,
 
278
                                          GUC_ACTION_SET,
 
279
                                          true);
 
280
 
 
281
        PG_RETURN_VOID();
 
282
}
 
283
 
 
284
/* to_tsvector(text, text) */
 
285
Datum
 
286
tsa_to_tsvector_name(PG_FUNCTION_ARGS)
 
287
{
 
288
        text       *cfgname = PG_GETARG_TEXT_PP(0);
 
289
        Datum           arg1 = PG_GETARG_DATUM(1);
 
290
        Oid                     config_oid;
 
291
 
 
292
        config_oid = TextGetObjectId(regconfigin, cfgname);
 
293
 
 
294
        return DirectFunctionCall2(to_tsvector_byid,
 
295
                                                           ObjectIdGetDatum(config_oid), arg1);
 
296
}
 
297
 
 
298
/* to_tsquery(text, text) */
 
299
Datum
 
300
tsa_to_tsquery_name(PG_FUNCTION_ARGS)
 
301
{
 
302
        text       *cfgname = PG_GETARG_TEXT_PP(0);
 
303
        Datum           arg1 = PG_GETARG_DATUM(1);
 
304
        Oid                     config_oid;
 
305
 
 
306
        config_oid = TextGetObjectId(regconfigin, cfgname);
 
307
 
 
308
        return DirectFunctionCall2(to_tsquery_byid,
 
309
                                                           ObjectIdGetDatum(config_oid), arg1);
 
310
}
 
311
 
 
312
 
 
313
/* plainto_tsquery(text, text) */
 
314
Datum
 
315
tsa_plainto_tsquery_name(PG_FUNCTION_ARGS)
 
316
{
 
317
        text       *cfgname = PG_GETARG_TEXT_PP(0);
 
318
        Datum           arg1 = PG_GETARG_DATUM(1);
 
319
        Oid                     config_oid;
 
320
 
 
321
        config_oid = TextGetObjectId(regconfigin, cfgname);
 
322
 
 
323
        return DirectFunctionCall2(plainto_tsquery_byid,
 
324
                                                           ObjectIdGetDatum(config_oid), arg1);
 
325
}
 
326
 
 
327
/* headline(text, text, tsquery [,text]) */
 
328
Datum
 
329
tsa_headline_byname(PG_FUNCTION_ARGS)
 
330
{
 
331
        Datum           arg0 = PG_GETARG_DATUM(0);
 
332
        Datum           arg1 = PG_GETARG_DATUM(1);
 
333
        Datum           arg2 = PG_GETARG_DATUM(2);
 
334
        Datum           result;
 
335
        Oid                     config_oid;
 
336
 
 
337
        /* first parameter has to be converted to oid */
 
338
        config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin,
 
339
                                                                CStringGetDatum(TextDatumGetCString(arg0))));
 
340
 
 
341
        if (PG_NARGS() == 3)
 
342
                result = DirectFunctionCall3(ts_headline_byid,
 
343
                                                                   ObjectIdGetDatum(config_oid), arg1, arg2);
 
344
        else
 
345
        {
 
346
                Datum           arg3 = PG_GETARG_DATUM(3);
 
347
 
 
348
                result = DirectFunctionCall4(ts_headline_byid_opt,
 
349
                                                                         ObjectIdGetDatum(config_oid),
 
350
                                                                         arg1, arg2, arg3);
 
351
        }
 
352
 
 
353
        return result;
 
354
}
 
355
 
 
356
/*
 
357
 * tsearch2 version of update trigger
 
358
 *
 
359
 * We pass this on to the core trigger after inserting the default text
 
360
 * search configuration name as the second argument.  Note that this isn't
 
361
 * a complete implementation of the original functionality; tsearch2 allowed
 
362
 * transformation function names to be included in the list.  However, that
 
363
 * is deliberately removed as being a security risk.
 
364
 */
 
365
Datum
 
366
tsa_tsearch2(PG_FUNCTION_ARGS)
 
367
{
 
368
        TriggerData *trigdata;
 
369
        Trigger    *trigger;
 
370
        char      **tgargs,
 
371
                          **tgargs_old;
 
372
        int                     i;
 
373
        Datum           res;
 
374
 
 
375
        /* Check call context */
 
376
        if (!CALLED_AS_TRIGGER(fcinfo))         /* internal error */
 
377
                elog(ERROR, "tsvector_update_trigger: not fired by trigger manager");
 
378
 
 
379
        trigdata = (TriggerData *) fcinfo->context;
 
380
        trigger = trigdata->tg_trigger;
 
381
 
 
382
        if (trigger->tgnargs < 2)
 
383
                elog(ERROR, "TSearch: format tsearch2(tsvector_field, text_field1,...)");
 
384
 
 
385
        /* create space for configuration name */
 
386
        tgargs = (char **) palloc((trigger->tgnargs + 1) * sizeof(char *));
 
387
        tgargs[0] = trigger->tgargs[0];
 
388
        for (i = 1; i < trigger->tgnargs; i++)
 
389
                tgargs[i + 1] = trigger->tgargs[i];
 
390
 
 
391
        tgargs[1] = pstrdup(GetConfigOptionByName("default_text_search_config",
 
392
                                                                                          NULL));
 
393
        tgargs_old = trigger->tgargs;
 
394
        trigger->tgargs = tgargs;
 
395
        trigger->tgnargs++;
 
396
 
 
397
        res = tsvector_update_trigger_byid(fcinfo);
 
398
 
 
399
        /* restore old trigger data */
 
400
        trigger->tgargs = tgargs_old;
 
401
        trigger->tgnargs--;
 
402
 
 
403
        pfree(tgargs[1]);
 
404
        pfree(tgargs);
 
405
 
 
406
        return res;
 
407
}
 
408
 
 
409
 
 
410
Datum
 
411
tsa_rewrite_accum(PG_FUNCTION_ARGS)
 
412
{
 
413
        TSQuery         acc;
 
414
        ArrayType  *qa;
 
415
        TSQuery         q;
 
416
        QTNode     *qex = NULL,
 
417
                           *subs = NULL,
 
418
                           *acctree = NULL;
 
419
        bool            isfind = false;
 
420
        Datum      *elemsp;
 
421
        int                     nelemsp;
 
422
        MemoryContext aggcontext;
 
423
        MemoryContext oldcontext;
 
424
 
 
425
        if (!AggCheckCallContext(fcinfo, &aggcontext))
 
426
                elog(ERROR, "tsa_rewrite_accum called in non-aggregate context");
 
427
 
 
428
        if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
 
429
        {
 
430
                acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
 
431
                SET_VARSIZE(acc, HDRSIZETQ);
 
432
                acc->size = 0;
 
433
        }
 
434
        else
 
435
                acc = PG_GETARG_TSQUERY(0);
 
436
 
 
437
        if (PG_ARGISNULL(1) || PG_GETARG_POINTER(1) == NULL)
 
438
                PG_RETURN_TSQUERY(acc);
 
439
        else
 
440
                qa = PG_GETARG_ARRAYTYPE_P_COPY(1);
 
441
 
 
442
        if (ARR_NDIM(qa) != 1)
 
443
                elog(ERROR, "array must be one-dimensional, not %d dimensions",
 
444
                         ARR_NDIM(qa));
 
445
        if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
 
446
                elog(ERROR, "array must have three elements");
 
447
        if (ARR_ELEMTYPE(qa) != TSQUERYOID)
 
448
                elog(ERROR, "array must contain tsquery elements");
 
449
 
 
450
        deconstruct_array(qa, TSQUERYOID, -1, false, 'i', &elemsp, NULL, &nelemsp);
 
451
 
 
452
        q = DatumGetTSQuery(elemsp[0]);
 
453
        if (q->size == 0)
 
454
        {
 
455
                pfree(elemsp);
 
456
                PG_RETURN_POINTER(acc);
 
457
        }
 
458
 
 
459
        if (!acc->size)
 
460
        {
 
461
                if (VARSIZE(acc) > HDRSIZETQ)
 
462
                {
 
463
                        pfree(elemsp);
 
464
                        PG_RETURN_POINTER(acc);
 
465
                }
 
466
                else
 
467
                        acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
 
468
        }
 
469
        else
 
470
                acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));
 
471
 
 
472
        QTNTernary(acctree);
 
473
        QTNSort(acctree);
 
474
 
 
475
        q = DatumGetTSQuery(elemsp[1]);
 
476
        if (q->size == 0)
 
477
        {
 
478
                pfree(elemsp);
 
479
                PG_RETURN_POINTER(acc);
 
480
        }
 
481
        qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
 
482
        QTNTernary(qex);
 
483
        QTNSort(qex);
 
484
 
 
485
        q = DatumGetTSQuery(elemsp[2]);
 
486
        if (q->size)
 
487
                subs = QT2QTN(GETQUERY(q), GETOPERAND(q));
 
488
 
 
489
        acctree = findsubquery(acctree, qex, subs, &isfind);
 
490
 
 
491
        if (isfind || !acc->size)
 
492
        {
 
493
                /* pfree( acc ); do not pfree(p), because nodeAgg.c will */
 
494
                if (acctree)
 
495
                {
 
496
                        QTNBinary(acctree);
 
497
                        oldcontext = MemoryContextSwitchTo(aggcontext);
 
498
                        acc = QTN2QT(acctree);
 
499
                        MemoryContextSwitchTo(oldcontext);
 
500
                }
 
501
                else
 
502
                {
 
503
                        acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
 
504
                        SET_VARSIZE(acc, HDRSIZETQ);
 
505
                        acc->size = 0;
 
506
                }
 
507
        }
 
508
 
 
509
        pfree(elemsp);
 
510
        QTNFree(qex);
 
511
        QTNFree(subs);
 
512
        QTNFree(acctree);
 
513
 
 
514
        PG_RETURN_TSQUERY(acc);
 
515
}
 
516
 
 
517
Datum
 
518
tsa_rewrite_finish(PG_FUNCTION_ARGS)
 
519
{
 
520
        TSQuery         acc = PG_GETARG_TSQUERY(0);
 
521
        TSQuery         rewrited;
 
522
 
 
523
        if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0)
 
524
        {
 
525
                rewrited = (TSQuery) palloc(HDRSIZETQ);
 
526
                SET_VARSIZE(rewrited, HDRSIZETQ);
 
527
                rewrited->size = 0;
 
528
        }
 
529
        else
 
530
        {
 
531
                rewrited = (TSQuery) palloc(VARSIZE(acc));
 
532
                memcpy(rewrited, acc, VARSIZE(acc));
 
533
                pfree(acc);
 
534
        }
 
535
 
 
536
        PG_RETURN_POINTER(rewrited);
 
537
}
 
538
 
 
539
 
 
540
/*
 
541
 * Get Oid of current dictionary
 
542
 */
 
543
static Oid
 
544
GetCurrentDict(void)
 
545
{
 
546
        if (current_dictionary_oid == InvalidOid)
 
547
                ereport(ERROR,
 
548
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 
549
                                 errmsg("no current dictionary"),
 
550
                                 errhint("Execute SELECT set_curdict(...).")));
 
551
 
 
552
        return current_dictionary_oid;
 
553
}
 
554
 
 
555
/*
 
556
 * Get Oid of current parser
 
557
 *
 
558
 * Here, it seems reasonable to select the "default" parser if none has been
 
559
 * set.
 
560
 */
 
561
static Oid
 
562
GetCurrentParser(void)
 
563
{
 
564
        if (current_parser_oid == InvalidOid)
 
565
                current_parser_oid = get_ts_parser_oid(stringToQualifiedNameList("pg_catalog.default"), false);
 
566
        return current_parser_oid;
 
567
}