PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ltxtquery_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "crc32.h"
#include "libpq/pqformat.h"
#include "ltree.h"
#include "miscadmin.h"
#include "nodes/miscnodes.h"
#include "varatt.h"
Include dependency graph for ltxtquery_io.c:

Go to the source code of this file.

Data Structures

struct  NODE
 
struct  QPRS_STATE
 
struct  INFIX
 

Macros

#define WAITOPERAND   1
 
#define INOPERAND   2
 
#define WAITOPERATOR   3
 
#define STACKDEPTH   32
 
#define RESIZEBUF(inf, addsize)
 

Typedefs

typedef struct NODE NODE
 

Functions

static int32 gettoken_query (QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint16 *flag)
 
static bool pushquery (QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval, uint16 flag)
 
static bool pushval_asis (QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 
static int32 makepol (QPRS_STATE *state)
 
static void findoprnd (ITEM *ptr, int32 *pos)
 
static ltxtqueryqueryin (char *buf, struct Node *escontext)
 
 PG_FUNCTION_INFO_V1 (ltxtq_in)
 
Datum ltxtq_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ltxtq_recv)
 
Datum ltxtq_recv (PG_FUNCTION_ARGS)
 
static void infix (INFIX *in, bool first)
 
 PG_FUNCTION_INFO_V1 (ltxtq_out)
 
Datum ltxtq_out (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (ltxtq_send)
 
Datum ltxtq_send (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ INOPERAND

#define INOPERAND   2

Definition at line 20 of file ltxtquery_io.c.

◆ RESIZEBUF

#define RESIZEBUF (   inf,
  addsize 
)
Value:
while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) \
{ \
int32 len = (inf)->cur - (inf)->buf; \
(inf)->buflen *= 2; \
(inf)->buf = (char*) repalloc( (void*)(inf)->buf, (inf)->buflen ); \
(inf)->cur = (inf)->buf + len; \
}
struct cursor * cur
Definition: ecpg.c:29
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
const void size_t len
static char * buf
Definition: pg_test_fsync.c:72

Definition at line 458 of file ltxtquery_io.c.

◆ STACKDEPTH

#define STACKDEPTH   32

Definition at line 209 of file ltxtquery_io.c.

◆ WAITOPERAND

#define WAITOPERAND   1

Definition at line 19 of file ltxtquery_io.c.

◆ WAITOPERATOR

#define WAITOPERATOR   3

Definition at line 21 of file ltxtquery_io.c.

Typedef Documentation

◆ NODE

typedef struct NODE NODE

Function Documentation

◆ findoprnd()

static void findoprnd ( ITEM ptr,
int32 pos 
)
static

Definition at line 298 of file ltxtquery_io.c.

299{
300 /* since this function recurses, it could be driven to stack overflow. */
302
303 if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
304 {
305 ptr[*pos].left = 0;
306 (*pos)++;
307 }
308 else if (ptr[*pos].val == (int32) '!')
309 {
310 ptr[*pos].left = 1;
311 (*pos)++;
312 findoprnd(ptr, pos);
313 }
314 else
315 {
316 ITEM *curitem = &ptr[*pos];
317 int32 tmp = *pos;
318
319 (*pos)++;
320 findoprnd(ptr, pos);
321 curitem->left = *pos - tmp;
322 findoprnd(ptr, pos);
323 }
324}
#define VAL
Definition: _int.h:162
int32_t int32
Definition: c.h:481
long val
Definition: informix.c:689
#define VALTRUE
Definition: ltree.h:175
static void findoprnd(ITEM *ptr, int32 *pos)
Definition: ltxtquery_io.c:298
void check_stack_depth(void)
Definition: stack_depth.c:95
Definition: _int.h:141
int16 left
Definition: _int.h:143
const char * type

References check_stack_depth(), findoprnd(), ITEM::left, type, VAL, val, and VALTRUE.

Referenced by findoprnd(), and queryin().

◆ gettoken_query()

static int32 gettoken_query ( QPRS_STATE state,
int32 val,
int32 lenval,
char **  strval,
uint16 flag 
)
static

Definition at line 61 of file ltxtquery_io.c.

