PostgreSQL Source Code  git master
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:28
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
const void size_t len
static char * buf
Definition: pg_test_fsync.c:73

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
signed int int32
Definition: c.h:494
long val
Definition: informix.c:670
#define VALTRUE
Definition: ltree.h:175
static void findoprnd(ITEM *ptr, int32 *pos)
Definition: ltxtquery_io.c:298
void check_stack_depth(void)
Definition: postgres.c:3531
Definition: _int.h:141
int16 left
Definition: _int.h:143
const char * type

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

Referenced by 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 (!t_isspace(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, '%'))
106  *flag |= LVAR_SUBLEXEME;
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:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#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
int t_isspace(const char *ptr)
Definition: ts_locale.c:50
#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, t_isspace(), 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:1520
void * palloc(Size size)
Definition: mcxt.c:1316
#define sprintf
Definition: port.h:240
char * buf
Definition: _int_bool.c:553
char * cur
Definition: _int_bool.c:554
int32 buflen
Definition: _int_bool.c:555
ITEM * curpol
Definition: _int_bool.c:552
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, ITEM::length, LVAR_ANYEND, LVAR_INCASE, LVAR_SUBLEXEME, INFIX::op, OPR, palloc(), pfree(), RESIZEBUF, sprintf, ITEM::type, ITEM::val, and VAL.

Referenced by 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)
414  PG_RETURN_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 {
574  ltxtquery *query = PG_GETARG_LTXTQUERY_P(0);
575  INFIX nrm;
576 
577  if (query->size == 0)
578  ereport(ERROR,
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 
590  PG_RETURN_POINTER(nrm.buf);
591 }
#define GETQUERY(x)
Definition: _int.h:157
int errdetail(const char *fmt,...)
Definition: elog.c:1205
#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:224
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 {
605  ltxtquery *query = PG_GETARG_LTXTQUERY_P(0);
607  int version = 1;
608  INFIX nrm;
609 
610  if (query->size == 0)
611  ereport(ERROR,
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 }
unsigned short uint16
Definition: c.h:505
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:52

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

Referenced by 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:27
struct NODE * next
Definition: _int_bool.c:30
int32 val
Definition: _int_bool.c:29
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:28

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:73
#define LTXTQUERY_TOO_BIG(size, lenofoperand)
Definition: ltree.h:162
void * palloc0(Size size)
Definition: mcxt.c:1346
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().