/* * check for boolean condition */ bool TS_execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM * val)) { if (curitem->type == VAL) return (*chkcond) (checkval, curitem); else if (curitem->val == (int4) '!') { return (calcnot) ? ((TS_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true) : true; } else if (curitem->val == (int4) '&') { if (TS_execute(curitem + curitem->left, checkval, calcnot, chkcond)) return TS_execute(curitem + 1, checkval, calcnot, chkcond); else return false; } else { /* |-operator */ if (TS_execute(curitem + curitem->left, checkval, calcnot, chkcond)) return true; else return TS_execute(curitem + 1, checkval, calcnot, chkcond); } return false; }
Datum ts_match_vq(PG_FUNCTION_ARGS) { TSVector val = PG_GETARG_TSVECTOR(0); TSQuery query = PG_GETARG_TSQUERY(1); CHKVAL chkval; bool result; if (!val->size || !query->size) { PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(false); } chkval.arrb = ARRPTR(val); chkval.arre = chkval.arrb + val->size; chkval.values = STRPTR(val); chkval.operand = GETOPERAND(query); result = TS_execute( GETQUERY(query), &chkval, true, checkcondition_str ); PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(result); }
Datum exectsq(PG_FUNCTION_ARGS) { tsvector *val = (tsvector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1))); CHKVAL chkval; bool result; SET_FUNCOID(); if (!val->size || !query->size) { PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(false); } chkval.arrb = ARRPTR(val); chkval.arre = chkval.arrb + val->size; chkval.values = STRPTR(val); chkval.operand = GETOPERAND(query); result = TS_execute( GETQUERY(query), &chkval, true, checkcondition_str ); PG_FREE_IF_COPY(val, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(result); }
datum_t gin_tsquery_consistent(PG_FUNC_ARGS) { bool *check = (bool *) ARG_POINTER(0); /* strat_nr_t strategy = ARG_UINT16(1); */ TSQuery query = ARG_TSQUERY(2); /* int32 nkeys = ARG_INT32(3); */ pointer_p *extra_data = (pointer_p *) ARG_POINTER(4); bool *recheck = (bool *) ARG_POINTER(5); bool res = FALSE; /* The query requires recheck only if it involves weights */ *recheck = false; if (query->size > 0) { QueryItem *item; GinChkVal gcv; /* * check-parameter array has one entry for each value (operand) in the * query. */ gcv.first_item = item = GETQUERY(query); gcv.check = check; gcv.map_item_operand = (int *)(extra_data[0]); gcv.need_recheck = recheck; res = TS_execute(GETQUERY(query), &gcv, true, checkcondition_gin); } RET_BOOL(res); }
Datum gin_ts_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(2)); bool res = FALSE; if (query->size > 0) { int4 i, j = 0; ITEM *item; GinChkVal gcv; gcv.frst = item = GETQUERY(query); gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size); for (i = 0; i < query->size; i++) if (item[i].type == VAL) gcv.mapped_check[i] = check[j++]; res = TS_execute( GETQUERY(query), &gcv, true, checkcondition_gin ); } PG_FREE_IF_COPY(query, 2); PG_RETURN_BOOL(res); }
/* * 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; }
Datum gin_tsquery_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); /* StrategyNumber strategy = PG_GETARG_UINT16(1); */ TSQuery query = PG_GETARG_TSQUERY(2); bool res = FALSE; if (query->size > 0) { int i, j = 0; QueryItem *item; GinChkVal gcv; /* * check-parameter array has one entry for each value (operand) in the * query. We expand that array into mapped_check, so that there's one * entry in mapped_check for every node in the query, including * operators, to allow quick lookups in checkcondition_gin. Only the * entries corresponding operands are actually used. */ gcv.frst = item = GETQUERY(query); gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size); for (i = 0; i < query->size; i++) if (item[i].type == QI_VAL) gcv.mapped_check[i] = check[j++]; res = TS_execute( GETQUERY(query), &gcv, true, checkcondition_gin ); } PG_RETURN_BOOL(res); }
Datum gin_tsquery_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); /* StrategyNumber strategy = PG_GETARG_UINT16(1); */ TSQuery query = PG_GETARG_TSQUERY(2); /* int32 nkeys = PG_GETARG_INT32(3); */ Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = FALSE; /* The query requires recheck only if it involves weights */ *recheck = false; if (query->size > 0) { QueryItem *item; GinChkVal gcv; /* * check-parameter array has one entry for each value (operand) in the * query. */ gcv.first_item = item = GETQUERY(query); gcv.check = reinterpret_cast<char *>(check); gcv.map_item_operand = (int *) (extra_data[0]); gcv.need_recheck = recheck; res = TS_execute(GETQUERY(query), &gcv, true, reinterpret_cast<bool (*)(void*, QueryOperand*)>(checkcondition_gin)); } PG_RETURN_BOOL(res); }
Datum gin_tsquery_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); /* StrategyNumber strategy = PG_GETARG_UINT16(1); */ TSQuery query = PG_GETARG_TSQUERY(2); /* int32 nkeys = PG_GETARG_INT32(3); */ Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = false; /* Initially assume query doesn't require recheck */ *recheck = false; if (query->size > 0) { GinChkVal gcv; /* * check-parameter array has one entry for each value (operand) in the * query. */ gcv.first_item = GETQUERY(query); gcv.check = check; gcv.map_item_operand = (int *) (extra_data[0]); gcv.need_recheck = recheck; res = TS_execute(GETQUERY(query), &gcv, TS_EXEC_CALC_NOT | TS_EXEC_PHRASE_NO_POS, checkcondition_gin); } PG_RETURN_BOOL(res); }
static bool Cover(DocRepresentation * doc, int len, QUERYTYPE * query, Extention * ext) { DocRepresentation *ptr; int lastpos = ext->pos; int i; bool found = false; reset_istrue_flag(query); ext->p = 0x7fffffff; ext->q = 0; ptr = doc + ext->pos; /* find upper bound of cover from current position, move up */ while (ptr - doc < len) { for (i = 0; i < ptr->nitem; i++) ptr->item[i]->istrue = 1; if (TS_execute(GETQUERY(query), NULL, false, checkcondition_ITEM)) { if (ptr->pos > ext->q) { ext->q = ptr->pos; ext->end = ptr; lastpos = ptr - doc; found = true; } break; } ptr++; } if (!found) return false; reset_istrue_flag(query); ptr = doc + lastpos; /* find lower bound of cover from founded upper bound, move down */ while (ptr >= doc) { for (i = 0; i < ptr->nitem; i++) ptr->item[i]->istrue = 1; if (TS_execute(GETQUERY(query), NULL, true, checkcondition_ITEM)) { if (ptr->pos < ext->p) { ext->begin = ptr; ext->p = ptr->pos; } break; } ptr--; } if (ext->p <= ext->q) { /* * set position for next try to next lexeme after begining of founded * cover */ ext->pos = (ptr - doc) + 1; return true; } ext->pos++; return Cover(doc, len, query, ext); }
static bool Cover(DocRepresentation *doc, int len, QueryRepresentation *qr, Extention *ext) { DocRepresentation *ptr; int lastpos = ext->pos; int i; bool found = false; /* * since this function recurses, it could be driven to stack overflow. * (though any decent compiler will optimize away the tail-recursion. */ check_stack_depth(); memset(qr->operandexist, 0, sizeof(bool) * qr->query->size); ext->p = 0x7fffffff; ext->q = 0; ptr = doc + ext->pos; /* find upper bound of cover from current position, move up */ while (ptr - doc < len) { for (i = 0; i < ptr->nitem; i++) { if (ptr->item[i]->type == QI_VAL) QR_SET_OPERAND_EXISTS(qr, ptr->item[i]); } if (TS_execute(GETQUERY(qr->query), (void *) qr, false, checkcondition_QueryOperand)) { if (ptr->pos > ext->q) { ext->q = ptr->pos; ext->end = ptr; lastpos = ptr - doc; found = true; } break; } ptr++; } if (!found) return false; memset(qr->operandexist, 0, sizeof(bool) * qr->query->size); ptr = doc + lastpos; /* find lower bound of cover from found upper bound, move down */ while (ptr >= doc + ext->pos) { for (i = 0; i < ptr->nitem; i++) if (ptr->item[i]->type == QI_VAL) QR_SET_OPERAND_EXISTS(qr, ptr->item[i]); if (TS_execute(GETQUERY(qr->query), (void *) qr, true, checkcondition_QueryOperand)) { if (ptr->pos < ext->p) { ext->begin = ptr; ext->p = ptr->pos; } break; } ptr--; } if (ext->p <= ext->q) { /* * set position for next try to next lexeme after beginning of found * cover */ ext->pos = (ptr - doc) + 1; return true; } ext->pos++; return Cover(doc, len, qr, ext); }