PostgreSQL Source Code  git master
ltxtquery_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "crc32.h"
#include "ltree.h"
#include "miscadmin.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

 PG_FUNCTION_INFO_V1 (ltxtq_in)
 
 PG_FUNCTION_INFO_V1 (ltxtq_out)
 
static int32 gettoken_query (QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint16 *flag)
 
static void pushquery (QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval, uint16 flag)
 
static void 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)
 
Datum ltxtq_in (PG_FUNCTION_ARGS)
 
static void infix (INFIX *in, bool first)
 
Datum ltxtq_out (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ INOPERAND

#define INOPERAND   2

Definition at line 20 of file ltxtquery_io.c.

Referenced by gettoken_query().

◆ 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
static char * buf
Definition: pg_test_fsync.c:67
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069

Definition at line 402 of file ltxtquery_io.c.

Referenced by infix().

◆ STACKDEPTH

#define STACKDEPTH   32

Definition at line 197 of file ltxtquery_io.c.

Referenced by makepol().

◆ WAITOPERAND

#define WAITOPERAND   1

Definition at line 19 of file ltxtquery_io.c.

Referenced by gettoken_query(), and queryin().

◆ WAITOPERATOR

#define WAITOPERATOR   3

Definition at line 21 of file ltxtquery_io.c.

Referenced by gettoken_query().

Typedef Documentation

◆ NODE

typedef struct NODE NODE

Function Documentation

◆ findoprnd()

static void findoprnd ( ITEM ptr,
int32 pos 
)
static

Definition at line 277 of file ltxtquery_io.c.

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

Referenced by queryin().

278 {
279  /* since this function recurses, it could be driven to stack overflow. */
281 
282  if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE)
283  {
284  ptr[*pos].left = 0;
285  (*pos)++;
286  }
287  else if (ptr[*pos].val == (int32) '!')
288  {
289  ptr[*pos].left = 1;
290  (*pos)++;
291  findoprnd(ptr, pos);
292  }
293  else
294  {
295  ITEM *curitem = &ptr[*pos];
296  int32 tmp = *pos;
297 
298  (*pos)++;
299  findoprnd(ptr, pos);
300  curitem->left = *pos - tmp;
301  findoprnd(ptr, pos);
302  }
303 }
Definition: _int.h:119
signed int int32
Definition: c.h:347
#define VALTRUE
Definition: ltree.h:128
void check_stack_depth(void)
Definition: postgres.c:3288
int16 left
Definition: _int.h:122
#define VAL
Definition: _int.h:141
static void findoprnd(ITEM *ptr, int32 *pos)
Definition: ltxtquery_io.c:277
long val
Definition: informix.c:664

◆ gettoken_query()

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

Definition at line 58 of file ltxtquery_io.c.

References QPRS_STATE::buf, CLOSE, QPRS_STATE::count, END, ereport, ERR, errcode(), errmsg(), ERROR, INOPERAND, ISALNUM, LVAR_ANYEND, LVAR_INCASE, LVAR_SUBLEXEME, OPEN, OPR, pg_mblen(), QPRS_STATE::state, t_iseq, t_isspace(), VAL, WAITOPERAND, and WAITOPERATOR.

Referenced by makepol().

