Header And Logo

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

Data Structures | Defines | Typedefs | Functions

ts_type.h File Reference

#include "fmgr.h"
#include "utils/pg_crc.h"
Include dependency graph for ts_type.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  WordEntry
struct  WordEntryPosVector
struct  TSVectorData
struct  QueryOperand
struct  QueryOperator
union  QueryItem
struct  TSQueryData

Defines

#define MAXSTRLEN   ( (1<<11) - 1)
#define MAXSTRPOS   ( (1<<20) - 1)
#define WEP_GETWEIGHT(x)   ( (x) >> 14 )
#define WEP_GETPOS(x)   ( (x) & 0x3fff )
#define WEP_SETWEIGHT(x, v)   ( (x) = ( (v) << 14 ) | ( (x) & 0x3fff ) )
#define WEP_SETPOS(x, v)   ( (x) = ( (x) & 0xc000 ) | ( (v) & 0x3fff ) )
#define MAXENTRYPOS   (1<<14)
#define MAXNUMPOS   (256)
#define LIMITPOS(x)   ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) )
#define DATAHDRSIZE   (offsetof(TSVectorData, entries))
#define CALCDATASIZE(nentries, lenstr)   (DATAHDRSIZE + (nentries) * sizeof(WordEntry) + (lenstr) )
#define ARRPTR(x)   ( (x)->entries )
#define STRPTR(x)   ( (char *) &(x)->entries[(x)->size] )
#define _POSVECPTR(x, e)   ((WordEntryPosVector *)(STRPTR(x) + SHORTALIGN((e)->pos + (e)->len)))
#define POSDATALEN(x, e)   ( ( (e)->haspos ) ? (_POSVECPTR(x,e)->npos) : 0 )
#define POSDATAPTR(x, e)   (_POSVECPTR(x,e)->pos)
#define DatumGetTSVector(X)   ((TSVector) PG_DETOAST_DATUM(X))
#define DatumGetTSVectorCopy(X)   ((TSVector) PG_DETOAST_DATUM_COPY(X))
#define TSVectorGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_TSVECTOR(n)   DatumGetTSVector(PG_GETARG_DATUM(n))
#define PG_GETARG_TSVECTOR_COPY(n)   DatumGetTSVectorCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_TSVECTOR(x)   return TSVectorGetDatum(x)
#define QI_VAL   1
#define QI_OPR   2
#define QI_VALSTOP   3
#define OP_NOT   1
#define OP_AND   2
#define OP_OR   3
#define HDRSIZETQ   ( VARHDRSZ + sizeof(int32) )
#define COMPUTESIZE(size, lenofoperand)   ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) )
#define GETQUERY(x)   ((QueryItem*)( (char*)(x)+HDRSIZETQ ))
#define GETOPERAND(x)   ( (char*)GETQUERY(x) + ((TSQuery)(x))->size * sizeof(QueryItem) )
#define DatumGetTSQuery(X)   ((TSQuery) DatumGetPointer(X))
#define DatumGetTSQueryCopy(X)   ((TSQuery) PG_DETOAST_DATUM_COPY(X))
#define TSQueryGetDatum(X)   PointerGetDatum(X)
#define PG_GETARG_TSQUERY(n)   DatumGetTSQuery(PG_GETARG_DATUM(n))
#define PG_GETARG_TSQUERY_COPY(n)   DatumGetTSQueryCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_TSQUERY(x)   return TSQueryGetDatum(x)

Typedefs

typedef uint16 WordEntryPos
typedef TSVectorDataTSVector
typedef int8 QueryItemType
typedef TSQueryDataTSQuery

Functions

Datum tsvectorin (PG_FUNCTION_ARGS)
Datum tsvectorout (PG_FUNCTION_ARGS)
Datum tsvectorsend (PG_FUNCTION_ARGS)
Datum tsvectorrecv (PG_FUNCTION_ARGS)
Datum tsvector_lt (PG_FUNCTION_ARGS)
Datum tsvector_le (PG_FUNCTION_ARGS)
Datum tsvector_eq (PG_FUNCTION_ARGS)
Datum tsvector_ne (PG_FUNCTION_ARGS)
Datum tsvector_ge (PG_FUNCTION_ARGS)
Datum tsvector_gt (PG_FUNCTION_ARGS)
Datum tsvector_cmp (PG_FUNCTION_ARGS)
Datum tsvector_length (PG_FUNCTION_ARGS)
Datum tsvector_strip (PG_FUNCTION_ARGS)
Datum tsvector_setweight (PG_FUNCTION_ARGS)
Datum tsvector_concat (PG_FUNCTION_ARGS)
Datum tsvector_update_trigger_byid (PG_FUNCTION_ARGS)
Datum tsvector_update_trigger_bycolumn (PG_FUNCTION_ARGS)
Datum ts_match_vq (PG_FUNCTION_ARGS)
Datum ts_match_qv (PG_FUNCTION_ARGS)
Datum ts_match_tt (PG_FUNCTION_ARGS)
Datum ts_match_tq (PG_FUNCTION_ARGS)
Datum ts_stat1 (PG_FUNCTION_ARGS)
Datum ts_stat2 (PG_FUNCTION_ARGS)
Datum ts_rank_tt (PG_FUNCTION_ARGS)
Datum ts_rank_wtt (PG_FUNCTION_ARGS)
Datum ts_rank_ttf (PG_FUNCTION_ARGS)
Datum ts_rank_wttf (PG_FUNCTION_ARGS)
Datum ts_rankcd_tt (PG_FUNCTION_ARGS)
Datum ts_rankcd_wtt (PG_FUNCTION_ARGS)
Datum ts_rankcd_ttf (PG_FUNCTION_ARGS)
Datum ts_rankcd_wttf (PG_FUNCTION_ARGS)
Datum tsmatchsel (PG_FUNCTION_ARGS)
Datum tsmatchjoinsel (PG_FUNCTION_ARGS)
Datum ts_typanalyze (PG_FUNCTION_ARGS)
Datum tsqueryin (PG_FUNCTION_ARGS)
Datum tsqueryout (PG_FUNCTION_ARGS)
Datum tsquerysend (PG_FUNCTION_ARGS)
Datum tsqueryrecv (PG_FUNCTION_ARGS)
Datum tsquery_lt (PG_FUNCTION_ARGS)
Datum tsquery_le (PG_FUNCTION_ARGS)
Datum tsquery_eq (PG_FUNCTION_ARGS)
Datum tsquery_ne (PG_FUNCTION_ARGS)
Datum tsquery_ge (PG_FUNCTION_ARGS)
Datum tsquery_gt (PG_FUNCTION_ARGS)
Datum tsquery_cmp (PG_FUNCTION_ARGS)
Datum tsquerytree (PG_FUNCTION_ARGS)
Datum tsquery_numnode (PG_FUNCTION_ARGS)
Datum tsquery_and (PG_FUNCTION_ARGS)
Datum tsquery_or (PG_FUNCTION_ARGS)
Datum tsquery_not (PG_FUNCTION_ARGS)
Datum tsquery_rewrite (PG_FUNCTION_ARGS)
Datum tsquery_rewrite_query (PG_FUNCTION_ARGS)
Datum tsq_mcontains (PG_FUNCTION_ARGS)
Datum tsq_mcontained (PG_FUNCTION_ARGS)

Define Documentation

#define _POSVECPTR (   x,
  e 
)    ((WordEntryPosVector *)(STRPTR(x) + SHORTALIGN((e)->pos + (e)->len)))

Definition at line 100 of file ts_type.h.

Referenced by add_pos(), calc_rank_and(), and tsvector_concat().

#define ARRPTR (   x  )     ( (x)->entries )

Definition at line 95 of file ts_type.h.

#define CALCDATASIZE (   nentries,
  lenstr 
)    (DATAHDRSIZE + (nentries) * sizeof(WordEntry) + (lenstr) )

