Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions

tsquery_util.c File Reference

#include "postgres.h"
#include "tsearch/ts_utils.h"
#include "miscadmin.h"
Include dependency graph for tsquery_util.c:

Go to the source code of this file.

Data Structures

struct  QTN2QTState

Functions

QTNodeQT2QTN (QueryItem *in, char *operand)
void QTNFree (QTNode *in)
int QTNodeCompare (QTNode *an, QTNode *bn)
static int cmpQTN (const void *a, const void *b)
void QTNSort (QTNode *in)
bool QTNEq (QTNode *a, QTNode *b)
void QTNTernary (QTNode *in)
void QTNBinary (QTNode *in)
static void cntsize (QTNode *in, int *sumlen, int *nnode)
static void fillQT (QTN2QTState *state, QTNode *in)
TSQuery QTN2QT (QTNode *in)
QTNodeQTNCopy (QTNode *in)
void QTNClearFlags (QTNode *in, uint32 flags)

Function Documentation

static int cmpQTN ( const void *  a,
const void *  b 
) [static]

Definition at line 135 of file tsquery_util.c.

References QTNodeCompare().

Referenced by QTNSort().

{
    return QTNodeCompare(*(QTNode *const *) a, *(QTNode *const *) b);
}

static void cntsize ( QTNode in,
int *  sumlen,
int *  nnode 
) [static]

Definition at line 263 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, i, QueryOperand::length, QTNode::nchild, QI_OPR, QueryItem::qoperand, QueryItem::type, and QTNode::valnode.

Referenced by QTN2QT().

{
    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    *nnode += 1;
    if (in->valnode->type == QI_OPR)
    {
        int         i;

        for (i = 0; i < in->nchild; i++)
            cntsize(in->child[i], sumlen, nnode);
    }
    else
    {
        *sumlen += in->valnode->qoperand.length + 1;
    }
}

static void fillQT ( QTN2QTState state,
QTNode in 
) [static]

Definition at line 290 of file tsquery_util.c.

References Assert, check_stack_depth(), QTNode::child, QTN2QTState::curitem, QTN2QTState::curoperand, QueryOperand::distance, QueryOperator::left, QueryOperand::length, QTNode::nchild, QTN2QTState::operand, QI_OPR, QI_VAL, QueryItem::qoperand, QueryItem::qoperator, QueryItem::type, QTNode::valnode, and QTNode::word.

Referenced by QTN2QT().

{
    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (in->valnode->type == QI_VAL)
    {
        memcpy(state->curitem, in->valnode, sizeof(QueryOperand));

        memcpy(state->curoperand, in->word, in->valnode->qoperand.length);
        state->curitem->qoperand.distance = state->curoperand - state->operand;
        state->curoperand[in->valnode->qoperand.length] = '\0';
        state->curoperand += in->valnode->qoperand.length + 1;
        state->curitem++;
    }
    else
    {
        QueryItem  *curitem = state->curitem;

        Assert(in->valnode->type == QI_OPR);

        memcpy(state->curitem, in->valnode, sizeof(QueryOperator));

        Assert(in->nchild <= 2);
        state->curitem++;

        fillQT(state, in->child[0]);

        if (in->nchild == 2)
        {
            curitem->qoperator.left = state->curitem - curitem;
            fillQT(state, in->child[1]);
        }
    }
}

QTNode* QT2QTN ( QueryItem in,
char *  operand 
)

Definition at line 21 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QueryOperand::distance, QueryOperator::left, QTNode::nchild, OP_NOT, QueryOperator::oper, palloc0(), QI_OPR, QueryItem::qoperand, QueryItem::qoperator, QT2QTN(), QTNode::sign, QueryItem::type, QueryOperand::valcrc, QTNode::valnode, and QTNode::word.

Referenced by CompareTSQ(), join_tsqueries(), QT2QTN(), tsa_rewrite_accum(), tsquery_not(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    QTNode     *node = (QTNode *) palloc0(sizeof(QTNode));

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    node->valnode = in;

    if (in->type == QI_OPR)
    {
        node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
        node->child[0] = QT2QTN(in + 1, operand);
        node->sign = node->child[0]->sign;
        if (in->qoperator.oper == OP_NOT)
            node->nchild = 1;
        else
        {
            node->nchild = 2;
            node->child[1] = QT2QTN(in + in->qoperator.left, operand);
            node->sign |= node->child[1]->sign;
        }
    }
    else if (operand)
    {
        node->word = operand + in->qoperand.distance;
        node->sign = ((uint32) 1) << (((unsigned int) in->qoperand.valcrc) % 32);
    }

    return node;
}