59 {
60  int charlen;
61 
62  for (;;)
63  {
64  charlen = pg_mblen(state->buf);
65 
66  switch (state->state)
67  {
68  case WAITOPERAND:
69  if (charlen == 1 && t_iseq(state->buf, '!'))
70  {
71  (state->buf)++;
72  *val = (int32) '!';
73  return OPR;
74  }
75  else if (charlen == 1 && t_iseq(state->buf, '('))
76  {
77  state->count++;
78  (state->buf)++;
79  return OPEN;
80  }
81  else if (ISALNUM(state->buf))
82  {
83  state->state = INOPERAND;
84  *strval = state->buf;
85  *lenval = charlen;
86  *flag = 0;
87  }
88  else if (!t_isspace(state->buf))
89  ereport(ERROR,
90  (errcode(ERRCODE_SYNTAX_ERROR),
91  errmsg("operand syntax error")));
92  break;
93  case INOPERAND:
94  if (ISALNUM(state->buf))
95  {
96  if (*flag)
97  ereport(ERROR,
98  (errcode(ERRCODE_SYNTAX_ERROR),
99  errmsg("modifiers syntax error")));
100  *lenval += charlen;
101  }
102  else if (charlen == 1 && t_iseq(state->buf, '%'))
103  *flag |= LVAR_SUBLEXEME;
104  else if (charlen == 1 && t_iseq(state->buf, '@'))
105  *flag |= LVAR_INCASE;
106  else if (charlen == 1 && t_iseq(state->buf, '*'))
107  *flag |= LVAR_ANYEND;
108  else
109  {
110  state->state = WAITOPERATOR;
111  return VAL;
112  }
113  break;
114  case WAITOPERATOR:
115  if (charlen == 1 && (t_iseq(state->buf, '&') || t_iseq(state->buf, '|')))
116  {
117  state->state = WAITOPERAND;
118  *val = (int32) *(state->buf);
119  (state->buf)++;
120  return OPR;
121  }
122  else if (charlen == 1 && t_iseq(state->buf, ')'))
123  {
124  (state->buf)++;
125  state->count--;
126  return (state->count < 0) ? ERR : CLOSE;
127  }
128  else if (*(state->buf) == '\0')
129  return (state->count) ? ERR : END;
130  else if (charlen == 1 && !t_iseq(state->buf, ' '))
131  return ERR;
132  break;
133  default:
134  return ERR;
135  break;
136  }
137 
138  state->buf += charlen;
139  }
140 }
#define LVAR_INCASE
Definition: ltree.h:44
#define WAITOPERAND
Definition: ltxtquery_io.c:19
#define ERR
Definition: _int.h:140
#define ISALNUM(x)
Definition: ltree.h:83
#define LVAR_ANYEND
Definition: ltree.h:43
int32 count
Definition: ltxtquery_io.c:41
char * buf
Definition: ltxtquery_io.c:39
int errcode(int sqlerrcode)
Definition: elog.c:608
signed int int32
Definition: c.h:347
int32 state
Definition: ltxtquery_io.c:40
#define END
Definition: _int.h:139
#define CLOSE
Definition: _int.h:144
#define ERROR
Definition: elog.h:43
int t_isspace(const char *ptr)
Definition: ts_locale.c:52
#define WAITOPERATOR
Definition: ltxtquery_io.c:21
#define t_iseq(x, c)
Definition: ts_locale.h:45
char * flag(int b)
Definition: test-ctype.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
#define OPEN
Definition: _int.h:143
#define VAL
Definition: _int.h:141
#define OPR
Definition: _int.h:142
#define LVAR_SUBLEXEME
Definition: ltree.h:45
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
#define INOPERAND
Definition: ltxtquery_io.c:20
int errmsg(const char *fmt,...)
Definition: elog.c:822
long val
Definition: informix.c:664

◆ infix()

static void infix ( INFIX in,
bool  first 
)
static

Definition at line 416 of file ltxtquery_io.c.

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().

