Header And Logo

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

Data Structures | Defines | Typedefs | Functions

tsquery_cleanup.c File Reference

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

Go to the source code of this file.

Data Structures

struct  NODE
struct  PLAINTREE

Defines

#define V_UNKNOWN   0
#define V_TRUE   1
#define V_FALSE   2
#define V_STOP   3

Typedefs

typedef struct NODE NODE

Functions

static NODEmaketree (QueryItem *in)
static void plainnode (PLAINTREE *state, NODE *node)
static QueryItemplaintree (NODE *root, int *len)
static void freetree (NODE *node)
static NODEclean_NOT_intree (NODE *node)
QueryItemclean_NOT (QueryItem *ptr, int *len)
static NODEclean_fakeval_intree (NODE *node, char *result)
QueryItemclean_fakeval (QueryItem *ptr, int *len)

Define Documentation

#define V_FALSE   2

Definition at line 207 of file tsquery_cleanup.c.

#define V_STOP   3

Definition at line 209 of file tsquery_cleanup.c.

Referenced by clean_fakeval_intree().

#define V_TRUE   1

Definition at line 205 of file tsquery_cleanup.c.

#define V_UNKNOWN   0

Definition at line 203 of file tsquery_cleanup.c.

Referenced by clean_fakeval().


Typedef Documentation

typedef struct NODE NODE

Function Documentation

QueryItem* clean_fakeval ( QueryItem ptr,
int *  len 
)

Definition at line 274 of file tsquery_cleanup.c.

References clean_fakeval_intree(), ereport, errmsg(), maketree(), NOTICE, plaintree(), and V_UNKNOWN.

Referenced by plainto_tsquery_byid(), and to_tsquery_byid().

{
    NODE       *root = maketree(ptr);
    char        result = V_UNKNOWN;
    NODE       *resroot;

    resroot = clean_fakeval_intree(root, &result);
    if (result != V_UNKNOWN)
    {
        ereport(NOTICE,
                (errmsg("text-search query contains only stop words or doesn't contain lexemes, ignored")));
        *len = 0;
        return NULL;
    }

    return plaintree(resroot, len);
}

static NODE* clean_fakeval_intree ( NODE node,
char *  result 
) [static]

Definition at line 216 of file tsquery_cleanup.c.

References Assert, check_stack_depth(), freetree(), NODE::left, OP_NOT, QueryOperator::oper, pfree(), QI_OPR, QI_VAL, QI_VALSTOP, QueryItem::qoperator, NODE::right, QueryItem::type, V_STOP, and NODE::valnode.

Referenced by clean_fakeval().

{
    char        lresult = V_UNKNOWN,
                rresult = V_UNKNOWN;

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

    if (node->valnode->type == QI_VAL)
        return node;
    else if (node->valnode->type == QI_VALSTOP)
    {
        pfree(node);
        *result = V_STOP;
        return NULL;
    }

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

    if (node->valnode->qoperator.oper == OP_NOT)
    {
        node->right = clean_fakeval_intree(node->right, &rresult);
        if (!node->right)
        {
            *result = V_STOP;
            freetree(node);
            return NULL;
        }
    }
    else
    {
        NODE       *res = node;

        node->left = clean_fakeval_intree(node->left, &lresult);
        node->right = clean_fakeval_intree(node->right, &rresult);

        if (lresult == V_STOP && rresult == V_STOP)
        {
            freetree(node);
            *result = V_STOP;
            return NULL;
        }
        else if (lresult == V_STOP)
        {
            res = node->right;
            pfree(node);
        }
        else if (rresult == V_STOP)
        {
            res = node->left;
            pfree(node);
        }
        return res;
    }
    return node;
}

QueryItem* clean_NOT ( QueryItem ptr,
int *  len 
)

Definition at line 185 of file tsquery_cleanup.c.

References clean_NOT_intree(), maketree(), and plaintree().

Referenced by tsquerytree().

{
    NODE       *root = maketree(ptr);

    return plaintree(clean_NOT_intree(root), len);
}

static NODE* clean_NOT_intree ( NODE node  )  [static]

Definition at line 132 of file tsquery_cleanup.c.

References Assert, check_stack_depth(), freetree(), NODE::left, NULL, OP_AND, OP_NOT, OP_OR, QueryOperator::oper, pfree(), QI_VAL, QueryItem::qoperator, NODE::right, QueryItem::type, and NODE::valnode.

