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