417 {
418  /* since this function recurses, it could be driven to stack overflow. */
420 
421  if (in->curpol->type == VAL)
422  {
423  char *op = in->op + in->curpol->distance;
424 
425  RESIZEBUF(in, in->curpol->length * 2 + 5);
426  while (*op)
427  {
428  *(in->cur) = *op;
429  op++;
430  in->cur++;
431  }
432  if (in->curpol->flag & LVAR_SUBLEXEME)
433  {
434  *(in->cur) = '%';
435  in->cur++;
436  }
437  if (in->curpol->flag & LVAR_INCASE)
438  {
439  *(in->cur) = '@';
440  in->cur++;
441  }
442  if (in->curpol->flag & LVAR_ANYEND)
443  {
444  *(in->cur) = '*';
445  in->cur++;
446  }
447  *(in->cur) = '\0';
448  in->curpol++;
449  }
450  else if (in->curpol->val == (int32) '!')
451  {
452  bool isopr = false;
453 
454  RESIZEBUF(in, 1);
455  *(in->cur) = '!';
456  in->cur++;
457  *(in->cur) = '\0';
458  in->curpol++;
459  if (in->curpol->type == OPR)
460  {
461  isopr = true;
462  RESIZEBUF(in, 2);
463  sprintf(in->cur, "( ");
464  in->cur = strchr(in->cur, '\0');
465  }
466  infix(in, isopr);
467  if (isopr)
468  {
469  RESIZEBUF(in, 2);
470  sprintf(in->cur, " )");
471  in->cur = strchr(in->cur, '\0');
472  }
473  }
474  else
475  {
476  int32 op = in->curpol->val;
477  INFIX nrm;
478 
479  in->curpol++;
480  if (op == (int32) '|' && !first)
481  {
482  RESIZEBUF(in, 2);
483  sprintf(in->cur, "( ");
484  in->cur = strchr(in->cur, '\0');
485  }
486 
487  nrm.curpol = in->curpol;
488  nrm.op = in->op;
489  nrm.buflen = 16;
490  nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
491 
492  /* get right operand */
493  infix(&nrm, false);
494 
495  /* get & print left operand */
496  in->curpol = nrm.curpol;
497  infix(in, false);
498 
499  /* print operator & right operand */
500  RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
501  sprintf(in->cur, " %c %s", op, nrm.buf);
502  in->cur = strchr(in->cur, '\0');
503  pfree(nrm.buf);
504 
505  if (op == (int32) '|' && !first)
506  {
507  RESIZEBUF(in, 2);
508  sprintf(in->cur, " )");
509  in->cur = strchr(in->cur, '\0');
510  }
511  }
512 }
#define LVAR_INCASE
Definition: ltree.h:44
ITEM * curpol
Definition: _int_bool.c:550
#define LVAR_ANYEND
Definition: ltree.h:43
uint8 length
Definition: ltree.h:98
char * op
Definition: ltxtquery_io.c:398
uint8 flag
Definition: ltree.h:96
signed int int32
Definition: c.h:347
int16 type
Definition: _int.h:121
#define sprintf
Definition: port.h:194
void pfree(void *pointer)
Definition: mcxt.c:1056
void check_stack_depth(void)
Definition: postgres.c:3288
int32 val
Definition: _int.h:123
#define VAL
Definition: _int.h:141
#define OPR
Definition: _int.h:142
#define LVAR_SUBLEXEME
Definition: ltree.h:45
static void infix(INFIX *in, bool first)
Definition: ltxtquery_io.c:416
char * cur
Definition: _int_bool.c:552
void * palloc(Size size)
Definition: mcxt.c:949
int32 buflen
Definition: _int_bool.c:553
#define RESIZEBUF(inf, addsize)
Definition: ltxtquery_io.c:402
uint16 distance
Definition: ltree.h:99
char * buf
Definition: _int_bool.c:551

◆ ltxtq_in()

Datum ltxtq_in ( PG_FUNCTION_ARGS  )

Definition at line 385 of file ltxtquery_io.c.

References buf, cur, PG_GETARG_POINTER, PG_RETURN_POINTER, and queryin().