TSQuery QTN2QT ( QTNode in  ) 

Definition at line 327 of file tsquery_util.c.

References cntsize(), COMPUTESIZE, QTN2QTState::curitem, QTN2QTState::curoperand, fillQT(), GETOPERAND, GETQUERY, QTN2QTState::operand, palloc0(), SET_VARSIZE, and TSQueryData::size.

Referenced by tsa_rewrite_accum(), tsquery_and(), tsquery_not(), tsquery_or(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    TSQuery     out;
    int         len;
    int         sumlen = 0,
                nnode = 0;
    QTN2QTState state;

    cntsize(in, &sumlen, &nnode);
    len = COMPUTESIZE(nnode, sumlen);

    out = (TSQuery) palloc0(len);
    SET_VARSIZE(out, len);
    out->size = nnode;

    state.curitem = GETQUERY(out);
    state.operand = state.curoperand = GETOPERAND(out);

    fillQT(&state, in);
    return out;
}

void QTNBinary ( QTNode in  ) 

Definition at line 219 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, QueryOperator::oper, palloc0(), QI_OPR, QueryItem::qoperator, QTNBinary(), QTNode::sign, QueryItem::type, and QTNode::valnode.

Referenced by QTNBinary(), tsa_rewrite_accum(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    int         i;

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (in->valnode->type != QI_OPR)
        return;

    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));

        nn->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
        nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);

        nn->nchild = 2;
        nn->flags = QTN_NEEDFREE;

        nn->child[0] = in->child[0];
        nn->child[1] = in->child[1];
        nn->sign = nn->child[0]->sign | nn->child[1]->sign;

        nn->valnode->type = in->valnode->type;
        nn->valnode->qoperator.oper = in->valnode->qoperator.oper;

        in->child[0] = nn;
        in->child[1] = in->child[in->nchild - 1];
        in->nchild--;
    }
}

void QTNClearFlags ( QTNode in,
uint32  flags 
)

Definition at line 385 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, QI_VAL, QTNClearFlags(), QueryItem::type, and QTNode::valnode.

Referenced by QTNClearFlags(), and tsquery_rewrite_query().

{
    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    in->flags &= ~flags;

    if (in->valnode->type != QI_VAL)
    {
        int         i;

        for (i = 0; i < in->nchild; i++)
            QTNClearFlags(in->child[i], flags);
    }
}

QTNode* QTNCopy ( QTNode in  ) 

Definition at line 350 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QueryOperand::length, QTNode::nchild, palloc(), QI_VAL, QueryItem::qoperand, QTNCopy(), QueryItem::type, QTNode::valnode, and QTNode::word.

Referenced by findeq(), and QTNCopy().

{
    QTNode     *out;

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    out = (QTNode *) palloc(sizeof(QTNode));

    *out = *in;
    out->valnode = (QueryItem *) palloc(sizeof(QueryItem));
    *(out->valnode) = *(in->valnode);
    out->flags |= QTN_NEEDFREE;

    if (in->valnode->type == QI_VAL)
    {
        out->word = palloc(in->valnode->qoperand.length + 1);
        memcpy(out->word, in->word, in->valnode->qoperand.length);
        out->word[in->valnode->qoperand.length] = '\0';
        out->flags |= QTN_WORDFREE;
    }
    else
    {
        int         i;

        out->child = (QTNode **) palloc(sizeof(QTNode *) * in->nchild);

        for (i = 0; i < in->nchild; i++)
            out->child[i] = QTNCopy(in->child[i]);
    }

    return out;
}

bool QTNEq ( QTNode a,
QTNode b 
)

Definition at line 158 of file tsquery_util.c.

References QTNodeCompare(), QTNode::sign, and sign.

Referenced by findeq().

