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; }
/* * Remove QI_VALSTOP (stopword) nodes from TSQuery. */ TSQuery cleanup_tsquery_stopwords(TSQuery in) { int32 len, lenstr, commonlen, i; NODE *root; int ladd, radd; TSQuery out; QueryItem *items; char *operands; if (in->size == 0) return in; /* eliminate stop words */ root = clean_stopword_intree(maketree(GETQUERY(in)), &ladd, &radd); if (root == NULL) { ereport(NOTICE, (errmsg("text-search query contains only stop words or doesn't contain lexemes, ignored"))); out = palloc(HDRSIZETQ); out->size = 0; SET_VARSIZE(out, HDRSIZETQ); return out; } /* * Build TSQuery from plain view */ lenstr = calcstrlen(root); items = plaintree(root, &len); commonlen = COMPUTESIZE(len, lenstr); out = palloc(commonlen); SET_VARSIZE(out, commonlen); out->size = len; memcpy(GETQUERY(out), items, len * sizeof(QueryItem)); items = GETQUERY(out); operands = GETOPERAND(out); for (i = 0; i < out->size; i++) { QueryOperand *op = (QueryOperand *) &items[i]; if (op->type != QI_VAL) continue; memcpy(operands, GETOPERAND(in) + op->distance, op->length); operands[op->length] = '\0'; op->distance = operands - GETOPERAND(out); operands += op->length + 1; } return out; }
Datum to_tsquery_byid(PG_FUNCTION_ARGS) { Oid cfgid = PG_GETARG_OID(0); text *in = PG_GETARG_TEXT_P(1); TSQuery query; QueryItem *res; int4 len; query = parse_tsquery(text_to_cstring(in), pushval_morph, ObjectIdGetDatum(cfgid), false); if (query->size == 0) PG_RETURN_TSQUERY(query); /* clean out any stopword placeholders from the tree */ res = clean_fakeval(GETQUERY(query), &len); if (!res) { SET_VARSIZE(query, HDRSIZETQ); query->size = 0; PG_RETURN_POINTER(query); } memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem)); /* * Removing the stopword placeholders might've resulted in fewer * QueryItems. If so, move the operands up accordingly. */ if (len != query->size) { char *oldoperand = GETOPERAND(query); int4 lenoperand = VARSIZE(query) - (oldoperand - (char *) query); Assert(len < query->size); query->size = len; memmove((void *) GETOPERAND(query), oldoperand, VARSIZE(query) - (oldoperand - (char *) query)); SET_VARSIZE(query, COMPUTESIZE(len, lenoperand)); } pfree(res); PG_RETURN_TSQUERY(query); }
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; }
Datum plainto_tsquery_byid(PG_FUNCTION_ARGS) { Oid cfgid = PG_GETARG_OID(0); text *in = PG_GETARG_TEXT_P(1); TSQuery query; QueryItem *res; int4 len; query = parse_tsquery(text_to_cstring(in), pushval_morph, ObjectIdGetDatum(cfgid), true); if (query->size == 0) PG_RETURN_TSQUERY(query); res = clean_fakeval(GETQUERY(query), &len); if (!res) { SET_VARSIZE(query, HDRSIZETQ); query->size = 0; PG_RETURN_POINTER(query); } memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem)); if (len != query->size) { char *oldoperand = GETOPERAND(query); int4 lenoperand = VARSIZE(query) - (oldoperand - (char *) query); Assert(len < query->size); query->size = len; memcpy((void *) GETOPERAND(query), oldoperand, lenoperand); SET_VARSIZE(query, COMPUTESIZE(len, lenoperand)); } pfree(res); PG_RETURN_POINTER(query); }
/* * input */ Datum bqarr_in(PG_FUNCTION_ARGS) { char *buf = (char *) PG_GETARG_POINTER(0); WORKSTATE state; int4 i; QUERYTYPE *query; int4 commonlen; ITEM *ptr; NODE *tmp; int4 pos = 0; #ifdef BS_DEBUG StringInfoData pbuf; #endif state.buf = buf; state.state = WAITOPERAND; state.count = 0; state.num = 0; state.str = NULL; /* make polish notation (postfix, but in reverse order) */ makepol(&state); if (!state.num) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("empty query"))); commonlen = COMPUTESIZE(state.num); query = (QUERYTYPE *) palloc(commonlen); SET_VARSIZE(query, commonlen); query->size = state.num; ptr = GETQUERY(query); for (i = state.num - 1; i >= 0; i--) { ptr[i].type = state.str->type; ptr[i].val = state.str->val; tmp = state.str->next; pfree(state.str); state.str = tmp; } pos = query->size - 1; findoprnd(ptr, &pos); #ifdef BS_DEBUG initStringInfo(&pbuf); for (i = 0; i < query->size; i++) { if (ptr[i].type == OPR) appendStringInfo(&pbuf, "%c(%d) ", ptr[i].val, ptr[i].left); else appendStringInfo(&pbuf, "%d ", ptr[i].val); } elog(DEBUG3, "POR: %s", pbuf.data); pfree(pbuf.data); #endif PG_RETURN_POINTER(query); }
/* * input */ static QUERYTYPE * queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int, int2), int cfg_id) { QPRS_STATE state; int4 i; QUERYTYPE *query; int4 commonlen; ITEM *ptr; NODE *tmp; int4 pos = 0; #ifdef BS_DEBUG char pbuf[16384], *cur; #endif /* init state */ state.buf = buf; state.state = WAITOPERAND; state.count = 0; state.num = 0; state.str = NULL; state.cfg_id = cfg_id; /* init value parser's state */ state.valstate.oprisdelim = true; state.valstate.len = 32; state.valstate.word = (char *) palloc(state.valstate.len); /* init list of operand */ state.sumlen = 0; state.lenop = 64; state.curop = state.op = (char *) palloc(state.lenop); *(state.curop) = '\0'; /* parse query & make polish notation (postfix, but in reverse order) */ makepol(&state, pushval); pfree(state.valstate.word); if (!state.num) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("empty query"))); /* make finish struct */ commonlen = COMPUTESIZE(state.num, state.sumlen); query = (QUERYTYPE *) palloc(commonlen); query->len = commonlen; query->size = state.num; ptr = GETQUERY(query); /* set item in polish notation */ for (i = 0; i < state.num; i++) { ptr[i].weight = state.str->weight; ptr[i].type = state.str->type; ptr[i].val = state.str->val; ptr[i].distance = state.str->distance; ptr[i].length = state.str->length; tmp = state.str->next; pfree(state.str); state.str = tmp; } /* set user friendly-operand view */ memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen); pfree(state.op); /* set left operand's position for every operator */ pos = 0; findoprnd(ptr, &pos); #ifdef BS_DEBUG cur = pbuf; *cur = '\0'; for (i = 0; i < query->size; i++) { if (ptr[i].type == OPR) sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); else sprintf(cur, "%d(%s) ", ptr[i].val, GETOPERAND(query) + ptr[i].distance); cur = strchr(cur, '\0'); } elog(DEBUG3, "POR: %s", pbuf); #endif return query; }
/* * input */ static ltxtquery * queryin(char *buf) { QPRS_STATE state; int4 i; ltxtquery *query; int4 commonlen; ITEM *ptr; NODE *tmp; int4 pos = 0; #ifdef BS_DEBUG char pbuf[16384], *cur; #endif /* init state */ state.buf = buf; state.state = WAITOPERAND; state.count = 0; state.num = 0; state.str = NULL; /* init list of operand */ state.sumlen = 0; state.lenop = 64; state.curop = state.op = (char *) palloc(state.lenop); *(state.curop) = '\0'; /* parse query & make polish notation (postfix, but in reverse order) */ makepol(&state); if (!state.num) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"), errdetail("Empty query."))); /* make finish struct */ commonlen = COMPUTESIZE(state.num, state.sumlen); query = (ltxtquery *) palloc(commonlen); SET_VARSIZE(query, commonlen); query->size = state.num; ptr = GETQUERY(query); /* 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((void *) GETOPERAND(query), (void *) state.op, state.sumlen); pfree(state.op); /* set left operand's position for every operator */ pos = 0; findoprnd(ptr, &pos); return query; }