386 {
388 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
static ltxtquery * queryin(char *buf)
Definition: ltxtquery_io.c:310

◆ ltxtq_out()

Datum ltxtq_out ( PG_FUNCTION_ARGS  )

Definition at line 515 of file ltxtquery_io.c.

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

516 {
517  ltxtquery *query = PG_GETARG_LTXTQUERY_P(0);
518  INFIX nrm;
519 
520  if (query->size == 0)
521  ereport(ERROR,
522  (errcode(ERRCODE_SYNTAX_ERROR),
523  errmsg("syntax error"),
524  errdetail("Empty query.")));
525 
526  nrm.curpol = GETQUERY(query);
527  nrm.buflen = 32;
528  nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
529  *(nrm.cur) = '\0';
530  nrm.op = GETOPERAND(query);
531  infix(&nrm, true);
532 
533  PG_FREE_IF_COPY(query, 0);
534  PG_RETURN_POINTER(nrm.buf);
535 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
int32 size
Definition: ltree.h:109
ITEM * curpol
Definition: _int_bool.c:550
char * op
Definition: ltxtquery_io.c:398
int errcode(int sqlerrcode)
Definition: elog.c:608
#define GETQUERY(x)
Definition: _int.h:136
#define GETOPERAND(x)
Definition: ltree.h:118
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:955
#define ereport(elevel, rest)
Definition: elog.h:141
static void infix(INFIX *in, bool first)
Definition: ltxtquery_io.c:416
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define PG_GETARG_LTXTQUERY_P(n)
Definition: ltree.h:181
char * cur
Definition: _int_bool.c:552
void * palloc(Size size)
Definition: mcxt.c:949
int32 buflen
Definition: _int_bool.c:553
int errmsg(const char *fmt,...)
Definition: elog.c:822
char * buf
Definition: _int_bool.c:551

◆ makepol()

static int32 makepol ( QPRS_STATE state)
static

Definition at line 202 of file ltxtquery_io.c.

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

Referenced by queryin().

203 {
204  int32 val = 0,
205  type;
206  int32 lenval = 0;
207  char *strval = NULL;
208  int32 stack[STACKDEPTH];
209  int32 lenstack = 0;
210  uint16 flag = 0;
211 
212  /* since this function recurses, it could be driven to stack overflow */
214 
215  while ((type = gettoken_query(state, &val, &lenval, &strval, &flag)) != END)
216  {
217  switch (type)
218  {
219  case VAL:
220  pushval_asis(state, VAL, strval, lenval, flag);
221  while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
222  stack[lenstack - 1] == (int32) '!'))
223  {
224  lenstack--;
225  pushquery(state, OPR, stack[lenstack], 0, 0, 0);
226  }
227  break;
228  case OPR:
229  if (lenstack && val == (int32) '|')
230  pushquery(state, OPR, val, 0, 0, 0);
231  else
232  {
233  if (lenstack == STACKDEPTH)
234  /* internal error */
235  elog(ERROR, "stack too short");
236  stack[lenstack] = val;
237  lenstack++;
238  }
239  break;
240  case OPEN:
241  if (makepol(state) == ERR)
242  return ERR;
243  while (lenstack && (stack[lenstack - 1] == (int32) '&' ||
244  stack[lenstack - 1] == (int32) '!'))
245  {
246  lenstack--;
247  pushquery(state, OPR, stack[lenstack], 0, 0, 0);
248  }
249  break;
250  case CLOSE:
251  while (lenstack)
252  {
253  lenstack--;
254  pushquery(state, OPR, stack[lenstack], 0, 0, 0);
255  };
256  return END;
257  break;
258  case ERR:
259  default:
260  ereport(ERROR,
261  (errcode(ERRCODE_SYNTAX_ERROR),
262  errmsg("syntax error")));
263 
264  return ERR;
265 
266  }
267  }
268  while (lenstack)
269  {
270  lenstack--;
271  pushquery(state, OPR, stack[lenstack], 0, 0, 0);
272  };
273  return END;
274 }
static int32 makepol(QPRS_STATE *state)
Definition: ltxtquery_io.c:202
#define ERR
Definition: _int.h:140
static void pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
Definition: ltxtquery_io.c:172
int errcode(int sqlerrcode)
Definition: elog.c:608
static int32 gettoken_query(QPRS_STATE *state, int32 *val, int32 *lenval, char **strval, uint16 *flag)
Definition: ltxtquery_io.c:58
signed int int32
Definition: c.h:347
unsigned short uint16
Definition: c.h:358
#define END
Definition: _int.h:139
#define CLOSE
Definition: _int.h:144
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3288
char * flag(int b)
Definition: test-ctype.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
#define OPEN
Definition: _int.h:143
static void pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval, uint16 flag)
Definition: ltxtquery_io.c:146
#define VAL
Definition: _int.h:141
#define OPR
Definition: _int.h:142
#define STACKDEPTH
Definition: ltxtquery_io.c:197
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
long val
Definition: informix.c:664

◆ PG_FUNCTION_INFO_V1() [1/2]

PG_FUNCTION_INFO_V1 ( ltxtq_in  )

◆ PG_FUNCTION_INFO_V1() [2/2]

PG_FUNCTION_INFO_V1 ( ltxtq_out  )

◆ pushquery()

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

Definition at line 146 of file ltxtquery_io.c.

