aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tsquery_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/tsquery_util.c')
-rw-r--r--src/backend/utils/adt/tsquery_util.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c
index b83a7551534..b0033184e7a 100644
--- a/src/backend/utils/adt/tsquery_util.c
+++ b/src/backend/utils/adt/tsquery_util.c
@@ -17,6 +17,9 @@
#include "tsearch/ts_utils.h"
#include "miscadmin.h"
+/*
+ * Build QTNode tree for a tsquery given in QueryItem array format.
+ */
QTNode *
QT2QTN(QueryItem *in, char *operand)
{
@@ -50,6 +53,12 @@ QT2QTN(QueryItem *in, char *operand)
return node;
}
+/*
+ * Free a QTNode tree.
+ *
+ * Referenced "word" and "valnode" items are freed if marked as transient
+ * by flags.
+ */
void
QTNFree(QTNode *in)
{
@@ -62,26 +71,27 @@ QTNFree(QTNode *in)
if (in->valnode->type == QI_VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
pfree(in->word);
- if (in->child)
+ if (in->valnode->type == QI_OPR)
{
- if (in->valnode)
- {
- if (in->valnode->type == QI_OPR && in->nchild > 0)
- {
- int i;
-
- for (i = 0; i < in->nchild; i++)
- QTNFree(in->child[i]);
- }
- if (in->flags & QTN_NEEDFREE)
- pfree(in->valnode);
- }
- pfree(in->child);
+ int i;
+
+ for (i = 0; i < in->nchild; i++)
+ QTNFree(in->child[i]);
}
+ if (in->child)
+ pfree(in->child);
+
+ if (in->flags & QTN_NEEDFREE)
+ pfree(in->valnode);
pfree(in);
}
+/*
+ * Sort comparator for QTNodes.
+ *
+ * The sort order is somewhat arbitrary.
+ */
int
QTNodeCompare(QTNode *an, QTNode *bn)
{
@@ -131,12 +141,19 @@ QTNodeCompare(QTNode *an, QTNode *bn)
}
}
+/*
+ * qsort comparator for QTNode pointers.
+ */
static int
cmpQTN(const void *a, const void *b)
{
return QTNodeCompare(*(QTNode *const *) a, *(QTNode *const *) b);
}
+/*
+ * Canonicalize a QTNode tree by sorting the children of AND/OR nodes
+ * into an arbitrary but well-defined order.
+ */
void
QTNSort(QTNode *in)
{
@@ -154,13 +171,16 @@ QTNSort(QTNode *in)
qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
}
+/*
+ * Are two QTNode trees equal according to QTNodeCompare?
+ */
bool
QTNEq(QTNode *a, QTNode *b)
{
uint32 sign = a->sign & b->sign;
if (!(sign == a->sign && sign == b->sign))
- return 0;
+ return false;
return (QTNodeCompare(a, b) == 0) ? true : false;
}
@@ -186,11 +206,17 @@ QTNTernary(QTNode *in)
for (i = 0; i < in->nchild; i++)
QTNTernary(in->child[i]);
+ /* Only AND and OR are associative, so don't flatten other node types */
+ if (in->valnode->qoperator.oper != OP_AND &&
+ in->valnode->qoperator.oper != OP_OR)
+ return;
+
for (i = 0; i < in->nchild; i++)
{
QTNode *cc = in->child[i];
- if (cc->valnode->type == QI_OPR && in->valnode->qoperator.oper == cc->valnode->qoperator.oper)
+ if (cc->valnode->type == QI_OPR &&
+ in->valnode->qoperator.oper == cc->valnode->qoperator.oper)
{
int oldnchild = in->nchild;
@@ -229,9 +255,6 @@ QTNBinary(QTNode *in)
for (i = 0; i < in->nchild; i++)
QTNBinary(in->child[i]);
- if (in->nchild <= 2)
- return;
-
while (in->nchild > 2)
{
QTNode *nn = (QTNode *) palloc0(sizeof(QTNode));
@@ -256,8 +279,9 @@ QTNBinary(QTNode *in)
}
/*
- * Count the total length of operand string in tree, including '\0'-
- * terminators.
+ * Count the total length of operand strings in tree (including '\0'-
+ * terminators) and the total number of nodes.
+ * Caller must initialize *sumlen and *nnode to zeroes.
*/
static void
cntsize(QTNode *in, int *sumlen, int *nnode)
@@ -286,6 +310,10 @@ typedef struct
char *curoperand;
} QTN2QTState;
+/*
+ * Recursively convert a QTNode tree into flat tsquery format.
+ * Caller must have allocated arrays of the correct size.
+ */
static void
fillQT(QTN2QTState *state, QTNode *in)
{
@@ -323,6 +351,9 @@ fillQT(QTN2QTState *state, QTNode *in)
}
}
+/*
+ * Build flat tsquery from a QTNode tree.
+ */
TSQuery
QTN2QT(QTNode *in)
{
@@ -351,6 +382,11 @@ QTN2QT(QTNode *in)
return out;
}
+/*
+ * Copy a QTNode tree.
+ *
+ * Modifiable copies of the words and valnodes are made, too.
+ */
QTNode *
QTNCopy(QTNode *in)
{
@@ -386,6 +422,9 @@ QTNCopy(QTNode *in)
return out;
}
+/*
+ * Clear the specified flag bit(s) in all nodes of a QTNode tree.
+ */
void
QTNClearFlags(QTNode *in, uint32 flags)
{