62{
63 int charlen;
64
65 for (;;)
66 {
67 charlen = pg_mblen(state->buf);
68
69 switch (state->state)
70 {
71 case WAITOPERAND:
72 if (t_iseq(state->buf, '!'))
73 {
74 (state->buf)++;
75 *val = (int32) '!';
76 return OPR;
77 }
78 else if (t_iseq(state->buf, '('))
79 {
80 state->count++;
81 (state->buf)++;
82 return OPEN;
83 }
84 else if (ISLABEL(state->buf))
85 {
86 state->state = INOPERAND;
87 *strval = state->buf;
88 *lenval = charlen;
89 *flag = 0;
90 }
91 else if (!isspace((unsigned char) *state->buf))
92 ereturn(state->escontext, ERR,
93 (errcode(ERRCODE_SYNTAX_ERROR),
94 errmsg("operand syntax error")));
95 break;
96 case INOPERAND:
97 if (ISLABEL(state->buf))
98 {
99 if (*flag)
100 ereturn(state->escontext, ERR,
101 (errcode(ERRCODE_SYNTAX_ERROR),
102 errmsg("modifiers syntax error")));
103 *lenval += charlen;
104 }
105 else if (t_iseq(state->buf, '%'))
107 else if (t_iseq(state->buf, '@'))
108 *flag |= LVAR_INCASE;
109 else if (t_iseq(state->buf, '*'))
110 *flag |= LVAR_ANYEND;
111 else
112 {
113 state->state = WAITOPERATOR;
114 return VAL;
115 }
116 break;
117 case WAITOPERATOR:
118 if (t_iseq(state->buf, '&') || t_iseq(state->buf, '|'))
119 {
120 state->state = WAITOPERAND;
121 *val = (int32) *(state->buf);
122 (state->buf)++;
123 return OPR;
124 }
125 else if (t_iseq(state->buf, ')'))
126 {
127 (state->buf)++;
128 state->count--;
129 return (state->count < 0) ? ERR : CLOSE;
130 }
131 else if (*(state->buf) == '\0')
132 {
133 return (state->count) ? ERR : END;
134 }
135 else if (!t_iseq(state->buf, ' '))
136 {
137 return ERR;
138 }
139 break;
140 default:
141 return ERR;
142 break;
143 }
144
145 state->buf += charlen;
146 }
147
148 /* should not get here */
149}
#define CLOSE
Definition: _int.h:165
#define OPEN
Definition: _int.h:164
#define END
Definition: _int.h:160
#define OPR
Definition: _int.h:163
#define ERR
Definition: _int.h:161
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define LVAR_INCASE
Definition: ltree.h:75
#define LVAR_ANYEND
Definition: ltree.h:74
#define ISLABEL(x)
Definition: ltree.h:130
#define LVAR_SUBLEXEME
Definition: ltree.h:76
#define WAITOPERAND
Definition: ltxtquery_io.c:19
#define WAITOPERATOR
Definition: ltxtquery_io.c:21
#define INOPERAND
Definition: ltxtquery_io.c:20
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
Definition: regguts.h:323
char * flag(int b)
Definition: test-ctype.c:33
#define t_iseq(x, c)
Definition: ts_locale.h:38

References CLOSE, END, ereturn, ERR, errcode(), errmsg(), flag(), INOPERAND, ISLABEL, LVAR_ANYEND, LVAR_INCASE, LVAR_SUBLEXEME, OPEN, OPR, pg_mblen(), t_iseq, VAL, val, WAITOPERAND, and WAITOPERATOR.

Referenced by makepol().

◆ infix()

static void infix ( INFIX in,
bool  first 
)
static

Definition at line 472 of file ltxtquery_io.c.