References NODE::distance, ereport, errcode(), errmsg(), ERROR, NODE::flag, NODE::length, NODE::next, QPRS_STATE::num, palloc(), QPRS_STATE::str, NODE::type, and NODE::val.

Referenced by makepol(), and pushval_asis().

147 {
148  NODE *tmp = (NODE *) palloc(sizeof(NODE));
149 
150  tmp->type = type;
151  tmp->val = val;
152  tmp->flag = flag;
153  if (distance > 0xffff)
154  ereport(ERROR,
155  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
156  errmsg("value is too big")));
157  if (lenval > 0xff)
158  ereport(ERROR,
159  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
160  errmsg("operand is too long")));
161  tmp->distance = distance;
162  tmp->length = lenval;
163  tmp->next = state->str;
164  state->str = tmp;
165  state->num++;
166 }
Definition: _int_bool.c:26
int32 val
Definition: _int_bool.c:29
int errcode(int sqlerrcode)
Definition: elog.c:608
struct NODE * next
Definition: _int_bool.c:30
NODE * str
Definition: ltxtquery_io.c:43
#define ERROR
Definition: elog.h:43
uint16 flag
Definition: ltxtquery_io.c:33
char * flag(int b)
Definition: test-ctype.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
int16 length
Definition: ltxtquery_io.c:32
int16 distance
Definition: ltxtquery_io.c:31
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
long val
Definition: informix.c:664
int32 type
Definition: _int_bool.c:28

◆ pushval_asis()

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

Definition at line 172 of file ltxtquery_io.c.

References QPRS_STATE::curop, ereport, errcode(), errmsg(), ERROR, QPRS_STATE::lenop, ltree_crc32_sz(), QPRS_STATE::op, pushquery(), repalloc(), and QPRS_STATE::sumlen.

Referenced by makepol().

173 {
174  if (lenval > 0xffff)
175  ereport(ERROR,
176  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
177  errmsg("word is too long")));
178 
179  pushquery(state, type, ltree_crc32_sz(strval, lenval),
180  state->curop - state->op, lenval, flag);
181 
182  while (state->curop - state->op + lenval + 1 >= state->lenop)
183  {
184  int32 tmp = state->curop - state->op;
185 
186  state->lenop *= 2;
187  state->op = (char *) repalloc((void *) state->op, state->lenop);
188  state->curop = state->op + tmp;
189  }
190  memcpy((void *) state->curop, (void *) strval, lenval);
191  state->curop += lenval;
192  *(state->curop) = '\0';
193  state->curop++;
194  state->sumlen += lenval + 1;
195 }
char * op
Definition: ltxtquery_io.c:50
char * curop
Definition: ltxtquery_io.c:51
int errcode(int sqlerrcode)
Definition: elog.c:608
unsigned int ltree_crc32_sz(char *buf, int size)
Definition: crc32.c:23
int32 sumlen
Definition: ltxtquery_io.c:49
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
char * flag(int b)
Definition: test-ctype.c:33
#define ereport(elevel, rest)
Definition: elog.h:141
static void pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval, uint16 flag)
Definition: ltxtquery_io.c:146
int32 lenop
Definition: ltxtquery_io.c:48
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ queryin()

static ltxtquery* queryin ( char *  buf)
static

Definition at line 310 of file ltxtquery_io.c.

References QPRS_STATE::buf, buf, COMPUTESIZE, QPRS_STATE::count, cur, QPRS_STATE::curop, NODE::distance, ITEM::distance, ereport, errcode(), errdetail(), errmsg(), ERROR, findoprnd(), NODE::flag, ITEM::flag, GETOPERAND, GETQUERY, i, NODE::length, ITEM::length, QPRS_STATE::lenop, LTXTQUERY_TOO_BIG, makepol(), NODE::next, QPRS_STATE::num, QPRS_STATE::op, palloc(), palloc0(), pfree(), SET_VARSIZE, ltxtquery::size, QPRS_STATE::state, QPRS_STATE::str, QPRS_STATE::sumlen, NODE::type, ITEM::type, NODE::val, ITEM::val, and WAITOPERAND.

Referenced by ltxtq_in().