Definition at line 92 of file ts_type.h.

#define COMPUTESIZE (   size,
  lenofoperand 
)    ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) )

Definition at line 246 of file ts_type.h.

#define DATAHDRSIZE   (offsetof(TSVectorData, entries))

Definition at line 91 of file ts_type.h.

Referenced by tsvectorrecv().

#define DatumGetTSQuery (   X  )     ((TSQuery) DatumGetPointer(X))
#define DatumGetTSQueryCopy (   X  )     ((TSQuery) PG_DETOAST_DATUM_COPY(X))

Definition at line 261 of file ts_type.h.

#define DatumGetTSVector (   X  )     ((TSVector) PG_DETOAST_DATUM(X))
#define DatumGetTSVectorCopy (   X  )     ((TSVector) PG_DETOAST_DATUM_COPY(X))

Definition at line 109 of file ts_type.h.

#define GETOPERAND (   x  )     ( (char*)GETQUERY(x) + ((TSQuery)(x))->size * sizeof(QueryItem) )

Definition at line 252 of file ts_type.h.

#define GETQUERY (   x  )     ((QueryItem*)( (char*)(x)+HDRSIZETQ ))

Definition at line 249 of file ts_type.h.

#define HDRSIZETQ   ( VARHDRSZ + sizeof(int32) )
#define LIMITPOS (   x  )     ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) )

Definition at line 78 of file ts_type.h.

Referenced by add_pos(), gettoken_tsvector(), parsetext(), and uniqueWORD().

#define MAXENTRYPOS   (1<<14)

Definition at line 76 of file ts_type.h.

Referenced by add_pos(), calc_rank_and(), uniquePos(), and uniqueWORD().

#define MAXNUMPOS   (256)

Definition at line 77 of file ts_type.h.

Referenced by add_pos(), tsvectorrecv(), uniquePos(), and uniqueWORD().

#define MAXSTRLEN   ( (1<<11) - 1)
#define MAXSTRPOS   ( (1<<20) - 1)
#define OP_AND   2
#define OP_NOT   1
#define OP_OR   3
#define PG_GETARG_TSQUERY (   n  )     DatumGetTSQuery(PG_GETARG_DATUM(n))
#define PG_GETARG_TSQUERY_COPY (   n  )     DatumGetTSQueryCopy(PG_GETARG_DATUM(n))
#define PG_GETARG_TSVECTOR (   n  )     DatumGetTSVector(PG_GETARG_DATUM(n))
#define PG_GETARG_TSVECTOR_COPY (   n  )     DatumGetTSVectorCopy(PG_GETARG_DATUM(n))

Definition at line 112 of file ts_type.h.

#define PG_RETURN_TSQUERY (   x  )     return TSQueryGetDatum(x)
#define PG_RETURN_TSVECTOR (   x  )     return TSVectorGetDatum(x)

Definition at line 113 of file ts_type.h.

Referenced by tsqueryrecv(), tsvectorin(), and tsvectorrecv().

#define POSDATALEN (   x,
  e 
)    ( ( (e)->haspos ) ? (_POSVECPTR(x,e)->npos) : 0 )
#define POSDATAPTR (   x,
  e 
)    (_POSVECPTR(x,e)->pos)
#define QI_OPR   2
#define QI_VAL   1
#define QI_VALSTOP   3

Definition at line 175 of file ts_type.h.

Referenced by clean_fakeval_intree(), findoprnd_recurse(), and parse_tsquery().

#define STRPTR (   x  )     ( (char *) &(x)->entries[(x)->size] )

Definition at line 98 of file ts_type.h.

#define TSQueryGetDatum (   X  )     PointerGetDatum(X)

Definition at line 262 of file ts_type.h.

Referenced by ts_match_tq(), and ts_match_tt().

#define TSVectorGetDatum (   X  )     PointerGetDatum(X)

Definition at line 110 of file ts_type.h.

Referenced by ts_match_tq(), and ts_match_tt().

#define WEP_GETPOS (   x  )     ( (x) & 0x3fff )
#define WEP_GETWEIGHT (   x  )     ( (x) >> 14 )
#define WEP_SETPOS (   x,
  v 
)    ( (x) = ( (x) & 0xc000 ) | ( (v) & 0x3fff ) )

Definition at line 74 of file ts_type.h.

Referenced by add_pos(), calc_rank_and(), gettoken_tsvector(), and make_tsvector().

#define WEP_SETWEIGHT (   x,
  v 
)    ( (x) = ( (v) << 14 ) | ( (x) & 0x3fff ) )

Definition at line 73 of file ts_type.h.

Referenced by add_pos(), gettoken_tsvector(), make_tsvector(), tsvector_setweight(), and uniquePos().


Typedef Documentation

Definition at line 170 of file ts_type.h.

typedef TSQueryData* TSQuery

Definition at line 239 of file ts_type.h.

Definition at line 89 of file ts_type.h.

Definition at line 61 of file ts_type.h.


Function Documentation

Datum ts_match_qv ( PG_FUNCTION_ARGS   ) 
Datum ts_match_tq ( PG_FUNCTION_ARGS   ) 
Datum ts_match_tt ( PG_FUNCTION_ARGS   ) 
Datum ts_match_vq ( PG_FUNCTION_ARGS   ) 

Definition at line 780 of file tsvector_op.c.

References CHKVAL::arrb, CHKVAL::arre, ARRPTR, checkcondition_str(), GETOPERAND, GETQUERY, CHKVAL::operand, PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, PG_RETURN_BOOL, TSQueryData::size, TSVectorData::size, STRPTR, TS_execute(), val, and CHKVAL::values.

Referenced by ts_match_qv(), ts_match_tq(), and ts_match_tt().

{
    TSVector    val = PG_GETARG_TSVECTOR(0);
    TSQuery     query = PG_GETARG_TSQUERY(1);
    CHKVAL      chkval;
    bool        result;

    if (!val->size || !query->size)
    {
        PG_FREE_IF_COPY(val, 0);
        PG_FREE_IF_COPY(query, 1);
        PG_RETURN_BOOL(false);
    }

    chkval.arrb = ARRPTR(val);
    chkval.arre = chkval.arrb + val->size;
    chkval.values = STRPTR(val);
    chkval.operand = GETOPERAND(query);
    result = TS_execute(
                        GETQUERY(query),
                        &chkval,
                        true,
                        checkcondition_str
        );

    PG_FREE_IF_COPY(val, 0);
    PG_FREE_IF_COPY(query, 1);
    PG_RETURN_BOOL(result);
}

Datum ts_rank_tt ( PG_FUNCTION_ARGS   ) 
Datum ts_rank_ttf ( PG_FUNCTION_ARGS   ) 

Definition at line 462 of file tsrank.c.

References calc_rank(), getWeights(), NULL, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

{
    TSVector    txt = PG_GETARG_TSVECTOR(0);
    TSQuery     query = PG_GETARG_TSQUERY(1);
    int         method = PG_GETARG_INT32(2);
    float       res;

    res = calc_rank(getWeights(NULL), txt, query, method);

    PG_FREE_IF_COPY(txt, 0);
    PG_FREE_IF_COPY(query, 1);
    PG_RETURN_FLOAT4(res);
}

Datum ts_rank_wtt ( PG_FUNCTION_ARGS   ) 
Datum ts_rank_wttf ( PG_FUNCTION_ARGS   ) 
Datum ts_rankcd_tt ( PG_FUNCTION_ARGS   ) 
Datum ts_rankcd_ttf ( PG_FUNCTION_ARGS   ) 

Definition at line 861 of file tsrank.c.

References calc_rank_cd(), getWeights(), NULL, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_TSQUERY, PG_GETARG_TSVECTOR, and PG_RETURN_FLOAT4.

