~ubuntu-branches/ubuntu/trusty/postgresql-8.4/trusty

« back to all changes in this revision

Viewing changes to src/backend/tsearch/ts_selfuncs.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-11 16:59:35 UTC
  • mfrom: (5.1.1 karmic)
  • Revision ID: james.westby@ubuntu.com-20090711165935-jfwin6gfrxf0gfsi
Tags: 8.4.0-2
* debian/libpq-dev.install: Ship catalog/genbki.h. (Closes: #536139)
* debian/rules: Drop --enable-cassert for final release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 *
8
8
 *
9
9
 * IDENTIFICATION
10
 
 *        $PostgreSQL: pgsql/src/backend/tsearch/ts_selfuncs.c,v 1.2 2009/01/01 17:23:48 momjian Exp $
 
10
 *        $PostgreSQL: pgsql/src/backend/tsearch/ts_selfuncs.c,v 1.4 2009/06/11 14:49:03 momjian Exp $
11
11
 *
12
12
 *-------------------------------------------------------------------------
13
13
 */
33
33
/* lookup table type for binary searching through MCELEMs */
34
34
typedef struct
35
35
{
36
 
        text   *element;
37
 
        float4  frequency;
 
36
        text       *element;
 
37
        float4          frequency;
38
38
} TextFreq;
39
39
 
40
40
/* type of keys for bsearch'ing through an array of TextFreqs */
41
41
typedef struct
42
42
{
43
 
        char    *lexeme;
44
 
        int             length;
 
43
        char       *lexeme;
 
44
        int                     length;
45
45
} LexemeKey;
46
46
 
47
47
static Selectivity tsquerysel(VariableStatData *vardata, Datum constval);
48
48
static Selectivity mcelem_tsquery_selec(TSQuery query,
49
 
                                                                                Datum *mcelem, int nmcelem,
50
 
                                                                                float4 *numbers, int nnumbers);
 
49
                                         Datum *mcelem, int nmcelem,
 
50
                                         float4 *numbers, int nnumbers);
51
51
static Selectivity tsquery_opr_selec(QueryItem *item, char *operand,
52
 
                                                                 TextFreq *lookup, int length, float4 minfreq);
 
52
                                  TextFreq *lookup, int length, float4 minfreq);
53
53
static int      compare_lexeme_textfreq(const void *e1, const void *e2);
54
54
 
55
55
 
