Exemple #1
0
/*
 * 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;
}
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
/*
 * 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;
}
Exemple #7
0
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);
}
Exemple #9
0
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);
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}