aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tsvector_op.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/tsvector_op.c')
-rw-r--r--src/backend/utils/adt/tsvector_op.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 8567172c64f..d34ab1fcf0b 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/tsvector_op.c,v 1.2 2007/08/31 02:26:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsvector_op.c,v 1.3 2007/09/07 15:09:56 teodor Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,6 +66,9 @@ typedef struct
static Datum tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column);
+/*
+ * Order: haspos, len, word, for all positions (pos, weight)
+ */
static int
silly_cmp_tsvector(const TSVector a, const TSVector b)
{
@@ -464,7 +467,7 @@ tsvector_concat(PG_FUNCTION_ARGS)
* compare 2 string values
*/
static int4
-ValCompare(CHKVAL * chkval, WordEntry * ptr, QueryItem * item)
+ValCompare(CHKVAL * chkval, WordEntry * ptr, QueryOperand * item)
{
if (ptr->len == item->length)
return strncmp(
@@ -479,7 +482,7 @@ ValCompare(CHKVAL * chkval, WordEntry * ptr, QueryItem * item)
* check weight info
*/
static bool
-checkclass_str(CHKVAL * chkval, WordEntry * val, QueryItem * item)
+checkclass_str(CHKVAL * chkval, WordEntry * val, QueryOperand * item)
{
WordEntryPos *ptr = (WordEntryPos *) (chkval->values + val->pos + SHORTALIGN(val->len) + sizeof(uint16));
uint16 len = *((uint16 *) (chkval->values + val->pos + SHORTALIGN(val->len)));
@@ -497,10 +500,11 @@ checkclass_str(CHKVAL * chkval, WordEntry * val, QueryItem * item)
* is there value 'val' in array or not ?
*/
static bool
-checkcondition_str(void *checkval, QueryItem * val)
+checkcondition_str(void *checkval, QueryOperand * val)
{
- WordEntry *StopLow = ((CHKVAL *) checkval)->arrb;
- WordEntry *StopHigh = ((CHKVAL *) checkval)->arre;
+ CHKVAL *chkval = (CHKVAL *) checkval;
+ WordEntry *StopLow = chkval->arrb;
+ WordEntry *StopHigh = chkval->arre;
WordEntry *StopMiddle;
int difference;
@@ -509,10 +513,10 @@ checkcondition_str(void *checkval, QueryItem * val)
while (StopLow < StopHigh)
{
StopMiddle = StopLow + (StopHigh - StopLow) / 2;
- difference = ValCompare((CHKVAL *) checkval, StopMiddle, val);
+ difference = ValCompare(chkval, StopMiddle, val);
if (difference == 0)
return (val->weight && StopMiddle->haspos) ?
- checkclass_str((CHKVAL *) checkval, StopMiddle, val) : true;
+ checkclass_str(chkval, StopMiddle, val) : true;
else if (difference < 0)
StopLow = StopMiddle + 1;
else
@@ -523,37 +527,48 @@ checkcondition_str(void *checkval, QueryItem * val)
}
/*
- * check for boolean condition
+ * check for boolean condition.
+ *
+ * if calcnot is false, NOT expressions are always evaluated to be true. This is used in ranking.
+ * checkval can be used to pass information to the callback. TS_execute doesn't
+ * do anything with it.
+ * chkcond is a callback function used to evaluate each VAL node in the query.
+ *
*/
bool
TS_execute(QueryItem * curitem, void *checkval, bool calcnot,
- bool (*chkcond) (void *checkval, QueryItem * val))
+ bool (*chkcond) (void *checkval, QueryOperand * val))
{
/* since this function recurses, it could be driven to stack overflow */
check_stack_depth();
- if (curitem->type == VAL)
- return chkcond(checkval, curitem);
- else if (curitem->val == (int4) '!')
- {
- return (calcnot) ?
- !TS_execute(curitem + 1, checkval, calcnot, chkcond)
- : true;
- }
- else if (curitem->val == (int4) '&')
+ if (curitem->type == QI_VAL)
+ return chkcond(checkval, (QueryOperand *) curitem);
+
+ switch(curitem->operator.oper)
{
- 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);
+ case OP_NOT:
+ if (calcnot)
+ return !TS_execute(curitem + 1, checkval, calcnot, chkcond);
+ else
+ return true;
+ case OP_AND:
+ if (TS_execute(curitem + curitem->operator.left, checkval, calcnot, chkcond))
+ return TS_execute(curitem + 1, checkval, calcnot, chkcond);
+ else
+ return false;
+
+ case OP_OR:
+ if (TS_execute(curitem + curitem->operator.left, checkval, calcnot, chkcond))
+ return true;
+ else
+ return TS_execute(curitem + 1, checkval, calcnot, chkcond);
+
+ default:
+ elog(ERROR, "unknown operator %d", curitem->operator.oper);
}
+
+ /* not reachable, but keep compiler quiet */
return false;
}