/* * This function is used for morph parsing */ static void pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 weight) { int4 count = 0; PRSTEXT prs; prs.lenwords = 32; prs.curwords = 0; prs.pos = 0; prs.words = (TSWORD *) palloc(sizeof(TSWORD) * prs.lenwords); parsetext_v2(findcfg(state->cfg_id), &prs, strval, lenval); for (count = 0; count < prs.curwords; count++) { pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight); pfree(prs.words[count].word); if (count) pushquery(state, OPR, (int4) '&', 0, 0, 0); } pfree(prs.words); /* XXX */ if (prs.curwords == 0) pushval_asis(state, VALSTOP, NULL, 0, 0); }
/* * This function is used for tsquery parsing */ static void pushval_asis(QPRS_STATE * state, int type, char *strval, int lenval, int2 weight) { if (lenval >= MAXSTRLEN) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("word is too long"))); pushquery(state, type, crc32_sz((uint8 *) strval, lenval), state->curop - state->op, lenval, weight); while (state->curop - state->op + lenval + 1 >= state->lenop) { int4 tmp = state->curop - state->op; state->lenop *= 2; state->op = (char *) repalloc((void *) state->op, state->lenop); state->curop = state->op + tmp; } memcpy((void *) state->curop, (void *) strval, lenval); state->curop += lenval; *(state->curop) = '\0'; state->curop++; state->sumlen += lenval + 1; return; }
/* * This function is used for query_txt parsing */ static void pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag) { if (lenval > 0xffff) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("word is too long"))); pushquery(state, type, ltree_crc32_sz(strval, lenval), state->curop - state->op, lenval, flag); while (state->curop - state->op + lenval + 1 >= state->lenop) { int4 tmp = state->curop - state->op; state->lenop *= 2; state->op = (char *) repalloc((void *) state->op, state->lenop); state->curop = state->op + tmp; } memcpy((void *) state->curop, (void *) strval, lenval); state->curop += lenval; *(state->curop) = '\0'; state->curop++; state->sumlen += lenval + 1; return; }
/* * make polish notation of query */ static int4 makepol(WORKSTATE *state) { int4 val, type; int4 stack[STACKDEPTH]; int4 lenstack = 0; while ((type = gettoken(state, &val)) != END) { switch (type) { case VAL: pushquery(state, type, val); while (lenstack && (stack[lenstack - 1] == (int4) '&' || stack[lenstack - 1] == (int4) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack]); } break; case OPR: if (lenstack && val == (int4) '|') pushquery(state, OPR, val); else { if (lenstack == STACKDEPTH) ereport(ERROR, (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), errmsg("statement too complex"))); stack[lenstack] = val; lenstack++; } break; case OPEN: if (makepol(state) == ERR) return ERR; if (lenstack && (stack[lenstack - 1] == (int4) '&' || stack[lenstack - 1] == (int4) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack]); } break; case CLOSE: while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack]); }; return END; break; case ERR: default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); return ERR; } } while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack]); }; return END; }
/* * make polish notaion of query */ static int4 makepol(QPRS_STATE * state, void (*pushval) (QPRS_STATE *, int, char *, int, int2)) { int4 val, type; int4 lenval; char *strval; int4 stack[STACKDEPTH]; int4 lenstack = 0; int2 weight; while ((type = gettoken_query(state, &val, &lenval, &strval, &weight)) != END) { switch (type) { case VAL: (*pushval) (state, VAL, strval, lenval, weight); while (lenstack && (stack[lenstack - 1] == (int4) '&' || stack[lenstack - 1] == (int4) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); } break; case OPR: if (lenstack && val == (int4) '|') pushquery(state, OPR, val, 0, 0, 0); else { if (lenstack == STACKDEPTH) /* internal error */ elog(ERROR, "stack too short"); stack[lenstack] = val; lenstack++; } break; case OPEN: if (makepol(state, pushval) == ERR) return ERR; if (lenstack && (stack[lenstack - 1] == (int4) '&' || stack[lenstack - 1] == (int4) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); } break; case CLOSE: while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); }; return END; break; case ERR: default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); return ERR; } } while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); }; return END; }
/* * make polish notation of query */ static int32 makepol(WORKSTATE *state) { int32 val, type; int32 stack[STACKDEPTH]; int32 lenstack = 0; /* since this function recurses, it could be driven to stack overflow */ check_stack_depth(); while ((type = gettoken(state, &val)) != END) { switch (type) { case VAL: pushquery(state, type, val); while (lenstack && (stack[lenstack - 1] == (int32) '&' || stack[lenstack - 1] == (int32) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack]); } break; case OPR: if (lenstack && val == (int32) '|') pushquery(state, OPR, val); else { if (lenstack == STACKDEPTH) ereport(ERROR, (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), errmsg("statement too complex"))); stack[lenstack] = val; lenstack++; } break; case OPEN: if (makepol(state) == ERR) return ERR; while (lenstack && (stack[lenstack - 1] == (int32) '&' || stack[lenstack - 1] == (int32) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack]); } break; case CLOSE: while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack]); }; return END; break; case ERR: default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); return ERR; } } while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack]); }; return END; }
/* * make polish notaion of query */ static int32 makepol(QPRS_STATE *state) { int32 val = 0, type; int32 lenval = 0; char *strval = NULL; int32 stack[STACKDEPTH]; int32 lenstack = 0; uint16 flag = 0; /* since this function recurses, it could be driven to stack overflow */ check_stack_depth(); while ((type = gettoken_query(state, &val, &lenval, &strval, &flag)) != END) { switch (type) { case VAL: pushval_asis(state, VAL, strval, lenval, flag); while (lenstack && (stack[lenstack - 1] == (int32) '&' || stack[lenstack - 1] == (int32) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); } break; case OPR: if (lenstack && val == (int32) '|') pushquery(state, OPR, val, 0, 0, 0); else { if (lenstack == STACKDEPTH) /* internal error */ elog(ERROR, "stack too short"); stack[lenstack] = val; lenstack++; } break; case OPEN: if (makepol(state) == ERR) return ERR; while (lenstack && (stack[lenstack - 1] == (int32) '&' || stack[lenstack - 1] == (int32) '!')) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); } break; case CLOSE: while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); }; return END; break; case ERR: default: ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("syntax error"))); return ERR; } } while (lenstack) { lenstack--; pushquery(state, OPR, stack[lenstack], 0, 0, 0); }; return END; }