]> granicus.if.org Git - postgresql/blob - contrib/test_parser/test_parser.c
da4f9be7810d269e79f6aed4f5eeaa00ac988a54
[postgresql] / contrib / test_parser / test_parser.c
1 /*-------------------------------------------------------------------------
2  *
3  * test_parser.c
4  *        Simple example of a text search parser
5  *
6  * Copyright (c) 2007-2010, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *        $PostgreSQL: pgsql/contrib/test_parser/test_parser.c,v 1.7 2010/01/02 16:57:32 momjian Exp $
10  *
11  *-------------------------------------------------------------------------
12  */
13 #include "postgres.h"
14
15 #include "fmgr.h"
16
17 PG_MODULE_MAGIC;
18
19
20 /*
21  * types
22  */
23
24 /* self-defined type */
25 typedef struct
26 {
27         char       *buffer;                     /* text to parse */
28         int                     len;                    /* length of the text in buffer */
29         int                     pos;                    /* position of the parser */
30 } ParserState;
31
32 /* copy-paste from wparser.h of tsearch2 */
33 typedef struct
34 {
35         int                     lexid;
36         char       *alias;
37         char       *descr;
38 } LexDescr;
39
40 /*
41  * prototypes
42  */
43 PG_FUNCTION_INFO_V1(testprs_start);
44 Datum           testprs_start(PG_FUNCTION_ARGS);
45
46 PG_FUNCTION_INFO_V1(testprs_getlexeme);
47 Datum           testprs_getlexeme(PG_FUNCTION_ARGS);
48
49 PG_FUNCTION_INFO_V1(testprs_end);
50 Datum           testprs_end(PG_FUNCTION_ARGS);
51
52 PG_FUNCTION_INFO_V1(testprs_lextype);
53 Datum           testprs_lextype(PG_FUNCTION_ARGS);
54
55 /*
56  * functions
57  */
58 Datum
59 testprs_start(PG_FUNCTION_ARGS)
60 {
61         ParserState *pst = (ParserState *) palloc0(sizeof(ParserState));
62
63         pst->buffer = (char *) PG_GETARG_POINTER(0);
64         pst->len = PG_GETARG_INT32(1);
65         pst->pos = 0;
66
67         PG_RETURN_POINTER(pst);
68 }
69
70 Datum
71 testprs_getlexeme(PG_FUNCTION_ARGS)
72 {
73         ParserState *pst = (ParserState *) PG_GETARG_POINTER(0);
74         char      **t = (char **) PG_GETARG_POINTER(1);
75         int                *tlen = (int *) PG_GETARG_POINTER(2);
76         int                     type;
77
78         *tlen = pst->pos;
79         *t = pst->buffer + pst->pos;
80
81         if ((pst->buffer)[pst->pos] == ' ')
82         {
83                 /* blank type */
84                 type = 12;
85                 /* go to the next non-white-space character */
86                 while ((pst->buffer)[pst->pos] == ' ' &&
87                            pst->pos < pst->len)
88                         (pst->pos)++;
89         }
90         else
91         {
92                 /* word type */
93                 type = 3;
94                 /* go to the next white-space character */
95                 while ((pst->buffer)[pst->pos] != ' ' &&
96                            pst->pos < pst->len)
97                         (pst->pos)++;
98         }
99
100         *tlen = pst->pos - *tlen;
101
102         /* we are finished if (*tlen == 0) */
103         if (*tlen == 0)
104                 type = 0;
105
106         PG_RETURN_INT32(type);
107 }
108
109 Datum
110 testprs_end(PG_FUNCTION_ARGS)
111 {
112         ParserState *pst = (ParserState *) PG_GETARG_POINTER(0);
113
114         pfree(pst);
115         PG_RETURN_VOID();
116 }
117
118 Datum
119 testprs_lextype(PG_FUNCTION_ARGS)
120 {
121         /*
122          * Remarks: - we have to return the blanks for headline reason - we use
123          * the same lexids like Teodor in the default word parser; in this way we
124          * can reuse the headline function of the default word parser.
125          */
126         LexDescr   *descr = (LexDescr *) palloc(sizeof(LexDescr) * (2 + 1));
127
128         /* there are only two types in this parser */
129         descr[0].lexid = 3;
130         descr[0].alias = pstrdup("word");
131         descr[0].descr = pstrdup("Word");
132         descr[1].lexid = 12;
133         descr[1].alias = pstrdup("blank");
134         descr[1].descr = pstrdup("Space symbols");
135         descr[2].lexid = 0;
136
137         PG_RETURN_POINTER(descr);
138 }