{
    TSVector    txt = PG_GETARG_TSVECTOR(0);
    TSQuery     query = PG_GETARG_TSQUERY(1);
    int         method = PG_GETARG_INT32(2);
    float       res;

    res = calc_rank_cd(getWeights(NULL), txt, query, method);

    PG_FREE_IF_COPY(txt, 0);
    PG_FREE_IF_COPY(query, 1);
    PG_RETURN_FLOAT4(res);
}

Datum ts_rankcd_wtt ( PG_FUNCTION_ARGS   ) 
Datum ts_rankcd_wttf ( PG_FUNCTION_ARGS   ) 
Datum ts_stat1 ( PG_FUNCTION_ARGS   ) 
Datum ts_stat2 ( PG_FUNCTION_ARGS   ) 
Datum ts_typanalyze ( PG_FUNCTION_ARGS   ) 

Definition at line 54 of file ts_typanalyze.c.

References VacAttrStats::attr, VacAttrStats::compute_stats, default_statistics_target, VacAttrStats::minrows, PG_GETARG_POINTER, and PG_RETURN_BOOL.

{
    VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0);
    Form_pg_attribute attr = stats->attr;

    /* If the attstattarget column is negative, use the default value */
    /* NB: it is okay to scribble on stats->attr since it's a copy */
    if (attr->attstattarget < 0)
        attr->attstattarget = default_statistics_target;

    stats->compute_stats = compute_tsvector_stats;
    /* see comment about the choice of minrows in commands/analyze.c */
    stats->minrows = 300 * attr->attstattarget;

    PG_RETURN_BOOL(true);
}

Datum tsmatchjoinsel ( PG_FUNCTION_ARGS   ) 

Definition at line 139 of file ts_selfuncs.c.

References DEFAULT_TS_MATCH_SEL, and PG_RETURN_FLOAT8.

{
    /* for the moment we just punt */
    PG_RETURN_FLOAT8(DEFAULT_TS_MATCH_SEL);
}

Datum tsmatchsel ( PG_FUNCTION_ARGS   ) 

Definition at line 67 of file ts_selfuncs.c.

References Assert, CLAMP_PROBABILITY, DEFAULT_TS_MATCH_SEL, get_restriction_variable(), IsA, PG_GETARG_INT32, PG_GETARG_POINTER, PG_RETURN_FLOAT8, ReleaseVariableStats, TSQUERYOID, tsquerysel(), TSVECTOROID, and VariableStatData::vartype.

{
    PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);

#ifdef NOT_USED
    Oid         operator = PG_GETARG_OID(1);
#endif
    List       *args = (List *) PG_GETARG_POINTER(2);
    int         varRelid = PG_GETARG_INT32(3);
    VariableStatData vardata;
    Node       *other;
    bool        varonleft;
    Selectivity selec;

    /*
     * If expression is not variable = something or something = variable, then
     * punt and return a default estimate.
     */
    if (!get_restriction_variable(root, args, varRelid,
                                  &vardata, &other, &varonleft))
        PG_RETURN_FLOAT8(DEFAULT_TS_MATCH_SEL);

    /*
     * Can't do anything useful if the something is not a constant, either.
     */
    if (!IsA(other, Const))
    {
        ReleaseVariableStats(vardata);
        PG_RETURN_FLOAT8(DEFAULT_TS_MATCH_SEL);
    }

    /*
     * The "@@" operator is strict, so we can cope with NULL right away
     */
    if (((Const *) other)->constisnull)
    {
        ReleaseVariableStats(vardata);
        PG_RETURN_FLOAT8(0.0);
    }

    /*
     * OK, there's a Var and a Const we're dealing with here.  We need the
     * Const to be a TSQuery, else we can't do anything useful.  We have to
     * check this because the Var might be the TSQuery not the TSVector.
     */
    if (((Const *) other)->consttype == TSQUERYOID)
    {
        /* tsvector @@ tsquery or the other way around */
        Assert(vardata.vartype == TSVECTOROID);

        selec = tsquerysel(&vardata, ((Const *) other)->constvalue);
    }
    else
    {
        /* If we can't see the query structure, must punt */
        selec = DEFAULT_TS_MATCH_SEL;
    }

    ReleaseVariableStats(vardata);

    CLAMP_PROBABILITY(selec);

    PG_RETURN_FLOAT8((float8) selec);
}

Datum tsq_mcontained ( PG_FUNCTION_ARGS   ) 
Datum tsq_mcontains ( PG_FUNCTION_ARGS   ) 

Definition at line 217 of file tsquery_op.c.

References GETQUERY, i, makeTSQuerySign(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_BOOL, QI_VAL, QueryItem::qoperand, TSQueryData::size, NODE::type, and QueryOperand::valcrc.

Referenced by tsq_mcontained().

{
    TSQuery     query = PG_GETARG_TSQUERY(0);
    TSQuery     ex = PG_GETARG_TSQUERY(1);
    TSQuerySign sq,
                se;
    int         i,
                j;
    QueryItem  *iq,
               *ie;

    if (query->size < ex->size)
    {
        PG_FREE_IF_COPY(query, 0);
        PG_FREE_IF_COPY(ex, 1);

        PG_RETURN_BOOL(false);
    }

    sq = makeTSQuerySign(query);
    se = makeTSQuerySign(ex);

    if ((sq & se) != se)
    {
        PG_FREE_IF_COPY(query, 0);
        PG_FREE_IF_COPY(ex, 1);

        PG_RETURN_BOOL(false);
    }

    iq = GETQUERY(query);
    ie = GETQUERY(ex);

    for (i = 0; i < ex->size; i++)
    {
        if (ie[i].type != QI_VAL)
            continue;
        for (j = 0; j < query->size; j++)
        {
            if (iq[j].type == QI_VAL &&
                ie[i].qoperand.valcrc == iq[j].qoperand.valcrc)
                break;
        }
        if (j >= query->size)
        {
            PG_FREE_IF_COPY(query, 0);
            PG_FREE_IF_COPY(ex, 1);

            PG_RETURN_BOOL(false);
        }
    }

    PG_FREE_IF_COPY(query, 0);
    PG_FREE_IF_COPY(ex, 1);

    PG_RETURN_BOOL(true);
}

Datum tsquery_and ( PG_FUNCTION_ARGS   ) 
Datum tsquery_cmp ( PG_FUNCTION_ARGS   ) 
Datum tsquery_eq ( PG_FUNCTION_ARGS   ) 
Datum tsquery_ge ( PG_FUNCTION_ARGS   ) 
Datum tsquery_gt ( PG_FUNCTION_ARGS   ) 
Datum tsquery_le ( PG_FUNCTION_ARGS   ) 
Datum tsquery_lt ( PG_FUNCTION_ARGS   ) 
Datum tsquery_ne ( PG_FUNCTION_ARGS   ) 
Datum tsquery_not ( PG_FUNCTION_ARGS   ) 

Definition at line 109 of file tsquery_op.c.

References QTNode::child, QTNode::flags, GETOPERAND, GETQUERY, QTNode::nchild, QueryOperator::oper, palloc0(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QueryItem::qoperator, QT2QTN(), QTN2QT(), QTNFree(), TSQueryData::size, QueryItem::type, and QTNode::valnode.

{
    TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
    QTNode     *res;
    TSQuery     query;

    if (a->size == 0)
        PG_RETURN_POINTER(a);

    res = (QTNode *) palloc0(sizeof(QTNode));

    res->flags |= QTN_NEEDFREE;

    res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
    res->valnode->type = QI_OPR;
    res->valnode->qoperator.oper = OP_NOT;

    res->child = (QTNode **) palloc0(sizeof(QTNode *));
    res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
    res->nchild = 1;

    query = QTN2QT(res);

    QTNFree(res);
    PG_FREE_IF_COPY(a, 0);

    PG_RETURN_POINTER(query);
}

Datum tsquery_numnode ( PG_FUNCTION_ARGS   ) 

Definition at line 20 of file tsquery_op.c.

References PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_INT32, and TSQueryData::size.

{
    TSQuery     query = PG_GETARG_TSQUERY(0);
    int         nnode = query->size;

    PG_FREE_IF_COPY(query, 0);
    PG_RETURN_INT32(nnode);
}

Datum tsquery_or ( PG_FUNCTION_ARGS   ) 

Definition at line 79 of file tsquery_op.c.

References join_tsqueries(), OP_OR, PG_FREE_IF_COPY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QTN2QT(), QTNFree(), and TSQueryData::size.

{
    TSQuery     a = PG_GETARG_TSQUERY_COPY(0);
    TSQuery     b = PG_GETARG_TSQUERY_COPY(1);
    QTNode     *res;
    TSQuery     query;

    if (a->size == 0)
    {
        PG_FREE_IF_COPY(a, 1);
        PG_RETURN_POINTER(b);
    }
    else if (b->size == 0)
    {
        PG_FREE_IF_COPY(b, 1);
        PG_RETURN_POINTER(a);
    }

    res = join_tsqueries(a, b, OP_OR);

    query = QTN2QT(res);

    QTNFree(res);
    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);

    PG_RETURN_POINTER(query);
}

Datum tsquery_rewrite ( PG_FUNCTION_ARGS   ) 

Definition at line 381 of file tsquery_rewrite.c.

References findsubquery(), GETOPERAND, GETQUERY, HDRSIZETQ, NULL, PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QT2QTN(), QTN2QT(), QTNBinary(), QTNFree(), QTNSort(), QTNTernary(), SET_VARSIZE, and TSQueryData::size.

{
    TSQuery     query = PG_GETARG_TSQUERY_COPY(0);
    TSQuery     ex = PG_GETARG_TSQUERY(1);
    TSQuery     subst = PG_GETARG_TSQUERY(2);
    TSQuery     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, subs, NULL);

    QTNFree(qex);
    QTNFree(subs);

    if (!tree)
    {
        SET_VARSIZE(rewrited, HDRSIZETQ);
        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);
        QTNFree(tree);
    }

    PG_FREE_IF_COPY(query, 0);
    PG_FREE_IF_COPY(ex, 1);
    PG_FREE_IF_COPY(subst, 2);
    PG_RETURN_POINTER(rewrited);
}