311 {
313  int32 i;
314  ltxtquery *query;
315  int32 commonlen;
316  ITEM *ptr;
317  NODE *tmp;
318  int32 pos = 0;
319 
320 #ifdef BS_DEBUG
321  char pbuf[16384],
322  *cur;
323 #endif
324 
325  /* init state */
326  state.buf = buf;
327  state.state = WAITOPERAND;
328  state.count = 0;
329  state.num = 0;
330  state.str = NULL;
331 
332  /* init list of operand */
333  state.sumlen = 0;
334  state.lenop = 64;
335  state.curop = state.op = (char *) palloc(state.lenop);
336  *(state.curop) = '\0';
337 
338  /* parse query & make polish notation (postfix, but in reverse order) */
339  makepol(&state);
340  if (!state.num)
341  ereport(ERROR,
342  (errcode(ERRCODE_SYNTAX_ERROR),
343  errmsg("syntax error"),
344  errdetail("Empty query.")));
345 
346  if (LTXTQUERY_TOO_BIG(state.num, state.sumlen))
347  ereport(ERROR,
348  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
349  errmsg("ltxtquery is too large")));
350  commonlen = COMPUTESIZE(state.num, state.sumlen);
351 
352  query = (ltxtquery *) palloc0(commonlen);
353  SET_VARSIZE(query, commonlen);
354  query->size = state.num;
355  ptr = GETQUERY(query);
356 
357  /* set item in polish notation */
358  for (i = 0; i < state.num; i++)
359  {
360  ptr[i].type = state.str->type;
361  ptr[i].val = state.str->val;
362  ptr[i].distance = state.str->distance;
363  ptr[i].length = state.str->length;
364  ptr[i].flag = state.str->flag;
365  tmp = state.str->next;
366  pfree(state.str);
367  state.str = tmp;
368  }
369 
370  /* set user-friendly operand view */
371  memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
372  pfree(state.op);
373 
374  /* set left operand's position for every operator */
375  pos = 0;
376  findoprnd(ptr, &pos);
377 
378  return query;
379 }
Definition: _int.h:119
#define WAITOPERAND
Definition: ltxtquery_io.c:19
static int32 makepol(QPRS_STATE *state)
Definition: ltxtquery_io.c:202
Definition: _int_bool.c:26
#define LTXTQUERY_TOO_BIG(size, lenofoperand)
Definition: ltree.h:115
int32 size
Definition: ltree.h:109
int32 val
Definition: _int_bool.c:29
int32 count
Definition: ltxtquery_io.c:41
char * op
Definition: ltxtquery_io.c:50
uint8 length
Definition: ltree.h:98
char * curop
Definition: ltxtquery_io.c:51
struct cursor * cur
Definition: ecpg.c:28
char * buf
Definition: ltxtquery_io.c:39
int errcode(int sqlerrcode)
Definition: elog.c:608
uint8 flag
Definition: ltree.h:96
#define GETQUERY(x)
Definition: _int.h:136
int32 sumlen
Definition: ltxtquery_io.c:49
struct NODE * next
Definition: _int_bool.c:30
NODE * str
Definition: ltxtquery_io.c:43
signed int int32
Definition: c.h:347
#define GETOPERAND(x)
Definition: ltree.h:118
int16 type
Definition: _int.h:121
int32 state
Definition: ltxtquery_io.c:40
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
uint16 flag
Definition: ltxtquery_io.c:33
static char * buf
Definition: pg_test_fsync.c:67
int errdetail(const char *fmt,...)
Definition: elog.c:955
int32 val
Definition: _int.h:123
#define ereport(elevel, rest)
Definition: elog.h:141
void * palloc0(Size size)
Definition: mcxt.c:980
#define COMPUTESIZE(size)
Definition: _int.h:134
int32 lenop
Definition: ltxtquery_io.c:48
int16 length
Definition: ltxtquery_io.c:32
Definition: regguts.h:298
int16 distance
Definition: ltxtquery_io.c:31
static void findoprnd(ITEM *ptr, int32 *pos)
Definition: ltxtquery_io.c:277
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
uint16 distance
Definition: ltree.h:99
int32 type
Definition: _int_bool.c:28