/* * Evaluate tsquery boolean expression using ternary logic. * * chkcond is a callback function used to evaluate each VAL node in the query. * checkval can be used to pass information to the callback. TS_execute doesn't * do anything with it. */ static GinTernaryValue TS_execute_ternary(QueryItem *curitem, void *checkval, GinTernaryValue (*chkcond) (void *checkval, QueryOperand *val)) { GinTernaryValue val1, val2, result; /* since this function recurses, it could be driven to stack overflow */ check_stack_depth(); if (curitem->type == QI_VAL) return chkcond(checkval, (QueryOperand *) curitem); switch (curitem->qoperator.oper) { case OP_NOT: result = TS_execute_ternary(curitem + 1, checkval, chkcond); if (result == GIN_MAYBE) return result; return !result; case OP_AND: val1 = TS_execute_ternary(curitem + curitem->qoperator.left, checkval, chkcond); if (val1 == GIN_FALSE) return GIN_FALSE; val2 = TS_execute_ternary(curitem + 1, checkval, chkcond); if (val2 == GIN_FALSE) return GIN_FALSE; if (val1 == GIN_TRUE && val2 == GIN_TRUE) return GIN_TRUE; else return GIN_MAYBE; case OP_OR: val1 = TS_execute_ternary(curitem + curitem->qoperator.left, checkval, chkcond); if (val1 == GIN_TRUE) return GIN_TRUE; val2 = TS_execute_ternary(curitem + 1, checkval, chkcond); if (val2 == GIN_TRUE) return GIN_TRUE; if (val1 == GIN_FALSE && val2 == GIN_FALSE) return GIN_FALSE; else return GIN_MAYBE; default: elog(ERROR, "unrecognized operator___: %d", curitem->qoperator.oper); } /* not reachable, but keep compiler quiet */ return false; }
/* * Evaluate tsquery boolean expression. * * chkcond is a callback function used to evaluate each VAL node in the query. * checkval can be used to pass information to the callback. TS_execute doesn't * do anything with it. * if calcnot is false, NOT expressions are always evaluated to be true. This * is used in ranking. */ bool TS_execute(QueryItem *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, QueryOperand *val)) { /* since this function recurses, it could be driven to stack overflow */ check_stack_depth(); if (curitem->type == QI_VAL) return chkcond(checkval, (QueryOperand *) curitem); switch (curitem->qoperator.oper) { case OP_NOT: if (calcnot) return !TS_execute(curitem + 1, checkval, calcnot, chkcond); else return true; case OP_AND: if (TS_execute(curitem + curitem->qoperator.left, checkval, calcnot, chkcond)) return TS_execute(curitem + 1, checkval, calcnot, chkcond); else return false; case OP_OR: if (TS_execute(curitem + curitem->qoperator.left, checkval, calcnot, chkcond)) return true; else return TS_execute(curitem + 1, checkval, calcnot, chkcond); default: elog(ERROR, "unrecognized operator: %d", curitem->qoperator.oper); } /* not reachable, but keep compiler quiet */ return false; }