Line data Source code
1 : %{
2 : /*-------------------------------------------------------------------------
3 : *
4 : * repl_scanner.l
5 : * a lexical scanner for the replication commands
6 : *
7 : * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8 : * Portions Copyright (c) 1994, Regents of the University of California
9 : *
10 : *
11 : * IDENTIFICATION
12 : * src/backend/replication/repl_scanner.l
13 : *
14 : *-------------------------------------------------------------------------
15 : */
16 : #include "postgres.h"
17 :
18 : #include "utils/builtins.h"
19 : #include "parser/scansup.h"
20 :
21 : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
22 : #undef fprintf
23 : #define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
24 :
25 : static void
26 0 : fprintf_to_ereport(const char *fmt, const char *msg)
27 : {
28 0 : ereport(ERROR, (errmsg_internal("%s", msg)));
29 : }
30 :
31 : /* Handle to the buffer that the lexer uses internally */
32 : static YY_BUFFER_STATE scanbufhandle;
33 :
34 : static StringInfoData litbuf;
35 :
36 : static void startlit(void);
37 : static char *litbufdup(void);
38 : static void addlit(char *ytext, int yleng);
39 : static void addlitchar(unsigned char ychar);
40 :
41 : /* LCOV_EXCL_START */
42 :
43 : %}
44 :
45 : %option 8bit
46 : %option never-interactive
47 : %option nodefault
48 : %option noinput
49 : %option nounput
50 : %option noyywrap
51 : %option warn
52 : %option prefix="replication_yy"
53 :
54 : %x xq xd
55 :
56 : /* Extended quote
57 : * xqdouble implements embedded quote, ''''
58 : */
59 : xqstart {quote}
60 : xqdouble {quote}{quote}
61 : xqinside [^']+
62 :
63 : /* Double quote
64 : * Allows embedded spaces and other special characters into identifiers.
65 : */
66 : dquote \"
67 : xdstart {dquote}
68 : xdstop {dquote}
69 : xddouble {dquote}{dquote}
70 : xdinside [^"]+
71 :
72 : digit [0-9]+
73 : hexdigit [0-9A-Za-z]+
74 :
75 : quote '
76 : quotestop {quote}
77 :
78 : ident_start [A-Za-z\200-\377_]
79 : ident_cont [A-Za-z\200-\377_0-9\$]
80 :
81 : identifier {ident_start}{ident_cont}*
82 :
83 : %%
84 :
85 : BASE_BACKUP { return K_BASE_BACKUP; }
86 : FAST { return K_FAST; }
87 : IDENTIFY_SYSTEM { return K_IDENTIFY_SYSTEM; }
88 : SHOW { return K_SHOW; }
89 : LABEL { return K_LABEL; }
90 : NOWAIT { return K_NOWAIT; }
91 : PROGRESS { return K_PROGRESS; }
92 : MAX_RATE { return K_MAX_RATE; }
93 : WAL { return K_WAL; }
94 : TABLESPACE_MAP { return K_TABLESPACE_MAP; }
95 : NOVERIFY_CHECKSUMS { return K_NOVERIFY_CHECKSUMS; }
96 : TIMELINE { return K_TIMELINE; }
97 : START_REPLICATION { return K_START_REPLICATION; }
98 : CREATE_REPLICATION_SLOT { return K_CREATE_REPLICATION_SLOT; }
99 : DROP_REPLICATION_SLOT { return K_DROP_REPLICATION_SLOT; }
100 : TIMELINE_HISTORY { return K_TIMELINE_HISTORY; }
101 : PHYSICAL { return K_PHYSICAL; }
102 : RESERVE_WAL { return K_RESERVE_WAL; }
103 : LOGICAL { return K_LOGICAL; }
104 : SLOT { return K_SLOT; }
105 : TEMPORARY { return K_TEMPORARY; }
106 : EXPORT_SNAPSHOT { return K_EXPORT_SNAPSHOT; }
107 : NOEXPORT_SNAPSHOT { return K_NOEXPORT_SNAPSHOT; }
108 : USE_SNAPSHOT { return K_USE_SNAPSHOT; }
109 : WAIT { return K_WAIT; }
110 : MANIFEST { return K_MANIFEST; }
111 : MANIFEST_CHECKSUMS { return K_MANIFEST_CHECKSUMS; }
112 :
113 : "," { return ','; }
114 : ";" { return ';'; }
115 : "(" { return '('; }
116 : ")" { return ')'; }
117 :
118 : [\n] ;
119 : [\t] ;
120 : " " ;
121 :
122 : {digit}+ {
123 : yylval.uintval = strtoul(yytext, NULL, 10);
124 : return UCONST;
125 : }
126 :
127 : {hexdigit}+\/{hexdigit}+ {
128 : uint32 hi,
129 : lo;
130 : if (sscanf(yytext, "%X/%X", &hi, &lo) != 2)
131 : yyerror("invalid streaming start location");
132 : yylval.recptr = ((uint64) hi) << 32 | lo;
133 : return RECPTR;
134 : }
135 :
136 : {xqstart} {
137 : BEGIN(xq);
138 : startlit();
139 : }
140 :
141 : <xq>{quotestop} {
142 : yyless(1);
143 : BEGIN(INITIAL);
144 : yylval.str = litbufdup();
145 : return SCONST;
146 : }
147 :
148 : <xq>{xqdouble} {
149 : addlitchar('\'');
150 : }
151 :
152 : <xq>{xqinside} {
153 : addlit(yytext, yyleng);
154 : }
155 :
156 : {xdstart} {
157 : BEGIN(xd);
158 : startlit();
159 : }
160 :
161 : <xd>{xdstop} {
162 : int len;
163 : yyless(1);
164 : BEGIN(INITIAL);
165 : yylval.str = litbufdup();
166 : len = strlen(yylval.str);
167 : truncate_identifier(yylval.str, len, true);
168 : return IDENT;
169 : }
170 :
171 : <xd>{xdinside} {
172 : addlit(yytext, yyleng);
173 : }
174 :
175 : {identifier} {
176 : int len = strlen(yytext);
177 :
178 : yylval.str = downcase_truncate_identifier(yytext, len, true);
179 : return IDENT;
180 : }
181 :
182 : <xq,xd><<EOF>> { yyerror("unterminated quoted string"); }
183 :
184 :
185 : <<EOF>> {
186 : yyterminate();
187 : }
188 :
189 : . {
190 : return T_WORD;
191 : }
192 : %%
193 :
194 : /* LCOV_EXCL_STOP */
195 :
196 : static void
197 : startlit(void)
198 1838 : {
199 : initStringInfo(&litbuf);
200 1838 : }
201 1838 :
202 : static char *
203 : litbufdup(void)
204 1838 : {
205 : return litbuf.data;
206 1838 : }
207 :
208 : static void
209 : addlit(char *ytext, int yleng)
210 1424 : {
211 : appendBinaryStringInfo(&litbuf, ytext, yleng);
212 1424 : }
213 1424 :
214 : static void
215 : addlitchar(unsigned char ychar)
216 0 : {
217 : appendStringInfoChar(&litbuf, ychar);
218 0 : }
219 0 :
220 : void
221 : yyerror(const char *message)
222 0 : {
223 : ereport(ERROR,
224 0 : (errcode(ERRCODE_SYNTAX_ERROR),
225 : errmsg_internal("%s", message)));
226 : }
227 :
228 :
229 : void
230 : replication_scanner_init(const char *str)
231 1454 : {
232 : Size slen = strlen(str);
233 1454 : char *scanbuf;
234 :
235 : /*
236 : * Might be left over after ereport()
237 : */
238 : if (YY_CURRENT_BUFFER)
239 1454 : yy_delete_buffer(YY_CURRENT_BUFFER);
240 0 :
241 : /*
242 : * Make a scan buffer with special termination needed by flex.
243 : */
244 : scanbuf = (char *) palloc(slen + 2);
245 1454 : memcpy(scanbuf, str, slen);
246 1454 : scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
247 1454 : scanbufhandle = yy_scan_buffer(scanbuf, slen + 2);
248 1454 : }
249 1454 :
250 : void
251 : replication_scanner_finish(void)
252 1454 : {
253 : yy_delete_buffer(scanbufhandle);
254 1454 : scanbufhandle = NULL;
255 1454 : }
|