diff options
Diffstat (limited to 'contrib/tsearch2/query_rewrite.c')
-rw-r--r-- | contrib/tsearch2/query_rewrite.c | 613 |
1 files changed, 343 insertions, 270 deletions
diff --git a/contrib/tsearch2/query_rewrite.c b/contrib/tsearch2/query_rewrite.c index e3d40cc44d8..f1faaf87786 100644 --- a/contrib/tsearch2/query_rewrite.c +++ b/contrib/tsearch2/query_rewrite.c @@ -6,135 +6,167 @@ MemoryContext AggregateContext = NULL; static int -addone(int * counters, int last, int total) { +addone(int *counters, int last, int total) +{ counters[last]++; - if ( counters[last]>=total ) { - if (last==0) + if (counters[last] >= total) + { + if (last == 0) return 0; - if ( addone( counters, last-1, total-1 ) == 0 ) + if (addone(counters, last - 1, total - 1) == 0) return 0; - counters[last] = counters[last-1]+1; + 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 ) +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->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 ); + 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; + } + 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) ); + } + 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->child = (QTNode **) MEMALLOC(memtype, sizeof(QTNode *) * ex->nchild); tnode->nchild = ex->nchild; - tnode->valnode = (ITEM*)MEMALLOC( memtype, sizeof(ITEM) ); + tnode->valnode = (ITEM *) MEMALLOC(memtype, sizeof(ITEM)); *(tnode->valnode) = *(ex->valnode); - for(i=0;i<ex->nchild;i++) - counters[i]=i; + 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] ]; + 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; + if (QTNEq(tnode, ex)) + { + int j = 0; - MEMFREE( memtype, tnode->valnode ); - MEMFREE( memtype, tnode->child ); - MEMFREE( memtype, tnode ); - if ( subs ) { - tnode = QTNCopy( subs, memtype ); + MEMFREE(memtype, tnode->valnode); + MEMFREE(memtype, tnode->child); + MEMFREE(memtype, tnode); + if (subs) + { + tnode = QTNCopy(subs, memtype); tnode->flags = QTN_NOCHANGE | QTN_NEEDFREE; - } else + } + else tnode = NULL; - node->child[ counters[0] ] = tnode; + 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] ) { + 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; + 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 ); + } 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 ); + } + else if (QTNEq(node, ex)) + { + QTNFree(node); + if (subs) + { + node = QTNCopy(subs, memtype); node->flags |= QTN_NOCHANGE; - } else { + } + 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 ); +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; - 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 ); + 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 ) { +dropvoidsubtree(QTNode * root) +{ - if ( !root ) + if (!root) return NULL; - if ( root->valnode->type==OPR ) { - int i,j=0; + if (root->valnode->type == OPR) + { + int i, + j = 0; - for(i=0;i<root->nchild;i++) { - if ( root->child[i] ) { + for (i = 0; i < root->nchild; i++) + { + if (root->child[i]) + { root->child[j] = root->child[i]; j++; } @@ -142,88 +174,100 @@ dropvoidsubtree( QTNode *root ) { root->nchild = j; - if ( root->valnode->val == (int4)'!' && root->nchild==0 ) { + if (root->valnode->val == (int4) '!' && root->nchild == 0) + { QTNFree(root); - root=NULL; - } else if ( root->nchild==1 ) { - QTNode *nroot = root->child[0]; + root = NULL; + } + else if (root->nchild == 1) + { + QTNode *nroot = root->child[0]; + pfree(root); - root = nroot; - } + 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 ); +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 (!subs && DidFind) + root = dropvoidsubtree(root); - if ( isfind ) + if (isfind) *isfind = DidFind; return root; } -static Oid tsqOid = InvalidOid; +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 < 0) - /* 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"); + 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 < 0) + /* 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; +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) ); + + if (acc == NULL || PG_ARGISNULL(0)) + { + acc = (QUERYTYPE *) MEMALLOC(AggMemory, sizeof(QUERYTYPE)); acc->len = HDRSIZEQT; acc->size = 0; } - if ( qa == NULL || PG_ARGISNULL(1) ) { - PG_FREE_IF_COPY( qa, 1 ); - PG_RETURN_POINTER( acc ); + if (qa == NULL || PG_ARGISNULL(1)) + { + PG_FREE_IF_COPY(qa, 1); + PG_RETURN_POINTER(acc); } - if ( ARR_NDIM(qa) != 1 ) + 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 ) + if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3) elog(ERROR, "array should have only three elements"); - if (tsqOid == InvalidOid) { + if (tsqOid == InvalidOid) + { SPI_connect(); get_tsq_Oid(); SPI_finish(); @@ -232,108 +276,122 @@ rewrite_accum(PG_FUNCTION_ARGS) { if (ARR_ELEMTYPE(qa) != tsqOid) elog(ERROR, "array should contain tsquery type"); - deconstruct_array(qa, tsqOid, -1, false, 'i', &elemsp, NULL, &nelemsp); + 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 ); + q = (QUERYTYPE *) DatumGetPointer(elemsp[0]); + if (q->size == 0) + { + pfree(elemsp); + PG_RETURN_POINTER(acc); } - - if ( !acc->size ) { - if ( acc->len > 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 ); + + if (!acc->size) + { + if (acc->len > HDRSIZEQT) + { + pfree(elemsp); + PG_RETURN_POINTER(acc); + } + else + acctree = QT2QTN(GETQUERY(q), GETOPERAND(q)); } - qex = QT2QTN( GETQUERY(q), GETOPERAND(q) ); - QTNTernary( qex ); - QTNSort( qex ); - - q = (QUERYTYPE*)DatumGetPointer( elemsp[2] ); - if ( q->size ) - subs = QT2QTN( GETQUERY(q), GETOPERAND(q) ); + else + acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc)); - acctree = findsubquery( acctree, qex, PlainMemory, subs, &isfind ); + 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); - if ( isfind || !acc->size ) { + 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 ); + if (acctree) + { + QTNBinary(acctree); + acc = QTN2QT(acctree, AggMemory); + } + else + { + acc = (QUERYTYPE *) MEMALLOC(AggMemory, HDRSIZEQT * 2); acc->len = HDRSIZEQT * 2; acc->size = 0; } } - pfree( elemsp ); - QTNFree( qex ); - QTNFree( subs ); - QTNFree( acctree ); + pfree(elemsp); + QTNFree(qex); + QTNFree(subs); + QTNFree(acctree); - PG_RETURN_POINTER( acc ); + 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)); +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)); acc->len = HDRSIZEQT; acc->size = 0; } - rewrited = (QUERYTYPE*) palloc( acc->len ); - memcpy( rewrited, acc, acc->len ); - pfree( acc ); + rewrited = (QUERYTYPE *) palloc(acc->len); + memcpy(rewrited, acc, acc->len); + pfree(acc); - PG_RETURN_POINTER(rewrited); + PG_RETURN_POINTER(rewrited); } -Datum tsquery_rewrite(PG_FUNCTION_ARGS); +Datum tsquery_rewrite(PG_FUNCTION_ARGS); Datum -tsquery_rewrite(PG_FUNCTION_ARGS) { +tsquery_rewrite(PG_FUNCTION_ARGS) +{ QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - text *in = PG_GETARG_TEXT_P(1); + 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 ) { + 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 ); + PG_RETURN_POINTER(rewrited); } - tree = QT2QTN( GETQUERY(query), GETOPERAND(query) ); - QTNTernary( tree ); - QTNSort( tree ); + tree = QT2QTN(GETQUERY(query), GETOPERAND(query)); + QTNTernary(tree); + QTNSort(tree); - buf = (char*)palloc( VARSIZE(in) ); + buf = (char *) palloc(VARSIZE(in)); memcpy(buf, VARDATA(in), VARSIZE(in) - VARHDRSZ); - buf[ VARSIZE(in) - VARHDRSZ ] = '\0'; + buf[VARSIZE(in) - VARHDRSZ] = '\0'; SPI_connect(); @@ -345,132 +403,147 @@ tsquery_rewrite(PG_FUNCTION_ARGS) { 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 ) + 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 ) + 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; + 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; + 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 ); + 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) ); + qex = QT2QTN(GETQUERY(qtex), GETOPERAND(qtex)); - QTNTernary( qex ); - QTNSort( qex ); + QTNTernary(qex); + QTNSort(qex); - if ( qtsubs->size ) - qsubs = QT2QTN( GETQUERY(qtsubs), GETOPERAND(qtsubs) ); + 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 ); + 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(); + SPI_finish(); - if ( tree ) { - QTNBinary( tree ); - rewrited = QTN2QT( tree, PlainMemory ); - QTNFree( tree ); + if (tree) + { + QTNBinary(tree); + rewrited = QTN2QT(tree, PlainMemory); + QTNFree(tree); PG_FREE_IF_COPY(query, 0); - } else { + } + else + { rewrited->len = HDRSIZEQT; rewrited->size = 0; } pfree(buf); PG_FREE_IF_COPY(in, 1); - PG_RETURN_POINTER( rewrited ); + 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); 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 ) { +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) + { rewrited->len = 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(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 ); + PG_FREE_IF_COPY(query, 0); + PG_FREE_IF_COPY(ex, 1); + PG_FREE_IF_COPY(subst, 2); + PG_RETURN_POINTER(rewrited); } - |