Datum tsquery_rewrite_query ( PG_FUNCTION_ARGS   ) 

Definition at line 253 of file tsquery_rewrite.c.

References buf, CurrentMemoryContext, DatumGetPointer, DatumGetTSQuery, elog, ereport, errcode(), errmsg(), ERROR, findsubquery(), GETOPERAND, GETQUERY, HDRSIZETQ, i, MemoryContextSwitchTo(), tupleDesc::natts, NULL, pfree(), PG_FREE_IF_COPY, PG_GETARG_TEXT_P, PG_GETARG_TSQUERY_COPY, PG_RETURN_POINTER, QT2QTN(), QTN2QT(), QTN_NOCHANGE, QTNBinary(), QTNClearFlags(), QTNFree(), QTNSort(), QTNTernary(), SET_VARSIZE, TSQueryData::size, SPI_connect(), SPI_cursor_close(), SPI_cursor_fetch(), SPI_cursor_open(), SPI_finish(), SPI_freeplan(), SPI_freetuptable(), SPI_getbinval(), SPI_gettypeid(), SPI_prepare(), SPI_processed, SPI_tuptable, text_to_cstring(), TSQUERYOID, SPITupleTable::tupdesc, and SPITupleTable::vals.

{
    TSQuery     query = PG_GETARG_TSQUERY_COPY(0);
    text       *in = PG_GETARG_TEXT_P(1);
    TSQuery     rewrited = query;
    MemoryContext outercontext = CurrentMemoryContext;
    MemoryContext oldcontext;
    QTNode     *tree;
    char       *buf;
    SPIPlanPtr  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 = text_to_cstring(in);

    SPI_connect();

    if ((plan = SPI_prepare(buf, 0, NULL)) == NULL)
        elog(ERROR, "SPI_prepare(\"%s\") failed", buf);

    if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, true)) == NULL)
        elog(ERROR, "SPI_cursor_open(\"%s\") failed", buf);

    SPI_cursor_fetch(portal, true, 100);

    if (SPI_tuptable == NULL ||
        SPI_tuptable->tupdesc->natts != 2 ||
        SPI_gettypeid(SPI_tuptable->tupdesc, 1) != TSQUERYOID ||
        SPI_gettypeid(SPI_tuptable->tupdesc, 2) != TSQUERYOID)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("ts_rewrite query must return two tsquery columns")));

    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)
            {
                TSQuery     qtex = DatumGetTSQuery(qdata);
                TSQuery     qtsubs = DatumGetTSQuery(sdata);
                QTNode     *qex,
                           *qsubs = NULL;

                if (qtex->size == 0)
                {
                    if (qtex != (TSQuery) DatumGetPointer(qdata))
                        pfree(qtex);
                    if (qtsubs != (TSQuery) DatumGetPointer(sdata))
                        pfree(qtsubs);
                    continue;
                }

                qex = QT2QTN(GETQUERY(qtex), GETOPERAND(qtex));

                QTNTernary(qex);
                QTNSort(qex);

                if (qtsubs->size)
                    qsubs = QT2QTN(GETQUERY(qtsubs), GETOPERAND(qtsubs));

                oldcontext = MemoryContextSwitchTo(outercontext);
                tree = findsubquery(tree, qex, qsubs, NULL);
                MemoryContextSwitchTo(oldcontext);

                QTNFree(qex);
                if (qtex != (TSQuery) DatumGetPointer(qdata))
                    pfree(qtex);
                QTNFree(qsubs);
                if (qtsubs != (TSQuery) DatumGetPointer(sdata))
                    pfree(qtsubs);

                if (tree)
                {
                    /* ready the tree for another pass */
                    QTNClearFlags(tree, QTN_NOCHANGE);
                    QTNSort(tree);
                }
            }
        }

        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);
        QTNFree(tree);
        PG_FREE_IF_COPY(query, 0);
    }
    else
    {
        SET_VARSIZE(rewrited, HDRSIZETQ);
        rewrited->size = 0;
    }

    pfree(buf);
    PG_FREE_IF_COPY(in, 1);
    PG_RETURN_POINTER(rewrited);
}

Datum tsqueryin ( PG_FUNCTION_ARGS   ) 
Datum tsqueryout ( PG_FUNCTION_ARGS   ) 

Definition at line 748 of file tsquery.c.