Referenced by clean_NOT().

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

    if (node->valnode->type == QI_VAL)
        return node;

    if (node->valnode->qoperator.oper == OP_NOT)
    {
        freetree(node);
        return NULL;
    }

    /* operator & or | */
    if (node->valnode->qoperator.oper == OP_OR)
    {
        if ((node->left = clean_NOT_intree(node->left)) == NULL ||
            (node->right = clean_NOT_intree(node->right)) == NULL)
        {
            freetree(node);
            return NULL;
        }
    }
    else
    {
        NODE       *res = node;

        Assert(node->valnode->qoperator.oper == OP_AND);

        node->left = clean_NOT_intree(node->left);
        node->right = clean_NOT_intree(node->right);
        if (node->left == NULL && node->right == NULL)
        {
            pfree(node);
            res = NULL;
        }
        else if (node->left == NULL)
        {
            res = node->right;
            pfree(node);
        }
        else if (node->right == NULL)
        {
            res = node->left;
            pfree(node);
        }
        return res;
    }
    return node;
}

static void freetree ( NODE node  )  [static]

Definition at line 111 of file tsquery_cleanup.c.

References check_stack_depth(), NODE::left, pfree(), and NODE::right.

Referenced by clean_fakeval_intree(), and clean_NOT_intree().

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

    if (!node)
        return;
    if (node->left)
        freetree(node->left);
    if (node->right)
        freetree(node->right);
    pfree(node);
}

static NODE* maketree ( QueryItem in  )  [static]

Definition at line 32 of file tsquery_cleanup.c.

References QueryOperator::left, NODE::left, OP_NOT, QueryOperator::oper, palloc(), QI_OPR, QueryItem::qoperator, NODE::right, QueryItem::type, and NODE::valnode.

Referenced by clean_fakeval(), and clean_NOT().

{
    NODE       *node = (NODE *) palloc(sizeof(NODE));

    node->valnode = in;
    node->right = node->left = NULL;
    if (in->type == QI_OPR)
    {
        node->right = maketree(in + 1);
        if (in->qoperator.oper != OP_NOT)
            node->left = maketree(in + in->qoperator.left);
    }
    return node;
}

static void plainnode ( PLAINTREE state,
NODE node 
) [static]

Definition at line 58 of file tsquery_cleanup.c.

References check_stack_depth(), cur, PLAINTREE::cur, NODE::left, QueryOperator::left, PLAINTREE::len, OP_NOT, QueryOperator::oper, pfree(), PLAINTREE::ptr, QI_VAL, QueryItem::qoperator, repalloc(), NODE::right, QueryItem::type, and NODE::valnode.

Referenced by plaintree().

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

    if (state->cur == state->len)
    {
        state->len *= 2;
        state->ptr = (QueryItem *) repalloc((void *) state->ptr, state->len * sizeof(QueryItem));
    }
    memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
    if (node->valnode->type == QI_VAL)
        state->cur++;
    else if (node->valnode->qoperator.oper == OP_NOT)
    {
        state->ptr[state->cur].qoperator.left = 1;
        state->cur++;
        plainnode(state, node->right);
    }
    else
    {
        int         cur = state->cur;

        state->cur++;
        plainnode(state, node->right);
        state->ptr[cur].qoperator.left = state->cur - cur;
        plainnode(state, node->left);
    }
    pfree(node);
}

static QueryItem* plaintree ( NODE root,
int *  len 
) [static]

Definition at line 93 of file tsquery_cleanup.c.

References PLAINTREE::cur, PLAINTREE::len, palloc(), plainnode(), PLAINTREE::ptr, QI_OPR, QI_VAL, QueryItem::type, and NODE::valnode.

Referenced by clean_fakeval(), and clean_NOT().

{
    PLAINTREE   pl;

    pl.cur = 0;
    pl.len = 16;
    if (root && (root->valnode->type == QI_VAL || root->valnode->type == QI_OPR))
    {
        pl.ptr = (QueryItem *) palloc(pl.len * sizeof(QueryItem));
        plainnode(&pl, root);
    }
    else
        pl.ptr = NULL;
    *len = pl.cur;
    return pl.ptr;
}