473{
474 /* since this function recurses, it could be driven to stack overflow. */
476
477 if (in->curpol->type == VAL)
478 {
479 char *op = in->op + in->curpol->distance;
480
481 RESIZEBUF(in, in->curpol->length * 2 + 5);
482 while (*op)
483 {
484 *(in->cur) = *op;
485 op++;
486 in->cur++;
487 }
488 if (in->curpol->flag & LVAR_SUBLEXEME)
489 {
490 *(in->cur) = '%';
491 in->cur++;
492 }
493 if (in->curpol->flag & LVAR_INCASE)
494 {
495 *(in->cur) = '@';
496 in->cur++;
497 }
498 if (in->curpol->flag & LVAR_ANYEND)
499 {
500 *(in->cur) = '*';
501 in->cur++;
502 }
503 *(in->cur) = '\0';
504 in->curpol++;
505 }
506 else if (in->curpol->val == (int32) '!')
507 {
508 bool isopr = false;
509
510 RESIZEBUF(in, 1);
511 *(in->cur) = '!';
512 in->cur++;
513 *(in->cur) = '\0';
514 in->curpol++;
515 if (in->curpol->type == OPR)
516 {
517 isopr = true;
518 RESIZEBUF(in, 2);
519 sprintf(in->cur, "( ");
520 in->cur = strchr(in->cur, '\0');
521 }
522 infix(in, isopr);
523 if (isopr)
524 {
525 RESIZEBUF(in, 2);
526 sprintf(in->cur, " )");
527 in->cur = strchr(in->cur, '\0');
528 }
529 }
530 else
531 {
532 int32 op = in->curpol->val;
533 INFIX nrm;
534
535 in->curpol++;
536 if (op == (int32) '|' && !first)
537 {
538 RESIZEBUF(in, 2);
539 sprintf(in->cur, "( ");
540 in->cur = strchr(in->cur, '\0');
541 }
542
543 nrm.curpol = in->curpol;
544 nrm.op = in->op;
545 nrm.buflen = 16;
546 nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
547
548 /* get right operand */
549 infix(&nrm, false);
550
551 /* get & print left operand */
552 in->curpol = nrm.curpol;
553 infix(in, false);
554
555 /* print operator & right operand */
556 RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
557 sprintf(in->cur, " %c %s", op, nrm.buf);
558 in->cur = strchr(in->cur, '\0');
559 pfree(nrm.buf);
560
561 if (op == (int32) '|' && !first)
562 {
563 RESIZEBUF(in, 2);
564 sprintf(in->cur, " )");
565 in->cur = strchr(in->cur, '\0');
566 }
567 }
568}
#define RESIZEBUF(inf, addsize)
Definition: ltxtquery_io.c:458
static void infix(INFIX *in, bool first)
Definition: ltxtquery_io.c:472
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
#define sprintf
Definition: port.h:240
char * buf
Definition: _int_bool.c:552
char * cur
Definition: _int_bool.c:553
int32 buflen
Definition: _int_bool.c:554
ITEM * curpol
Definition: _int_bool.c:551
char * op
Definition: ltxtquery_io.c:454
uint16 distance
Definition: ltree.h:146
uint8 flag
Definition: ltree.h:143
int32 val
Definition: _int.h:144
int16 type
Definition: _int.h:142
uint8 length
Definition: ltree.h:145

References INFIX::buf, INFIX::buflen, check_stack_depth(), INFIX::cur, INFIX::curpol, ITEM::distance, ITEM::flag, infix(), ITEM::length, LVAR_ANYEND, LVAR_INCASE, LVAR_SUBLEXEME, INFIX::op, OPR, palloc(), pfree(), RESIZEBUF, sprintf, ITEM::type, ITEM::val, and VAL.

Referenced by infix(), ltxtq_out(), and ltxtq_send().

◆ ltxtq_in()

Datum ltxtq_in ( PG_FUNCTION_ARGS  )

Definition at line 409 of file ltxtquery_io.c.

410{
411 ltxtquery *res;
412
413 if ((res = queryin((char *) PG_GETARG_POINTER(0), fcinfo->context)) == NULL)
416}
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static ltxtquery * queryin(char *buf, struct Node *escontext)
Definition: ltxtquery_io.c:331

References PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_POINTER, queryin(), and res.

◆ ltxtq_out()

Datum ltxtq_out ( PG_FUNCTION_ARGS  )

Definition at line 572 of file ltxtquery_io.c.