References INFIX::buf, INFIX::buflen, INFIX::cur, INFIX::curpol, GETOPERAND, GETQUERY, infix(), INFIX::op, palloc(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_CSTRING, PG_RETURN_POINTER, and TSQueryData::size.

{
    TSQuery     query = PG_GETARG_TSQUERY(0);
    INFIX       nrm;

    if (query->size == 0)
    {
        char       *b = palloc(1);

        *b = '\0';
        PG_RETURN_POINTER(b);
    }
    nrm.curpol = GETQUERY(query);
    nrm.buflen = 32;
    nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
    *(nrm.cur) = '\0';
    nrm.op = GETOPERAND(query);
    infix(&nrm, true);

    PG_FREE_IF_COPY(query, 0);
    PG_RETURN_CSTRING(nrm.buf);
}

Datum tsqueryrecv ( PG_FUNCTION_ARGS   ) 

Definition at line 825 of file tsquery.c.

References Assert, buf, COMP_CRC32, QueryOperand::distance, elog, ERROR, FIN_CRC32, findoprnd(), GETOPERAND, GETQUERY, HDRSIZETQ, i, INIT_CRC32, QueryOperand::length, MaxAllocSize, MAXSTRLEN, MAXSTRPOS, OP_AND, OP_NOT, OP_OR, QueryOperator::oper, palloc(), palloc0(), pfree(), PG_GETARG_POINTER, PG_RETURN_TSVECTOR, pq_getmsgint(), pq_getmsgstring(), QueryOperand::prefix, QI_OPR, QI_VAL, QueryItem::qoperand, QueryItem::qoperator, repalloc(), SET_VARSIZE, QueryItem::type, val, QueryOperand::valcrc, and QueryOperand::weight.

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    TSQuery     query;
    int         i,
                len;
    QueryItem  *item;
    int         datalen;
    char       *ptr;
    uint32      size;
    const char **operands;

    size = pq_getmsgint(buf, sizeof(uint32));
    if (size > (MaxAllocSize / sizeof(QueryItem)))
        elog(ERROR, "invalid size of tsquery");

    /* Allocate space to temporarily hold operand strings */
    operands = palloc(size * sizeof(char *));

    /* Allocate space for all the QueryItems. */
    len = HDRSIZETQ + sizeof(QueryItem) * size;
    query = (TSQuery) palloc0(len);
    query->size = size;
    item = GETQUERY(query);

    datalen = 0;
    for (i = 0; i < size; i++)
    {
        item->type = (int8) pq_getmsgint(buf, sizeof(int8));

        if (item->type == QI_VAL)
        {
            size_t      val_len;    /* length after recoding to server encoding */
            uint8       weight;
            uint8       prefix;
            const char *val;
            pg_crc32    valcrc;

            weight = (uint8) pq_getmsgint(buf, sizeof(uint8));
            prefix = (uint8) pq_getmsgint(buf, sizeof(uint8));
            val = pq_getmsgstring(buf);
            val_len = strlen(val);

            /* Sanity checks */

            if (weight > 0xF)
                elog(ERROR, "invalid tsquery: invalid weight bitmap");

            if (val_len > MAXSTRLEN)
                elog(ERROR, "invalid tsquery: operand too long");

            if (datalen > MAXSTRPOS)
                elog(ERROR, "invalid tsquery: total operand length exceeded");

            /* Looks valid. */

            INIT_CRC32(valcrc);
            COMP_CRC32(valcrc, val, val_len);
            FIN_CRC32(valcrc);

            item->qoperand.weight = weight;
            item->qoperand.prefix = (prefix) ? true : false;
            item->qoperand.valcrc = (int32) valcrc;
            item->qoperand.length = val_len;
            item->qoperand.distance = datalen;

            /*
             * Operand strings are copied to the final struct after this loop;
             * here we just collect them to an array
             */
            operands[i] = val;

            datalen += val_len + 1;     /* + 1 for the '\0' terminator */
        }
        else if (item->type == QI_OPR)
        {
            int8        oper;

            oper = (int8) pq_getmsgint(buf, sizeof(int8));
            if (oper != OP_NOT && oper != OP_OR && oper != OP_AND)
                elog(ERROR, "invalid tsquery: unrecognized operator type %d",
                     (int) oper);
            if (i == size - 1)
                elog(ERROR, "invalid pointer to right operand");

            item->qoperator.oper = oper;
        }
        else
            elog(ERROR, "unrecognized tsquery node type: %d", item->type);

        item++;
    }

    /* Enlarge buffer to make room for the operand values. */
    query = (TSQuery) repalloc(query, len + datalen);
    item = GETQUERY(query);
    ptr = GETOPERAND(query);

    /*
     * Fill in the left-pointers. Checks that the tree is well-formed as a
     * side-effect.
     */
    findoprnd(item, size);

    /* Copy operands to output struct */
    for (i = 0; i < size; i++)
    {
        if (item->type == QI_VAL)
        {
            memcpy(ptr, operands[i], item->qoperand.length + 1);
            ptr += item->qoperand.length + 1;
        }
        item++;
    }

    pfree(operands);

    Assert(ptr - GETOPERAND(query) == datalen);

    SET_VARSIZE(query, len + datalen);

    PG_RETURN_TSVECTOR(query);
}

Datum tsquerysend ( PG_FUNCTION_ARGS   ) 

Definition at line 789 of file tsquery.c.

References buf, QueryOperand::distance, elog, ERROR, GETOPERAND, GETQUERY, i, QueryOperator::oper, PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint(), pq_sendstring(), QueryOperand::prefix, QI_OPR, QI_VAL, QueryItem::qoperand, QueryItem::qoperator, TSQueryData::size, QueryItem::type, and QueryOperand::weight.

{
    TSQuery     query = PG_GETARG_TSQUERY(0);
    StringInfoData buf;
    int         i;
    QueryItem  *item = GETQUERY(query);

    pq_begintypsend(&buf);

    pq_sendint(&buf, query->size, sizeof(uint32));
    for (i = 0; i < query->size; i++)
    {
        pq_sendint(&buf, item->type, sizeof(item->type));

        switch (item->type)
        {
            case QI_VAL:
                pq_sendint(&buf, item->qoperand.weight, sizeof(uint8));
                pq_sendint(&buf, item->qoperand.prefix, sizeof(uint8));
                pq_sendstring(&buf, GETOPERAND(query) + item->qoperand.distance);
                break;
            case QI_OPR:
                pq_sendint(&buf, item->qoperator.oper, sizeof(item->qoperator.oper));
                break;
            default:
                elog(ERROR, "unrecognized tsquery node type: %d", item->type);
        }
        item++;
    }

    PG_FREE_IF_COPY(query, 0);

    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}

Datum tsquerytree ( PG_FUNCTION_ARGS   ) 

Definition at line 954 of file tsquery.c.

References INFIX::buf, INFIX::buflen, clean_NOT(), cstring_to_text(), cstring_to_text_with_len(), INFIX::cur, INFIX::curpol, GETOPERAND, GETQUERY, infix(), INFIX::op, palloc(), pfree(), PG_FREE_IF_COPY, PG_GETARG_TSQUERY, PG_RETURN_POINTER, PG_RETURN_TEXT_P, SET_VARSIZE, TSQueryData::size, and VARHDRSZ.

{
    TSQuery     query = PG_GETARG_TSQUERY(0);
    INFIX       nrm;
    text       *res;
    QueryItem  *q;
    int         len;

    if (query->size == 0)
    {
        res = (text *) palloc(VARHDRSZ);
        SET_VARSIZE(res, VARHDRSZ);
        PG_RETURN_POINTER(res);
    }

    q = clean_NOT(GETQUERY(query), &len);

    if (!q)
    {
        res = cstring_to_text("T");
    }
    else
    {
        nrm.curpol = q;
        nrm.buflen = 32;
        nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
        *(nrm.cur) = '\0';
        nrm.op = GETOPERAND(query);
        infix(&nrm, true);
        res = cstring_to_text_with_len(nrm.buf, nrm.cur - nrm.buf);
        pfree(q);
    }

    PG_FREE_IF_COPY(query, 0);

    PG_RETURN_TEXT_P(res);
}

Datum tsvector_cmp ( PG_FUNCTION_ARGS   ) 
Datum tsvector_concat ( PG_FUNCTION_ARGS   ) 

Definition at line 329 of file tsvector_op.c.

References _POSVECPTR, add_pos(), ARRPTR, Assert, CALCDATASIZE, cmp(), compareEntry, ereport, errcode(), errmsg(), ERROR, WordEntry::haspos, i, WordEntry::len, MAXSTRPOS, memmove, palloc0(), PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, PG_RETURN_POINTER, WordEntry::pos, POSDATALEN, POSDATAPTR, SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, VARSIZE, and WEP_GETPOS.

