aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tsvector_op.c
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2007-09-07 15:09:56 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2007-09-07 15:09:56 +0000
commite5be89981fc70648eedb325781cf2fbd4da05ba8 (patch)
tree8a2c587b7ae857fcbe2c2ed4ff21772c11d935a3 /src/backend/utils/adt/tsvector_op.c
parentda1248401d00bce0cb75fa3ab278f906f407bec9 (diff)
downloadpostgresql-e5be89981fc70648eedb325781cf2fbd4da05ba8.tar.gz
postgresql-e5be89981fc70648eedb325781cf2fbd4da05ba8.zip
Refactoring by Heikki Linnakangas <heikki@enterprisedb.com> with
small editorization by me - Brake the QueryItem struct into QueryOperator and QueryOperand. Type was really the only common field between them. QueryItem still exists, and is used in the TSQuery struct as before, but it's now a union of the two. Many other changes fell from that, like separation of pushval_asis function into pushValue, pushOperator and pushStop. - Moved some structs that were for internal use only from header files to the right .c-files. - Moved tsvector parser to a new tsvector_parser.c file. Parser code was about half of the size of tsvector.c, it's also used from tsquery.c, and it has some data structures of its own, so it seems better to separate it. Cleaned up the API so that TSVectorParserState is not accessed from outside tsvector_parser.c. - Separated enumerations (#defines, really) used for QueryItem.type field and as return codes from gettoken_query. It was just accidental code sharing. - Removed ParseQueryNode struct used internally by makepol and friends. push*-functions now construct QueryItems directly. - Changed int4 variables to just ints for variables like "i" or "array size", where the storage-size was not significant.
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;
}