573{
575 INFIX nrm;
576
577 if (query->size == 0)
579 (errcode(ERRCODE_SYNTAX_ERROR),
580 errmsg("syntax error"),
581 errdetail("Empty query.")));
582
583 nrm.curpol = GETQUERY(query);
584 nrm.buflen = 32;
585 nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
586 *(nrm.cur) = '\0';
587 nrm.op = GETOPERAND(query);
588 infix(&nrm, true);
589
591}
#define GETQUERY(x)
Definition: _int.h:157
int errdetail(const char *fmt,...)
Definition: elog.c:1203
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_GETARG_LTXTQUERY_P(n)
Definition: ltree.h:228
#define GETOPERAND(x)
Definition: ltree.h:165
int32 size
Definition: ltree.h:156

References INFIX::buf, INFIX::buflen, INFIX::cur, INFIX::curpol, ereport, errcode(), errdetail(), errmsg(), ERROR, GETOPERAND, GETQUERY, infix(), INFIX::op, palloc(), PG_GETARG_LTXTQUERY_P, PG_RETURN_POINTER, and ltxtquery::size.

◆ ltxtq_recv()

Datum ltxtq_recv ( PG_FUNCTION_ARGS  )

Definition at line 428 of file ltxtquery_io.c.

429{
431 int version = pq_getmsgint(buf, 1);
432 char *str;
433 int nbytes;
434 ltxtquery *res;
435
436 if (version != 1)
437 elog(ERROR, "unsupported ltxtquery version number %d", version);
438
439 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
440 res = queryin(str, NULL);
441 pfree(str);
442
444}
#define elog(elevel,...)
Definition: elog.h:225
const char * str
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
StringInfoData * StringInfo
Definition: stringinfo.h:54

References buf, elog, ERROR, pfree(), PG_GETARG_POINTER, PG_RETURN_POINTER, pq_getmsgint(), pq_getmsgtext(), queryin(), res, and str.

◆ ltxtq_send()

Datum ltxtq_send ( PG_FUNCTION_ARGS  )

Definition at line 603 of file ltxtquery_io.c.

604{
607 int version = 1;
608 INFIX nrm;
609
610 if (query->size == 0)
612 (errcode(ERRCODE_SYNTAX_ERROR),
613 errmsg("syntax error"),
614 errdetail("Empty query.")));
615
616 nrm.curpol = GETQUERY(query);
617 nrm.buflen = 32;
618 nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
619 *(nrm.cur) = '\0';
620 nrm.op = GETOPERAND(query);
621 infix(&nrm, true);
622
624 pq_sendint8(&buf, version);
625 pq_sendtext(&buf, nrm.buf, strlen(nrm.buf));
626 pfree(nrm.buf);
627
629}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint8(StringInfo buf, uint8 i)
Definition: pqformat.h:128

References INFIX::buf, buf, INFIX::buflen, INFIX::cur, INFIX::curpol, ereport, errcode(), errdetail(), errmsg(), ERROR, GETOPERAND, GETQUERY, infix(), INFIX::op, palloc(), pfree(), PG_GETARG_LTXTQUERY_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint8(), pq_sendtext(), and ltxtquery::size.

◆ makepol()

static int32 makepol ( QPRS_STATE state)
static

Definition at line 214 of file ltxtquery_io.c.