{
    uint32      sign = a->sign & b->sign;

    if (!(sign == a->sign && sign == b->sign))
        return 0;

    return (QTNodeCompare(a, b) == 0) ? true : false;
}

void QTNFree ( QTNode in  ) 

Definition at line 54 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, QTNode::nchild, pfree(), QI_OPR, QI_VAL, QTN_NEEDFREE, QTN_WORDFREE, QTNFree(), QueryItem::type, QTNode::valnode, and QTNode::word.

Referenced by CompareTSQ(), dropvoidsubtree(), findeq(), QTNFree(), tsa_rewrite_accum(), tsquery_and(), tsquery_not(), tsquery_or(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    if (!in)
        return;

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (in->valnode->type == QI_VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
        pfree(in->word);

    if (in->child)
    {
        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);
    }

    pfree(in);
}

int QTNodeCompare ( QTNode an,
QTNode bn 
)

Definition at line 86 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, elog, ERROR, i, QueryOperand::length, QTNode::nchild, QueryOperator::oper, QI_OPR, QI_VAL, QueryItem::qoperand, QueryItem::qoperator, QTNodeCompare(), tsCompareString(), QueryItem::type, QueryOperand::valcrc, QTNode::valnode, and QTNode::word.

Referenced by cmpQTN(), CompareTSQ(), QTNEq(), and QTNodeCompare().

{
    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (an->valnode->type != bn->valnode->type)
        return (an->valnode->type > bn->valnode->type) ? -1 : 1;

    if (an->valnode->type == QI_OPR)
    {
        QueryOperator *ao = &an->valnode->qoperator;
        QueryOperator *bo = &bn->valnode->qoperator;

        if (ao->oper != bo->oper)
            return (ao->oper > bo->oper) ? -1 : 1;

        if (an->nchild != bn->nchild)
            return (an->nchild > bn->nchild) ? -1 : 1;

        {
            int         i,
                        res;

            for (i = 0; i < an->nchild; i++)
                if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
                    return res;
        }
        return 0;
    }
    else if (an->valnode->type == QI_VAL)
    {
        QueryOperand *ao = &an->valnode->qoperand;
        QueryOperand *bo = &bn->valnode->qoperand;

        if (ao->valcrc != bo->valcrc)
        {
            return (ao->valcrc > bo->valcrc) ? -1 : 1;
        }

        return tsCompareString(an->word, ao->length, bn->word, bo->length, false);
    }
    else
    {
        elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type);
        return 0;               /* keep compiler quiet */
    }
}

void QTNSort ( QTNode in  ) 

Definition at line 141 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, cmpQTN(), i, QTNode::nchild, QI_OPR, qsort, QTNSort(), QueryItem::type, and QTNode::valnode.

Referenced by findeq(), QTNSort(), tsa_rewrite_accum(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    int         i;

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (in->valnode->type != QI_OPR)
        return;

    for (i = 0; i < in->nchild; i++)
        QTNSort(in->child[i]);
    if (in->nchild > 1)
        qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
}

void QTNTernary ( QTNode in  ) 

Definition at line 176 of file tsquery_util.c.

References check_stack_depth(), QTNode::child, QTNode::flags, i, memmove, QTNode::nchild, QueryOperator::oper, pfree(), QI_OPR, QueryItem::qoperator, QTN_NEEDFREE, QTNTernary(), repalloc(), QueryItem::type, and QTNode::valnode.

Referenced by QTNTernary(), tsa_rewrite_accum(), tsquery_rewrite(), and tsquery_rewrite_query().

{
    int         i;

    /* since this function recurses, it could be driven to stack overflow. */
    check_stack_depth();

    if (in->valnode->type != QI_OPR)
        return;

    for (i = 0; i < in->nchild; i++)
        QTNTernary(in->child[i]);

    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)
        {
            int         oldnchild = in->nchild;

            in->nchild += cc->nchild - 1;
            in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));

            if (i + 1 != oldnchild)
                memmove(in->child + i + cc->nchild, in->child + i + 1,
                        (oldnchild - i - 1) * sizeof(QTNode *));

            memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
            i += cc->nchild - 1;

            if (cc->flags & QTN_NEEDFREE)
                pfree(cc->valnode);
            pfree(cc);
        }
    }
}