63
63
tsmatchsel(PG_FUNCTION_ARGS)
64
64
{
65
65
        PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
 
66
 
66
67
#ifdef NOT_USED
67
68
        Oid                     operator = PG_GETARG_OID(1);
68
69
#endif
71
72
        VariableStatData vardata;
72
73
        Node       *other;
73
74
        bool            varonleft;
74
 
        Selectivity     selec;
 
75
        Selectivity selec;
75
76
 
76
77
        /*
77
78
         * If expression is not variable = something or something = variable, then
145
146
static Selectivity
146
147
tsquerysel(VariableStatData *vardata, Datum constval)
147
148
{
148
 
        Selectivity                     selec;
 
149
        Selectivity selec;
 
150
        TSQuery         query;
 
151
 
 
152
        /* The caller made sure the const is a TSQuery, so get it now */
 
153
        query = DatumGetTSQuery(constval);
 
154
 
 
155
        /* Empty query matches nothing */
 
156
        if (query->size == 0)
 
157
                return (Selectivity) 0.0;
149
158
 
150
159
        if (HeapTupleIsValid(vardata->statsTuple))
151
160
        {
152
 
                TSQuery                         query;
153
 
                Form_pg_statistic       stats;
154
 
                Datum                           *values;
155
 
                int                                     nvalues;
156
 
                float4                          *numbers;
157
 
                int                                     nnumbers;
158
 
 
159
 
                /* The caller made sure the const is a TSQuery, so get it now */
160
 
                query = DatumGetTSQuery(constval);
 
161
                Form_pg_statistic stats;
 
162
                Datum      *values;
 
163
                int                     nvalues;
 
164
                float4     *numbers;
 
165
                int                     nnumbers;
161
166
 
162
167
                stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple);
163
168
 
198
203
mcelem_tsquery_selec(TSQuery query, Datum *mcelem, int nmcelem,
199
204
                                         float4 *numbers, int nnumbers)
200
205
{
201
 
        float4                  minfreq;
202
 
        TextFreq                *lookup;
203
 
        Selectivity             selec;
204
 
        int                             i;
 
206
        float4          minfreq;
 
207
        TextFreq   *lookup;
 
208
        Selectivity selec;
 
209
        int                     i;
205
210
 
206
211
        /*
207
212
         * There should be two more Numbers than Values, because the last two
217
222
        for (i = 0; i < nmcelem; i++)
218
223
        {
219
224
                /*
220
 
                 * The text Datums came from an array, so it cannot be compressed
221
 
                 * or stored out-of-line -- it's safe to use VARSIZE_ANY*.
 
225
                 * The text Datums came from an array, so it cannot be compressed or
 
226
                 * stored out-of-line -- it's safe to use VARSIZE_ANY*.
222
227
                 */
223
228
                Assert(!VARATT_IS_COMPRESSED(mcelem[i]) && !VARATT_IS_EXTERNAL(mcelem[i]));
224
229
                lookup[i].element = (text *) DatumGetPointer(mcelem[i]);
242
247
/*
243
248
 * Traverse the tsquery in preorder, calculating selectivity as:
244
249
 *
245
 
 *   selec(left_oper) * selec(right_oper) in AND nodes,
246
 
 *
247
 
 *   selec(left_oper) + selec(right_oper) -
248
 
 *      selec(left_oper) * selec(right_oper) in OR nodes,
249
 
 *
250
 
 *   1 - select(oper) in NOT nodes
251
 
 *
252
 
 *   freq[val] in VAL nodes, if the value is in MCELEM
253
 
 *   min(freq[MCELEM]) / 2 in VAL nodes, if it is not
 
250
 *       selec(left_oper) * selec(right_oper) in AND nodes,
 
251
 *
 
252
 *       selec(left_oper) + selec(right_oper) -
 
253
 *              selec(left_oper) * selec(right_oper) in OR nodes,
 
254
 *
 
255
 *       1 - select(oper) in NOT nodes
 
256
 *
 
257
 *       freq[val] in VAL nodes, if the value is in MCELEM
 
258
 *       min(freq[MCELEM]) / 2 in VAL nodes, if it is not
254
259
 *
255
260
 *
256
261
 * The MCELEM array is already sorted (see ts_typanalyze.c), so we can use
261
266
                                  TextFreq *lookup, int length, float4 minfreq)
262
267
{
263
268
        LexemeKey       key;
264
 
        TextFreq        *searchres;
265
 
        Selectivity     selec, s1, s2;
 
269
        TextFreq   *searchres;
 
270
        Selectivity selec,
 
271
                                s1,
 
272
                                s2;
266
273
 
267
274
        /* since this function recurses, it could be driven to stack overflow */
268
275
        check_stack_depth();
303
310
        switch (item->operator.oper)
304
311
        {
305
312
                case OP_NOT:
306
 
                        selec =  1.0 - tsquery_opr_selec(item + 1, operand,
307
 
                                                                                         lookup, length, minfreq);
 
313
                        selec = 1.0 - tsquery_opr_selec(item + 1, operand,
 
314
                                                                                        lookup, length, minfreq);
308
315
                        break;
309
316
 
310
317
                case OP_AND:
311
318
                        s1 = tsquery_opr_selec(item + 1, operand,
312
 
                                                                         lookup, length, minfreq);
 
319
                                                                   lookup, length, minfreq);
313
320
                        s2 = tsquery_opr_selec(item + item->operator.left, operand,
314
321
                                                                   lookup, length, minfreq);
315
322
                        selec = s1 * s2;
344
351
static int
345
352
compare_lexeme_textfreq(const void *e1, const void *e2)
346
353
{
347
 
        const LexemeKey *key = (const LexemeKey *) e1;
348
 
        const TextFreq  *t = (const TextFreq *) e2;
349
 
        int                             len1,
350
 
                                        len2;
 
354
        const LexemeKey *key = (const LexemeKey *) e1;
 
355
        const TextFreq *t = (const TextFreq *) e2;
 
356
        int                     len1,
 
357
                                len2;
351
358
 
352
359
        len1 = key->length;
353
360
        len2 = VARSIZE_ANY_EXHDR(t->element);