215{
216 int32 val = 0,
217 type;
218 int32 lenval = 0;
219 char *strval = NULL;
220 int32 stack[STACKDEPTH];
221 int32 lenstack = 0;
222 uint16 flag = 0;
223
224 /* since this function recurses, it could be driven to stack overflow */
226
227 while ((type = gettoken_query(state, &val, &lenval, &strval, &flag)) != END)
228 {
229 switch (type)
230 {
231 case VAL:
232 if (!pushval_asis(state, VAL, strval, lenval, flag))
233 return ERR;
234 while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
235 stack[lenstack - 1] == (int32) '!'))
236 {
237 lenstack--;
238 if (!pushquery(state, OPR, stack[lenstack], 0, 0, 0))
239 return ERR;
240 }
241 break;
242 case OPR:
243 if (lenstack && val == (int32) '|')
244 {
245 if (!pushquery(state, OPR, val, 0, 0, 0))
246 return ERR;
247 }
248 else
249 {
250 if (lenstack == STACKDEPTH)
251 /* internal error */
252 elog(ERROR, "stack too short");
253 stack[lenstack] = val;
254 lenstack++;
255 }
256 break;
257 case OPEN:
258 if (makepol(state) == ERR)
259 return ERR;
260 while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
261 stack[lenstack - 1] == (int32) '!'))
262 {
263 lenstack--;
264 if (!pushquery(state, OPR, stack[lenstack], 0, 0, 0))
265 return ERR;
266 }
267 break;
268 case CLOSE:
269 while (lenstack)
270 {
271 lenstack--;
272 if (!pushquery(state, OPR, stack[lenstack], 0, 0, 0))
273 return ERR;
274 };
275 return END;
276 break;
277 case ERR:
278 if (SOFT_ERROR_OCCURRED(state->escontext))
279 return ERR;
280 /* fall through */
281 default:
282 ereturn(state->escontext, ERR,
283 (errcode(ERRCODE_SYNTAX_ERROR),
284 errmsg("syntax error")));
285
286 }
287 }
288 while (lenstack)
289 {
290 lenstack--;
291 if (!pushquery(state, OPR, stack[lenstack], 0, 0, 0))
292 return ERR;
293 };
294 return END;
295}
uint16_t uint16
Definition: c.h:484
static int32 gettoken_query(QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint16 *flag)
Definition: ltxtquery_io.c:61
static bool pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval, uint16 flag)
Definition: ltxtquery_io.c:155
static int32 makepol(QPRS_STATE *state)
Definition: ltxtquery_io.c:214
static bool pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
Definition: ltxtquery_io.c:182
#define STACKDEPTH
Definition: ltxtquery_io.c:209
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:53

References check_stack_depth(), CLOSE, elog, END, ereturn, ERR, errcode(), errmsg(), ERROR, flag(), gettoken_query(), makepol(), OPEN, OPR, pushquery(), pushval_asis(), SOFT_ERROR_OCCURRED, STACKDEPTH, type, VAL, and val.

Referenced by makepol(), and queryin().

◆ PG_FUNCTION_INFO_V1() [1/4]

PG_FUNCTION_INFO_V1 ( ltxtq_in  )

◆ PG_FUNCTION_INFO_V1() [2/4]

PG_FUNCTION_INFO_V1 ( ltxtq_out  )

◆ PG_FUNCTION_INFO_V1() [3/4]

PG_FUNCTION_INFO_V1 ( ltxtq_recv  )

◆ PG_FUNCTION_INFO_V1() [4/4]

PG_FUNCTION_INFO_V1 ( ltxtq_send  )

◆ pushquery()

static bool pushquery ( QPRS_STATE state,
int32  type,
int32  val,
int32  distance,
int32  lenval,
uint16  flag 
)
static

Definition at line 155 of file ltxtquery_io.c.

156{
157 NODE *tmp = (NODE *) palloc(sizeof(NODE));
158
159 tmp->type = type;
160 tmp->val = val;
161 tmp->flag = flag;
162 if (distance > 0xffff)
163 ereturn(state->escontext, false,
164 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
165 errmsg("value is too big")));
166 if (lenval > 0xff)
167 ereturn(state->escontext, false,
168 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
169 errmsg("operand is too long")));
170 tmp->distance = distance;
171 tmp->length = lenval;
172 tmp->next = state->str;
173 state->str = tmp;
174 state->num++;
175 return true;
176}
Definition: _int_bool.c:26
struct NODE * next
Definition: _int_bool.c:29
int32 val
Definition: _int_bool.c:28
int16 distance
Definition: ltxtquery_io.c:31
uint16 flag
Definition: ltxtquery_io.c:33
int16 length
Definition: ltxtquery_io.c:32
int32 type
Definition: _int_bool.c:27

References NODE::distance, ereturn, errcode(), errmsg(), NODE::flag, flag(), NODE::length, NODE::next, palloc(), NODE::type, type, NODE::val, and val.

Referenced by makepol(), and pushval_asis().

◆ pushval_asis()

static bool pushval_asis ( QPRS_STATE state,
int  type,
char *  strval,
int  lenval,
uint16  flag 
)
static

Definition at line 182 of file ltxtquery_io.c.

