/* since this function recurses, it could be driven to stack overflow. */
check_stack_depth();
/* get the position this call is supposed to update */
mypos = *pos;
/* in all cases, we should increment *pos to advance over this item */
(*pos)++;
if (ptr[mypos].type == VAL || ptr[mypos].type == VALTRUE)
{ /* base case: a VAL has no operand, so just set its left to zero */
ptr[mypos].left = 0;
} elseif (ptr[mypos].val == (int32) '!')
{ /* unary operator, likewise easy: operand is just after it */
ptr[mypos].left = 1; /* recurse to scan operand */ if (!findoprnd(state, ptr, pos)) returnfalse;
} else
{ /* binary operator */
int32 delta;
/* recurse to scan right operand */ if (!findoprnd(state, ptr, pos)) returnfalse; /* we must fill left with offset to left operand's top */ /* delta can't overflow, see LTXTQUERY_TOO_BIG ... */
delta = *pos - mypos; /* ... but it might be too large to fit in the 16-bit left field */
Assert(delta > 0); if (unlikely(delta > PG_INT16_MAX))
ereturn(state->escontext, false,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("ltxtquery is too large")));
ptr[mypos].left = (int16) delta; /* recurse to scan left operand */ if (!findoprnd(state, ptr, pos)) returnfalse;
}
/* parse query & make polish notation (postfix, but in reverse order) */ if (makepol(&state) == ERR) return NULL; if (!state.num)
ereturn(escontext, NULL,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("syntax error"),
errdetail("Empty query.")));
if (LTXTQUERY_TOO_BIG(state.num, state.sumlen))
ereturn(escontext, NULL,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("ltxtquery is too large")));
commonlen = COMPUTESIZE(state.num, state.sumlen);
/* set item in polish notation */ for (i = 0; i < state.num; i++)
{
ptr[i].type = state.str->type;
ptr[i].val = state.str->val;
ptr[i].distance = state.str->distance;
ptr[i].length = state.str->length;
ptr[i].flag = state.str->flag;
tmp = state.str->next;
pfree(state.str);
state.str = tmp;
}
/* set user-friendly operand view */
memcpy(GETOPERAND(query), state.op, state.sumlen);
pfree(state.op);
/* set left operand's position for every operator */
pos = 0; if (!findoprnd(&state, ptr, &pos)) return NULL; /* if successful, findoprnd should have scanned the whole array */
Assert(pos == state.num);
return query;
}
/* *inwithoutmorphology
*/
PG_FUNCTION_INFO_V1(ltxtq_in);
Datum
ltxtq_in(PG_FUNCTION_ARGS)
{
ltxtquery *res;
if ((res = queryin(PG_GETARG_POINTER(0), fcinfo->context)) == NULL)
PG_RETURN_NULL();
PG_RETURN_POINTER(res);
}
/* *ltxtquerytyperecvfunction * *Thetypeissentastextinbinarymode,sothisisalmostthesame *astheinputfunction,butit'sprefixedwithaversionnumbersowe *canchangethebinaryformatsentinfutureifnecessary.Fornow, *onlyversion1issupported.
*/
PG_FUNCTION_INFO_V1(ltxtq_recv);
Datum
ltxtq_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); int version = pq_getmsgint(buf, 1); char *str; int nbytes;
ltxtquery *res;
if (version != 1)
elog(ERROR, "unsupported ltxtquery version number %d", version);
/* *recursivewalkontreeandprintitin *infix(human-readable)view
*/ staticvoid
infix(INFIX *in, bool first)
{ /* since this function recurses, it could be driven to stack overflow. */
check_stack_depth();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.