{
    TSVector    in1 = PG_GETARG_TSVECTOR(0);
    TSVector    in2 = PG_GETARG_TSVECTOR(1);
    TSVector    out;
    WordEntry  *ptr;
    WordEntry  *ptr1,
               *ptr2;
    WordEntryPos *p;
    int         maxpos = 0,
                i,
                j,
                i1,
                i2,
                dataoff,
                output_bytes,
                output_size;
    char       *data,
               *data1,
               *data2;

    /* Get max position in in1; we'll need this to offset in2's positions */
    ptr = ARRPTR(in1);
    i = in1->size;
    while (i--)
    {
        if ((j = POSDATALEN(in1, ptr)) != 0)
        {
            p = POSDATAPTR(in1, ptr);
            while (j--)
            {
                if (WEP_GETPOS(*p) > maxpos)
                    maxpos = WEP_GETPOS(*p);
                p++;
            }
        }
        ptr++;
    }

    ptr1 = ARRPTR(in1);
    ptr2 = ARRPTR(in2);
    data1 = STRPTR(in1);
    data2 = STRPTR(in2);
    i1 = in1->size;
    i2 = in2->size;

    /*
     * Conservative estimate of space needed.  We might need all the data in
     * both inputs, and conceivably add a pad byte before position data for
     * each item where there was none before.
     */
    output_bytes = VARSIZE(in1) + VARSIZE(in2) + i1 + i2;

    out = (TSVector) palloc0(output_bytes);
    SET_VARSIZE(out, output_bytes);

    /*
     * We must make out->size valid so that STRPTR(out) is sensible.  We'll
     * collapse out any unused space at the end.
     */
    out->size = in1->size + in2->size;

    ptr = ARRPTR(out);
    data = STRPTR(out);
    dataoff = 0;
    while (i1 && i2)
    {
        int         cmp = compareEntry(data1, ptr1, data2, ptr2);

        if (cmp < 0)
        {                       /* in1 first */
            ptr->haspos = ptr1->haspos;
            ptr->len = ptr1->len;
            memcpy(data + dataoff, data1 + ptr1->pos, ptr1->len);
            ptr->pos = dataoff;
            dataoff += ptr1->len;
            if (ptr->haspos)
            {
                dataoff = SHORTALIGN(dataoff);
                memcpy(data + dataoff, _POSVECPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
                dataoff += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
            }

            ptr++;
            ptr1++;
            i1--;
        }
        else if (cmp > 0)
        {                       /* in2 first */
            ptr->haspos = ptr2->haspos;
            ptr->len = ptr2->len;
            memcpy(data + dataoff, data2 + ptr2->pos, ptr2->len);
            ptr->pos = dataoff;
            dataoff += ptr2->len;
            if (ptr->haspos)
            {
                int         addlen = add_pos(in2, ptr2, out, ptr, maxpos);

                if (addlen == 0)
                    ptr->haspos = 0;
                else
                {
                    dataoff = SHORTALIGN(dataoff);
                    dataoff += addlen * sizeof(WordEntryPos) + sizeof(uint16);
                }
            }

            ptr++;
            ptr2++;
            i2--;
        }
        else
        {
            ptr->haspos = ptr1->haspos | ptr2->haspos;
            ptr->len = ptr1->len;
            memcpy(data + dataoff, data1 + ptr1->pos, ptr1->len);
            ptr->pos = dataoff;
            dataoff += ptr1->len;
            if (ptr->haspos)
            {
                if (ptr1->haspos)
                {
                    dataoff = SHORTALIGN(dataoff);
                    memcpy(data + dataoff, _POSVECPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
                    dataoff += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
                    if (ptr2->haspos)
                        dataoff += add_pos(in2, ptr2, out, ptr, maxpos) * sizeof(WordEntryPos);
                }
                else    /* must have ptr2->haspos */
                {
                    int         addlen = add_pos(in2, ptr2, out, ptr, maxpos);

                    if (addlen == 0)
                        ptr->haspos = 0;
                    else
                    {
                        dataoff = SHORTALIGN(dataoff);
                        dataoff += addlen * sizeof(WordEntryPos) + sizeof(uint16);
                    }
                }
            }

            ptr++;
            ptr1++;
            ptr2++;
            i1--;
            i2--;
        }
    }

    while (i1)
    {
        ptr->haspos = ptr1->haspos;
        ptr->len = ptr1->len;
        memcpy(data + dataoff, data1 + ptr1->pos, ptr1->len);
        ptr->pos = dataoff;
        dataoff += ptr1->len;
        if (ptr->haspos)
        {
            dataoff = SHORTALIGN(dataoff);
            memcpy(data + dataoff, _POSVECPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
            dataoff += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
        }

        ptr++;
        ptr1++;
        i1--;
    }

    while (i2)
    {
        ptr->haspos = ptr2->haspos;
        ptr->len = ptr2->len;
        memcpy(data + dataoff, data2 + ptr2->pos, ptr2->len);
        ptr->pos = dataoff;
        dataoff += ptr2->len;
        if (ptr->haspos)
        {
            int         addlen = add_pos(in2, ptr2, out, ptr, maxpos);

            if (addlen == 0)
                ptr->haspos = 0;
            else
            {
                dataoff = SHORTALIGN(dataoff);
                dataoff += addlen * sizeof(WordEntryPos) + sizeof(uint16);
            }
        }

        ptr++;
        ptr2++;
        i2--;
    }

    /*
     * Instead of checking each offset individually, we check for overflow of
     * pos fields once at the end.
     */
    if (dataoff > MAXSTRPOS)
        ereport(ERROR,
                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                 errmsg("string is too long for tsvector (%d bytes, max %d bytes)", dataoff, MAXSTRPOS)));

    /*
     * Adjust sizes (asserting that we didn't overrun the original estimates)
     * and collapse out any unused array entries.
     */
    output_size = ptr - ARRPTR(out);
    Assert(output_size <= out->size);
    out->size = output_size;
    if (data != STRPTR(out))
        memmove(STRPTR(out), data, dataoff);
    output_bytes = CALCDATASIZE(out->size, dataoff);
    Assert(output_bytes <= VARSIZE(out));
    SET_VARSIZE(out, output_bytes);

    PG_FREE_IF_COPY(in1, 0);
    PG_FREE_IF_COPY(in2, 1);
    PG_RETURN_POINTER(out);
}

Datum tsvector_eq ( PG_FUNCTION_ARGS   ) 
Datum tsvector_ge ( PG_FUNCTION_ARGS   ) 
Datum tsvector_gt ( PG_FUNCTION_ARGS   ) 
Datum tsvector_le ( PG_FUNCTION_ARGS   ) 
Datum tsvector_length ( PG_FUNCTION_ARGS   ) 

Definition at line 221 of file tsvector_op.c.

References PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, PG_RETURN_INT32, and TSVectorData::size.

{
    TSVector    in = PG_GETARG_TSVECTOR(0);
    int32       ret = in->size;

    PG_FREE_IF_COPY(in, 0);
    PG_RETURN_INT32(ret);
}

Datum tsvector_lt ( PG_FUNCTION_ARGS   ) 
Datum tsvector_ne ( PG_FUNCTION_ARGS   ) 
Datum tsvector_setweight ( PG_FUNCTION_ARGS   ) 

Definition at line 231 of file tsvector_op.c.

References ARRPTR, elog, ERROR, i, palloc(), PG_FREE_IF_COPY, PG_GETARG_CHAR, PG_GETARG_TSVECTOR, PG_RETURN_POINTER, POSDATALEN, POSDATAPTR, TSVectorData::size, VARSIZE, and WEP_SETWEIGHT.

{
    TSVector    in = PG_GETARG_TSVECTOR(0);
    char        cw = PG_GETARG_CHAR(1);
    TSVector    out;
    int         i,
                j;
    WordEntry  *entry;
    WordEntryPos *p;
    int         w = 0;

    switch (cw)
    {
        case 'A':
        case 'a':
            w = 3;
            break;
        case 'B':
        case 'b':
            w = 2;
            break;
        case 'C':
        case 'c':
            w = 1;
            break;
        case 'D':
        case 'd':
            w = 0;
            break;
        default:
            /* internal error */
            elog(ERROR, "unrecognized weight: %d", cw);
    }

    out = (TSVector) palloc(VARSIZE(in));
    memcpy(out, in, VARSIZE(in));
    entry = ARRPTR(out);
    i = out->size;
    while (i--)
    {
        if ((j = POSDATALEN(out, entry)) != 0)
        {
            p = POSDATAPTR(out, entry);
            while (j--)
            {
                WEP_SETWEIGHT(*p, w);
                p++;
            }
        }
        entry++;
    }

    PG_FREE_IF_COPY(in, 0);
    PG_RETURN_POINTER(out);
}

Datum tsvector_strip ( PG_FUNCTION_ARGS   ) 

Definition at line 188 of file tsvector_op.c.

References ARRPTR, CALCDATASIZE, cur, i, WordEntry::len, palloc0(), PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, PG_RETURN_POINTER, SET_VARSIZE, TSVectorData::size, and STRPTR.

{
    TSVector    in = PG_GETARG_TSVECTOR(0);
    TSVector    out;
    int         i,
                len = 0;
    WordEntry  *arrin = ARRPTR(in),
               *arrout;
    char       *cur;

    for (i = 0; i < in->size; i++)
        len += arrin[i].len;

    len = CALCDATASIZE(in->size, len);
    out = (TSVector) palloc0(len);
    SET_VARSIZE(out, len);
    out->size = in->size;
    arrout = ARRPTR(out);
    cur = STRPTR(out);
    for (i = 0; i < in->size; i++)
    {
        memcpy(cur, STRPTR(in) + arrin[i].pos, arrin[i].len);
        arrout[i].haspos = 0;
        arrout[i].len = arrin[i].len;
        arrout[i].pos = cur - STRPTR(out);
        cur += arrout[i].len;
    }

    PG_FREE_IF_COPY(in, 0);
    PG_RETURN_POINTER(out);
}

Datum tsvector_update_trigger_bycolumn ( PG_FUNCTION_ARGS   ) 

Definition at line 1305 of file tsvector_op.c.

References tsvector_update_trigger().

{
    return tsvector_update_trigger(fcinfo, true);
}

Datum tsvector_update_trigger_byid ( PG_FUNCTION_ARGS   ) 

Definition at line 1299 of file tsvector_op.c.

References tsvector_update_trigger().

Referenced by tsa_tsearch2().

{
    return tsvector_update_trigger(fcinfo, false);
}

Datum tsvectorin ( PG_FUNCTION_ARGS   ) 

Definition at line 175 of file tsvector.c.

References ARRPTR, Assert, buf, CALCDATASIZE, close_tsvector_parser(), cur, elog, WordEntryIN::entry, ereport, errcode(), errmsg(), ERROR, gettoken_tsvector(), WordEntry::haspos, i, init_tsvector_parser(), WordEntry::len, MAXSTRLEN, MAXSTRPOS, NULL, palloc(), palloc0(), pfree(), PG_GETARG_CSTRING, PG_RETURN_TSVECTOR, WordEntryIN::pos, WordEntry::pos, WordEntryIN::poslen, repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, tmpbuf, and uniqueentry().

{
    char       *buf = PG_GETARG_CSTRING(0);
    TSVectorParseState state;
    WordEntryIN *arr;
    int         totallen;
    int         arrlen;         /* allocated size of arr */
    WordEntry  *inarr;
    int         len = 0;
    TSVector    in;
    int         i;
    char       *token;
    int         toklen;
    WordEntryPos *pos;
    int         poslen;
    char       *strbuf;
    int         stroff;

    /*
     * Tokens are appended to tmpbuf, cur is a pointer to the end of used
     * space in tmpbuf.
     */
    char       *tmpbuf;
    char       *cur;
    int         buflen = 256;   /* allocated size of tmpbuf */

    state = init_tsvector_parser(buf, false, false);

    arrlen = 64;
    arr = (WordEntryIN *) palloc(sizeof(WordEntryIN) * arrlen);
    cur = tmpbuf = (char *) palloc(buflen);

    while (gettoken_tsvector(state, &token, &toklen, &pos, &poslen, NULL))
    {
        if (toklen >= MAXSTRLEN)
            ereport(ERROR,
                    (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                     errmsg("word is too long (%ld bytes, max %ld bytes)",
                            (long) toklen,
                            (long) (MAXSTRLEN - 1))));

        if (cur - tmpbuf > MAXSTRPOS)
            ereport(ERROR,
                    (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                     errmsg("string is too long for tsvector (%ld bytes, max %ld bytes)",
                            (long) (cur - tmpbuf), (long) MAXSTRPOS)));

        /*
         * Enlarge buffers if needed
         */
        if (len >= arrlen)
        {
            arrlen *= 2;
            arr = (WordEntryIN *)
                repalloc((void *) arr, sizeof(WordEntryIN) * arrlen);
        }
        while ((cur - tmpbuf) + toklen >= buflen)
        {
            int         dist = cur - tmpbuf;

            buflen *= 2;
            tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
            cur = tmpbuf + dist;
        }
        arr[len].entry.len = toklen;
        arr[len].entry.pos = cur - tmpbuf;
        memcpy((void *) cur, (void *) token, toklen);
        cur += toklen;

        if (poslen != 0)
        {
            arr[len].entry.haspos = 1;
            arr[len].pos = pos;
            arr[len].poslen = poslen;
        }
        else
        {
            arr[len].entry.haspos = 0;
            arr[len].pos = NULL;
            arr[len].poslen = 0;
        }
        len++;
    }

    close_tsvector_parser(state);

    if (len > 0)
        len = uniqueentry(arr, len, tmpbuf, &buflen);
    else
        buflen = 0;

    if (buflen > MAXSTRPOS)
        ereport(ERROR,
                (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
                 errmsg("string is too long for tsvector (%d bytes, max %d bytes)", buflen, MAXSTRPOS)));

    totallen = CALCDATASIZE(len, buflen);
    in = (TSVector) palloc0(totallen);
    SET_VARSIZE(in, totallen);
    in->size = len;
    inarr = ARRPTR(in);
    strbuf = STRPTR(in);
    stroff = 0;
    for (i = 0; i < len; i++)
    {
        memcpy(strbuf + stroff, &tmpbuf[arr[i].entry.pos], arr[i].entry.len);
        arr[i].entry.pos = stroff;
        stroff += arr[i].entry.len;
        if (arr[i].entry.haspos)
        {
            if (arr[i].poslen > 0xFFFF)
                elog(ERROR, "positions array too long");

            /* Copy number of positions */
            stroff = SHORTALIGN(stroff);
            *(uint16 *) (strbuf + stroff) = (uint16) arr[i].poslen;
            stroff += sizeof(uint16);

            /* Copy positions */
            memcpy(strbuf + stroff, arr[i].pos, arr[i].poslen * sizeof(WordEntryPos));
            stroff += arr[i].poslen * sizeof(WordEntryPos);

            pfree(arr[i].pos);
        }
        inarr[i] = arr[i].entry;
    }

    Assert((strbuf + stroff - (char *) in) == totallen);

    PG_RETURN_TSVECTOR(in);
}

Datum tsvectorout ( PG_FUNCTION_ARGS   ) 

Definition at line 308 of file tsvector.c.

References ARRPTR, i, WordEntry::len, palloc(), pg_database_encoding_max_length(), PG_FREE_IF_COPY, PG_GETARG_TSVECTOR, pg_mblen(), PG_RETURN_CSTRING, WordEntry::pos, POSDATALEN, POSDATAPTR, TSVectorData::size, STRPTR, t_iseq, WEP_GETPOS, and WEP_GETWEIGHT.

{
    TSVector    out = PG_GETARG_TSVECTOR(0);
    char       *outbuf;
    int32       i,
                lenbuf = 0,
                pp;
    WordEntry  *ptr = ARRPTR(out);
    char       *curbegin,
               *curin,
               *curout;

    lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
    for (i = 0; i < out->size; i++)
    {
        lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ;
        if (ptr[i].haspos)
            lenbuf += 1 /* : */ + 7 /* int2 + , + weight */ * POSDATALEN(out, &(ptr[i]));
    }

    curout = outbuf = (char *) palloc(lenbuf);
    for (i = 0; i < out->size; i++)
    {
        curbegin = curin = STRPTR(out) + ptr->pos;
        if (i != 0)
            *curout++ = ' ';
        *curout++ = '\'';
        while (curin - curbegin < ptr->len)
        {
            int         len = pg_mblen(curin);

            if (t_iseq(curin, '\''))
                *curout++ = '\'';
            else if (t_iseq(curin, '\\'))
                *curout++ = '\\';

            while (len--)
                *curout++ = *curin++;
        }

        *curout++ = '\'';
        if ((pp = POSDATALEN(out, ptr)) != 0)
        {
            WordEntryPos *wptr;

            *curout++ = ':';
            wptr = POSDATAPTR(out, ptr);
            while (pp)
            {
                curout += sprintf(curout, "%d", WEP_GETPOS(*wptr));
                switch (WEP_GETWEIGHT(*wptr))
                {
                    case 3:
                        *curout++ = 'A';
                        break;
                    case 2:
                        *curout++ = 'B';
                        break;
                    case 1:
                        *curout++ = 'C';
                        break;
                    case 0:
                    default:
                        break;
                }

                if (pp > 1)
                    *curout++ = ',';
                pp--;
                wptr++;
            }
        }
        ptr++;
    }

    *curout = '\0';
    PG_FREE_IF_COPY(out, 0);
    PG_RETURN_CSTRING(outbuf);
}

Datum tsvectorrecv ( PG_FUNCTION_ARGS   ) 

Definition at line 440 of file tsvector.c.

References ARRPTR, buf, compareentry(), DATAHDRSIZE, elog, TSVectorData::entries, ERROR, WordEntry::haspos, i, WordEntry::len, MaxAllocSize, MAXNUMPOS, MAXSTRLEN, MAXSTRPOS, palloc0(), PG_GETARG_POINTER, PG_RETURN_TSVECTOR, WordEntry::pos, POSDATAPTR, pq_getmsgint(), pq_getmsgstring(), qsort_arg(), repalloc(), SET_VARSIZE, SHORTALIGN, TSVectorData::size, STRPTR, WEP_GETPOS, and WordEntryCMP().

{
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    TSVector    vec;
    int         i;
    int32       nentries;
    int         datalen;        /* number of bytes used in the variable size
                                 * area after fixed size TSVector header and
                                 * WordEntries */
    Size        hdrlen;
    Size        len;            /* allocated size of vec */
    bool        needSort = false;

    nentries = pq_getmsgint(buf, sizeof(int32));
    if (nentries < 0 || nentries > (MaxAllocSize / sizeof(WordEntry)))
        elog(ERROR, "invalid size of tsvector");

    hdrlen = DATAHDRSIZE + sizeof(WordEntry) * nentries;

    len = hdrlen * 2;           /* times two to make room for lexemes */
    vec = (TSVector) palloc0(len);
    vec->size = nentries;

    datalen = 0;
    for (i = 0; i < nentries; i++)
    {
        const char *lexeme;
        uint16      npos;
        size_t      lex_len;

        lexeme = pq_getmsgstring(buf);
        npos = (uint16) pq_getmsgint(buf, sizeof(uint16));

        /* sanity checks */

        lex_len = strlen(lexeme);
        if (lex_len > MAXSTRLEN)
            elog(ERROR, "invalid tsvector: lexeme too long");

        if (datalen > MAXSTRPOS)
            elog(ERROR, "invalid tsvector: maximum total lexeme length exceeded");

        if (npos > MAXNUMPOS)
            elog(ERROR, "unexpected number of tsvector positions");

        /*
         * Looks valid. Fill the WordEntry struct, and copy lexeme.
         *
         * But make sure the buffer is large enough first.
         */
        while (hdrlen + SHORTALIGN(datalen + lex_len) +
               (npos + 1) * sizeof(WordEntryPos) >= len)
        {
            len *= 2;
            vec = (TSVector) repalloc(vec, len);
        }

        vec->entries[i].haspos = (npos > 0) ? 1 : 0;
        vec->entries[i].len = lex_len;
        vec->entries[i].pos = datalen;

        memcpy(STRPTR(vec) + datalen, lexeme, lex_len);

        datalen += lex_len;

        if (i > 0 && WordEntryCMP(&vec->entries[i],
                                  &vec->entries[i - 1],
                                  STRPTR(vec)) <= 0)
            needSort = true;

        /* Receive positions */
        if (npos > 0)
        {
            uint16      j;
            WordEntryPos *wepptr;

            /*
             * Pad to 2-byte alignment if necessary. Though we used palloc0
             * for the initial allocation, subsequent repalloc'd memory areas
             * are not initialized to zero.
             */
            if (datalen != SHORTALIGN(datalen))
            {
                *(STRPTR(vec) + datalen) = '\0';
                datalen = SHORTALIGN(datalen);
            }

            memcpy(STRPTR(vec) + datalen, &npos, sizeof(uint16));

            wepptr = POSDATAPTR(vec, &vec->entries[i]);
            for (j = 0; j < npos; j++)
            {
                wepptr[j] = (WordEntryPos) pq_getmsgint(buf, sizeof(WordEntryPos));
                if (j > 0 && WEP_GETPOS(wepptr[j]) <= WEP_GETPOS(wepptr[j - 1]))
                    elog(ERROR, "position information is misordered");
            }

            datalen += (npos + 1) * sizeof(WordEntry);
        }
    }

    SET_VARSIZE(vec, hdrlen + datalen);

    if (needSort)
        qsort_arg((void *) ARRPTR(vec), vec->size, sizeof(WordEntry),
                  compareentry, (void *) STRPTR(vec));

    PG_RETURN_TSVECTOR(vec);
}

Datum tsvectorsend ( PG_FUNCTION_ARGS   ) 

Definition at line 401 of file tsvector.c.

References ARRPTR, buf, i, WordEntry::len, PG_GETARG_TSVECTOR, PG_RETURN_BYTEA_P, WordEntry::pos, POSDATALEN, POSDATAPTR, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendint(), pq_sendtext(), TSVectorData::size, and STRPTR.

{
    TSVector    vec = PG_GETARG_TSVECTOR(0);
    StringInfoData buf;
    int         i,
                j;
    WordEntry  *weptr = ARRPTR(vec);

    pq_begintypsend(&buf);

    pq_sendint(&buf, vec->size, sizeof(int32));
    for (i = 0; i < vec->size; i++)
    {
        uint16      npos;

        /*
         * the strings in the TSVector array are not null-terminated, so we
         * have to send the null-terminator separately
         */
        pq_sendtext(&buf, STRPTR(vec) + weptr->pos, weptr->len);
        pq_sendbyte(&buf, '\0');

        npos = POSDATALEN(vec, weptr);
        pq_sendint(&buf, npos, sizeof(uint16));

        if (npos > 0)
        {
            WordEntryPos *wepptr = POSDATAPTR(vec, weptr);

            for (j = 0; j < npos; j++)
                pq_sendint(&buf, wepptr[j], sizeof(WordEntryPos));
        }
        weptr++;
    }

    PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}