Age Owner TLA Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * 3 : * test_parser.c 4 : * Simple example of a text search parser 5 : * 6 : * Copyright (c) 2007-2023, 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 : 5655 tgl 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 5624 bruce 47 5 : testprs_start(PG_FUNCTION_ARGS) 48 : { 5655 tgl 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 5624 bruce 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); 4108 tgl 64 46 : int startpos = pst->pos; 65 : int type; 66 : 5624 bruce 67 46 : *t = pst->buffer + pst->pos; 68 : 4108 tgl 69 46 : if (pst->pos < pst->len && 70 41 : (pst->buffer)[pst->pos] == ' ') 71 : { 72 : /* blank type */ 5655 73 18 : type = 12; 74 : /* go to the next non-space character */ 4108 75 36 : while (pst->pos < pst->len && 76 36 : (pst->buffer)[pst->pos] == ' ') 5655 77 18 : (pst->pos)++; 78 : } 79 : else 80 : { 81 : /* word type */ 82 28 : type = 3; 83 : /* go to the next space character */ 4108 84 165 : while (pst->pos < pst->len && 85 155 : (pst->buffer)[pst->pos] != ' ') 5655 86 137 : (pst->pos)++; 87 : } 88 : 4108 89 46 : *tlen = pst->pos - startpos; 90 : 91 : /* we are finished if (*tlen == 0) */ 5655 92 46 : if (*tlen == 0) 5624 bruce 93 5 : type = 0; 94 : 5655 tgl 95 46 : PG_RETURN_INT32(type); 96 : } 97 : 98 : Datum 5624 bruce 99 5 : testprs_end(PG_FUNCTION_ARGS) 100 : { 5655 tgl 101 5 : ParserState *pst = (ParserState *) PG_GETARG_POINTER(0); 102 : 103 5 : pfree(pst); 104 5 : PG_RETURN_VOID(); 105 : } 106 : 107 : Datum 5624 bruce 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 */ 5655 tgl 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 : }