183{
184 if (lenval > 0xffff)
185 ereturn(state->escontext, false,
186 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
187 errmsg("word is too long")));
188
189 if (!pushquery(state, type, ltree_crc32_sz(strval, lenval),
190 state->curop - state->op, lenval, flag))
191 return false;
192
193 while (state->curop - state->op + lenval + 1 >= state->lenop)
194 {
195 int32 tmp = state->curop - state->op;
196
197 state->lenop *= 2;
198 state->op = (char *) repalloc(state->op, state->lenop);
199 state->curop = state->op + tmp;
200 }
201 memcpy(state->curop, strval, lenval);
202 state->curop += lenval;
203 *(state->curop) = '\0';
204 state->curop++;
205 state->sumlen += lenval + 1;
206 return true;
207}
unsigned int ltree_crc32_sz(const char *buf, int size)
Definition: crc32.c:24

References ereturn, errcode(), errmsg(), flag(), ltree_crc32_sz(), pushquery(), repalloc(), and type.

Referenced by makepol().

◆ queryin()

static ltxtquery * queryin ( char *  buf,
struct Node escontext 
)
static

Definition at line 331 of file ltxtquery_io.c.

332{
334 int32 i;
335 ltxtquery *query;
336 int32 commonlen;
337 ITEM *ptr;
338 NODE *tmp;
339 int32 pos = 0;
340
341#ifdef BS_DEBUG
342 char pbuf[16384],
343 *cur;
344#endif
345
346 /* init state */
347 state.buf = buf;
348 state.state = WAITOPERAND;
349 state.count = 0;
350 state.num = 0;
351 state.str = NULL;
352 state.escontext = escontext;
353
354 /* init list of operand */
355 state.sumlen = 0;
356 state.lenop = 64;
357 state.curop = state.op = (char *) palloc(state.lenop);
358 *(state.curop) = '\0';
359
360 /* parse query & make polish notation (postfix, but in reverse order) */
361 if (makepol(&state) == ERR)
362 return NULL;
363 if (!state.num)
364 ereturn(escontext, NULL,
365 (errcode(ERRCODE_SYNTAX_ERROR),
366 errmsg("syntax error"),
367 errdetail("Empty query.")));
368
369 if (LTXTQUERY_TOO_BIG(state.num, state.sumlen))
370 ereturn(escontext, NULL,
371 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
372 errmsg("ltxtquery is too large")));
373 commonlen = COMPUTESIZE(state.num, state.sumlen);
374
375 query = (ltxtquery *) palloc0(commonlen);
376 SET_VARSIZE(query, commonlen);
377 query->size = state.num;
378 ptr = GETQUERY(query);
379
380 /* set item in polish notation */
381 for (i = 0; i < state.num; i++)
382 {
383 ptr[i].type = state.str->type;
384 ptr[i].val = state.str->val;
385 ptr[i].distance = state.str->distance;
386 ptr[i].length = state.str->length;
387 ptr[i].flag = state.str->flag;
388 tmp = state.str->next;
389 pfree(state.str);
390 state.str = tmp;
391 }
392
393 /* set user-friendly operand view */
394 memcpy(GETOPERAND(query), state.op, state.sumlen);
395 pfree(state.op);
396
397 /* set left operand's position for every operator */
398 pos = 0;
399 findoprnd(ptr, &pos);
400
401 return query;
402}
#define COMPUTESIZE(size)
Definition: _int.h:155
int i
Definition: isn.c:72
#define LTXTQUERY_TOO_BIG(size, lenofoperand)
Definition: ltree.h:162
void * palloc0(Size size)
Definition: mcxt.c:1347
char flag
Definition: regguts.h:326
struct state * next
Definition: regguts.h:332
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References buf, COMPUTESIZE, cur, ITEM::distance, ereturn, ERR, errcode(), errdetail(), errmsg(), findoprnd(), ITEM::flag, state::flag, GETOPERAND, GETQUERY, i, ITEM::length, LTXTQUERY_TOO_BIG, makepol(), state::next, palloc(), palloc0(), pfree(), SET_VARSIZE, ltxtquery::size, ITEM::type, ITEM::val, and WAITOPERAND.

Referenced by ltxtq_in(), and ltxtq_recv().