aboutsummaryrefslogtreecommitdiff
path: root/contrib/tsearch2/query_rewrite.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tsearch2/query_rewrite.c')
-rw-r--r--contrib/tsearch2/query_rewrite.c549
1 files changed, 0 insertions, 549 deletions
diff --git a/contrib/tsearch2/query_rewrite.c b/contrib/tsearch2/query_rewrite.c
deleted file mode 100644
index 0604a49927a..00000000000
--- a/contrib/tsearch2/query_rewrite.c
+++ /dev/null
@@ -1,549 +0,0 @@
-#include "postgres.h"
-#include "executor/spi.h"
-
-#include "query_util.h"
-
-MemoryContext AggregateContext = NULL;
-
-static int
-addone(int *counters, int last, int total)
-{
- counters[last]++;
- if (counters[last] >= total)
- {
- if (last == 0)
- return 0;
- if (addone(counters, last - 1, total - 1) == 0)
- return 0;
- counters[last] = counters[last - 1] + 1;
- }
- return 1;
-}
-
-static QTNode *
-findeq(QTNode * node, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
-{
-
- if ((node->sign & ex->sign) != ex->sign || node->valnode->type != ex->valnode->type || node->valnode->val != ex->valnode->val)
- return node;
-
- if (node->flags & QTN_NOCHANGE)
- return node;
-
- if (node->valnode->type == OPR)
- {
- if (node->nchild == ex->nchild)
- {
- if (QTNEq(node, ex))
- {
- QTNFree(node);
- if (subs)
- {
- node = QTNCopy(subs, memtype);
- node->flags |= QTN_NOCHANGE;
- }
- else
- node = NULL;
- *isfind = true;
- }
- }
- else if (node->nchild > ex->nchild)
- {
- int *counters = (int *) palloc(sizeof(int) * node->nchild);
- int i;
- QTNode *tnode = (QTNode *) MEMALLOC(memtype, sizeof(QTNode));
-
- memset(tnode, 0, sizeof(QTNode));
- tnode->child = (QTNode **) MEMALLOC(memtype, sizeof(QTNode *) * ex->nchild);
- tnode->nchild = ex->nchild;
- tnode->valnode = (ITEM *) MEMALLOC(memtype, sizeof(ITEM));
- *(tnode->valnode) = *(ex->valnode);
-
- for (i = 0; i < ex->nchild; i++)
- counters[i] = i;
-
- do
- {
- tnode->sign = 0;
- for (i = 0; i < ex->nchild; i++)
- {
- tnode->child[i] = node->child[counters[i]];
- tnode->sign |= tnode->child[i]->sign;
- }
-
- if (QTNEq(tnode, ex))
- {
- int j = 0;
-
- MEMFREE(memtype, tnode->valnode);
- MEMFREE(memtype, tnode->child);
- MEMFREE(memtype, tnode);
- if (subs)
- {
- tnode = QTNCopy(subs, memtype);
- tnode->flags = QTN_NOCHANGE | QTN_NEEDFREE;
- }
- else
- tnode = NULL;
-
- node->child[counters[0]] = tnode;
-
- for (i = 1; i < ex->nchild; i++)
- node->child[counters[i]] = NULL;
- for (i = 0; i < node->nchild; i++)
- {
- if (node->child[i])
- {
- node->child[j] = node->child[i];
- j++;
- }
- }
-
- node->nchild = j;
-
- *isfind = true;
-
- break;
- }
- } while (addone(counters, ex->nchild - 1, node->nchild));
- if (tnode && (tnode->flags & QTN_NOCHANGE) == 0)
- {
- MEMFREE(memtype, tnode->valnode);
- MEMFREE(memtype, tnode->child);
- MEMFREE(memtype, tnode);
- }
- else
- QTNSort(node);
- pfree(counters);
- }
- }
- else if (QTNEq(node, ex))
- {
- QTNFree(node);
- if (subs)
- {
- node = QTNCopy(subs, memtype);
- node->flags |= QTN_NOCHANGE;
- }
- else
- {
- node = NULL;
- }
- *isfind = true;
- }
-
- return node;
-}
-
-static QTNode *
-dofindsubquery(QTNode * root, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
-{
- root = findeq(root, ex, memtype, subs, isfind);
-
- if (root && (root->flags & QTN_NOCHANGE) == 0 && root->valnode->type == OPR)
- {
- int i;
-
- for (i = 0; i < root->nchild; i++)
- root->child[i] = dofindsubquery(root->child[i], ex, memtype, subs, isfind);
- }
-
- return root;
-}
-
-static QTNode *
-dropvoidsubtree(QTNode * root)
-{
-
- if (!root)
- return NULL;
-
- if (root->valnode->type == OPR)
- {
- int i,
- j = 0;
-
- for (i = 0; i < root->nchild; i++)
- {
- if (root->child[i])
- {
- root->child[j] = root->child[i];
- j++;
- }
- }
-
- root->nchild = j;
-
- if (root->valnode->val == (int4) '!' && root->nchild == 0)
- {
- QTNFree(root);
- root = NULL;
- }
- else if (root->nchild == 1)
- {
- QTNode *nroot = root->child[0];
-
- pfree(root);
- root = nroot;
- }
- }
-
- return root;
-}
-
-static QTNode *
-findsubquery(QTNode * root, QTNode * ex, MemoryType memtype, QTNode * subs, bool *isfind)
-{
- bool DidFind = false;
-
- root = dofindsubquery(root, ex, memtype, subs, &DidFind);
-
- if (!subs && DidFind)
- root = dropvoidsubtree(root);
-
- if (isfind)
- *isfind = DidFind;
-
- return root;
-}
-
-static Oid tsqOid = InvalidOid;
-static void
-get_tsq_Oid(void)
-{
- int ret;
- bool isnull;
-
- if ((ret = SPI_exec("select oid from pg_type where typname='tsquery'", 1)) < 0)
- /* internal error */
- elog(ERROR, "SPI_exec to get tsquery oid returns %d", ret);
-
- if (SPI_processed < 1)
- /* internal error */
- elog(ERROR, "there is no tsvector type");
- tsqOid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull));
- if (tsqOid == InvalidOid)
- /* internal error */
- elog(ERROR, "tsquery type has InvalidOid");
-}
-
-
-PG_FUNCTION_INFO_V1(tsquery_rewrite);
-PG_FUNCTION_INFO_V1(rewrite_accum);
-Datum rewrite_accum(PG_FUNCTION_ARGS);
-
-Datum
-rewrite_accum(PG_FUNCTION_ARGS)
-{
- QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
- ArrayType *qa = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
- QUERYTYPE *q;
- QTNode *qex,
- *subs = NULL,
- *acctree;
- bool isfind = false;
- Datum *elemsp;
- int nelemsp;
-
- AggregateContext = ((AggState *) fcinfo->context)->aggcontext;
-
- if (acc == NULL || PG_ARGISNULL(0))
- {
- acc = (QUERYTYPE *) MEMALLOC(AggMemory, sizeof(QUERYTYPE));
- SET_VARSIZE(acc, HDRSIZEQT);
- acc->size = 0;
- }
-
- if (qa == NULL || PG_ARGISNULL(1))
- {
- PG_FREE_IF_COPY(qa, 1);
- PG_RETURN_POINTER(acc);
- }
-
- if (ARR_NDIM(qa) != 1)
- elog(ERROR, "array must be one-dimensional, not %d dimension", ARR_NDIM(qa));
-
- if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
- elog(ERROR, "array should have only three elements");
-
- if (tsqOid == InvalidOid)
- {
- SPI_connect();
- get_tsq_Oid();
- SPI_finish();
- }
-
- if (ARR_ELEMTYPE(qa) != tsqOid)
- elog(ERROR, "array should contain tsquery type");
-
- deconstruct_array(qa, tsqOid, -1, false, 'i', &elemsp, NULL, &nelemsp);
-
- q = (QUERYTYPE *) DatumGetPointer(elemsp[0]);
- if (q->size == 0)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
-
- if (!acc->size)
- {
- if (VARSIZE(acc) > HDRSIZEQT)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
- else
- acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
- }
- else
- acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));
-
- QTNTernary(acctree);
- QTNSort(acctree);
-
- q = (QUERYTYPE *) DatumGetPointer(elemsp[1]);
- if (q->size == 0)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
- qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
- QTNTernary(qex);
- QTNSort(qex);
-
- q = (QUERYTYPE *) DatumGetPointer(elemsp[2]);
- if (q->size)
- subs = QT2QTN(GETQUERY(q), GETOPERAND(q));
-
- acctree = findsubquery(acctree, qex, PlainMemory, subs, &isfind);
-
- if (isfind || !acc->size)
- {
- /* pfree( acc ); do not pfree(p), because nodeAgg.c will */
- if (acctree)
- {
- QTNBinary(acctree);
- acc = QTN2QT(acctree, AggMemory);
- }
- else
- {
- acc = (QUERYTYPE *) MEMALLOC(AggMemory, HDRSIZEQT * 2);
- SET_VARSIZE(acc, HDRSIZEQT * 2);
- acc->size = 0;
- }
- }
-
- pfree(elemsp);
- QTNFree(qex);
- QTNFree(subs);
- QTNFree(acctree);
-
- PG_RETURN_POINTER(acc);
-}
-
-PG_FUNCTION_INFO_V1(rewrite_finish);
-Datum rewrite_finish(PG_FUNCTION_ARGS);
-
-Datum
-rewrite_finish(PG_FUNCTION_ARGS)
-{
- QUERYTYPE *acc = (QUERYTYPE *) PG_GETARG_POINTER(0);
- QUERYTYPE *rewrited;
-
- if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0)
- {
- acc = (QUERYTYPE *) palloc(sizeof(QUERYTYPE));
- SET_VARSIZE(acc, HDRSIZEQT);
- acc->size = 0;
- }
-
- rewrited = (QUERYTYPE *) palloc(VARSIZE(acc));
- memcpy(rewrited, acc, VARSIZE(acc));
- pfree(acc);
-
- PG_RETURN_POINTER(rewrited);
-}
-
-Datum tsquery_rewrite(PG_FUNCTION_ARGS);
-
-Datum
-tsquery_rewrite(PG_FUNCTION_ARGS)
-{
- QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
- text *in = PG_GETARG_TEXT_P(1);
- QUERYTYPE *rewrited = query;
- QTNode *tree;
- char *buf;
- void *plan;
- Portal portal;
- bool isnull;
- int i;
-
- if (query->size == 0)
- {
- PG_FREE_IF_COPY(in, 1);
- PG_RETURN_POINTER(rewrited);
- }
-
- tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
- QTNTernary(tree);
- QTNSort(tree);
-
- buf = (char *) palloc(VARSIZE(in));
- memcpy(buf, VARDATA(in), VARSIZE(in) - VARHDRSZ);
- buf[VARSIZE(in) - VARHDRSZ] = '\0';
-
- SPI_connect();
-
- if (tsqOid == InvalidOid)
- get_tsq_Oid();
-
- if ((plan = SPI_prepare(buf, 0, NULL)) == NULL)
- elog(ERROR, "SPI_prepare('%s') returns NULL", buf);
-
- if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, false)) == NULL)
- elog(ERROR, "SPI_cursor_open('%s') returns NULL", buf);
-
- SPI_cursor_fetch(portal, true, 100);
-
- if (SPI_tuptable->tupdesc->natts != 2)
- elog(ERROR, "number of fields doesn't equal to 2");
-
- if (SPI_gettypeid(SPI_tuptable->tupdesc, 1) != tsqOid)
- elog(ERROR, "column #1 isn't of tsquery type");
-
- if (SPI_gettypeid(SPI_tuptable->tupdesc, 2) != tsqOid)
- elog(ERROR, "column #2 isn't of tsquery type");
-
- while (SPI_processed > 0 && tree)
- {
- for (i = 0; i < SPI_processed && tree; i++)
- {
- Datum qdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
- Datum sdata;
-
- if (isnull)
- continue;
-
- sdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 2, &isnull);
-
- if (!isnull)
- {
- QUERYTYPE *qtex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(qdata));
- QUERYTYPE *qtsubs = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(sdata));
- QTNode *qex,
- *qsubs = NULL;
-
- if (qtex->size == 0)
- {
- if (qtex != (QUERYTYPE *) DatumGetPointer(qdata))
- pfree(qtex);
- if (qtsubs != (QUERYTYPE *) DatumGetPointer(sdata))
- pfree(qtsubs);
- continue;
- }
-
- qex = QT2QTN(GETQUERY(qtex), GETOPERAND(qtex));
-
- QTNTernary(qex);
- QTNSort(qex);
-
- if (qtsubs->size)
- qsubs = QT2QTN(GETQUERY(qtsubs), GETOPERAND(qtsubs));
-
- tree = findsubquery(tree, qex, SPIMemory, qsubs, NULL);
-
- QTNFree(qex);
- if (qtex != (QUERYTYPE *) DatumGetPointer(qdata))
- pfree(qtex);
- QTNFree(qsubs);
- if (qtsubs != (QUERYTYPE *) DatumGetPointer(sdata))
- pfree(qtsubs);
- }
- }
-
- SPI_freetuptable(SPI_tuptable);
- SPI_cursor_fetch(portal, true, 100);
- }
-
- SPI_freetuptable(SPI_tuptable);
- SPI_cursor_close(portal);
- SPI_freeplan(plan);
- SPI_finish();
-
-
- if (tree)
- {
- QTNBinary(tree);
- rewrited = QTN2QT(tree, PlainMemory);
- QTNFree(tree);
- PG_FREE_IF_COPY(query, 0);
- }
- else
- {
- SET_VARSIZE(rewrited, HDRSIZEQT);
- rewrited->size = 0;
- }
-
- pfree(buf);
- PG_FREE_IF_COPY(in, 1);
- PG_RETURN_POINTER(rewrited);
-}
-
-
-PG_FUNCTION_INFO_V1(tsquery_rewrite_query);
-Datum tsquery_rewrite_query(PG_FUNCTION_ARGS);
-
-Datum
-tsquery_rewrite_query(PG_FUNCTION_ARGS)
-{
- QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
- QUERYTYPE *ex = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1)));
- QUERYTYPE *subst = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(2)));
- QUERYTYPE *rewrited = query;
- QTNode *tree,
- *qex,
- *subs = NULL;
-
- if (query->size == 0 || ex->size == 0)
- {
- PG_FREE_IF_COPY(ex, 1);
- PG_FREE_IF_COPY(subst, 2);
- PG_RETURN_POINTER(rewrited);
- }
-
- tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
- QTNTernary(tree);
- QTNSort(tree);
-
- qex = QT2QTN(GETQUERY(ex), GETOPERAND(ex));
- QTNTernary(qex);
- QTNSort(qex);
-
- if (subst->size)
- subs = QT2QTN(GETQUERY(subst), GETOPERAND(subst));
-
- tree = findsubquery(tree, qex, PlainMemory, subs, NULL);
- QTNFree(qex);
- QTNFree(subs);
-
- if (!tree)
- {
- SET_VARSIZE(rewrited, HDRSIZEQT);
- rewrited->size = 0;
- PG_FREE_IF_COPY(ex, 1);
- PG_FREE_IF_COPY(subst, 2);
- PG_RETURN_POINTER(rewrited);
- }
- else
- {
- QTNBinary(tree);
- rewrited = QTN2QT(tree, PlainMemory);
- QTNFree(tree);
- }
-
- PG_FREE_IF_COPY(query, 0);
- PG_FREE_IF_COPY(ex, 1);
- PG_FREE_IF_COPY(subst, 2);
- PG_RETURN_POINTER(rewrited);
-}