TSQuery QTN2QT(QTNode *in) { TSQuery out; int len; int sumlen = 0, nnode = 0; QTN2QTState state; cntsize(in, &sumlen, &nnode); if (TSQUERY_TOO_BIG(nnode, sumlen)) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("tsquery is too large"))); len = COMPUTESIZE(nnode, sumlen); out = (TSQuery) palloc0(len); SET_VARSIZE(out, len); out->size = nnode; state.curitem = GETQUERY(out); state.operand = state.curoperand = GETOPERAND(out); fillQT(&state, in); return out; }
static void fillQT(QTN2QTState *state, QTNode *in) { /* since this function recurses, it could be driven to stack overflow. */ check_stack_depth(); if (in->valnode->type == QI_VAL) { memcpy(state->curitem, in->valnode, sizeof(QueryOperand)); memcpy(state->curoperand, in->word, in->valnode->qoperand.length); state->curitem->qoperand.distance = state->curoperand - state->operand; state->curoperand[in->valnode->qoperand.length] = '\0'; state->curoperand += in->valnode->qoperand.length + 1; state->curitem++; } else { QueryItem *curitem = state->curitem; Assert(in->valnode->type == QI_OPR); memcpy(state->curitem, in->valnode, sizeof(QueryOperator)); Assert(in->nchild <= 2); state->curitem++; fillQT(state, in->child[0]); if (in->nchild == 2) { curitem->qoperator.left = state->curitem - curitem; fillQT(state, in->child[1]); } } }
TSQuery QTN2QT(QTNode *in) { TSQuery out; int len; int sumlen = 0, nnode = 0; QTN2QTState state; cntsize(in, &sumlen, &nnode); len = COMPUTESIZE(nnode, sumlen); out = (TSQuery) palloc0(len); SET_VARSIZE(out, len); out->size = nnode; state.curitem = GETQUERY(out); state.operand = state.curoperand = GETOPERAND(out); fillQT(&state, in); return out; }