PostgreSQL Source Code git master
Loading...
Searching...
No Matches
scan.l
Go to the documentation of this file.
1%top{
2/*-------------------------------------------------------------------------
3 *
4 * scan.l
5 * lexical scanner for PostgreSQL
6 *
7 * NOTE NOTE NOTE:
8 *
9 * The rules in this file must be kept in sync with src/fe_utils/psqlscan.l
10 * and src/interfaces/ecpg/preproc/pgc.l!
11 *
12 * The rules are designed so that the scanner never has to backtrack,
13 * in the sense that there is always a rule that can match the input
14 * consumed so far (the rule action may internally throw back some input
15 * with yyless(), however). As explained in the flex manual, this makes
16 * for a useful speed increase --- several percent faster when measuring
17 * raw parsing (Flex + Bison). The extra complexity is mostly in the rules
18 * for handling float numbers and continued string literals. If you change
19 * the lexical rules, verify that you haven't broken the no-backtrack
20 * property by running flex with the "-b" option and checking that the
21 * resulting "lex.backup" file says that no backing up is needed. (As of
22 * Postgres 9.2, this check is made automatically by the Makefile.)
23 *
24 *
25 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
26 * Portions Copyright (c) 1994, Regents of the University of California
27 *
28 * IDENTIFICATION
29 * src/backend/parser/scan.l
30 *
31 *-------------------------------------------------------------------------
32 */
33#include "postgres.h"
34
35#include <ctype.h>
36#include <unistd.h>
37
38#include "common/string.h"
39#include "gramparse.h"
40#include "nodes/miscnodes.h"
41#include "parser/parser.h" /* only needed for GUC variables */
42#include "parser/scansup.h"
43#include "port/pg_bitutils.h"
44#include "mb/pg_wchar.h"
45#include "utils/builtins.h"
46}
47
48%{
49
50/* LCOV_EXCL_START */
51
52/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
53#undef fprintf
54#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
55
56static void
57fprintf_to_ereport(const char *fmt, const char *msg)
58{
59 ereport(ERROR, (errmsg_internal("%s", msg)));
60}
61
62/*
63 * GUC variable. This is a DIRECT violation of the warning given at the
64 * head of gram.y, ie flex/bison code must not depend on any GUC variables;
65 * as such, changing its value can induce very unintuitive behavior.
66 * In practice, backslash_quote is not too awful since it only controls
67 * whether to throw an error: it cannot change non-error results.
68 */
70
71/*
72 * Constant data exported from this file. This array maps from the
73 * zero-based keyword numbers returned by ScanKeywordLookup to the
74 * Bison token numbers needed by gram.y. This is exported because
75 * callers need to pass it to scanner_init, if they are using the
76 * standard keyword list ScanKeywords.
77 */
78#define PG_KEYWORD(kwname, value, category, collabel) value,
79
81#include "parser/kwlist.h"
82};
83
84#undef PG_KEYWORD
85
86/*
87 * Set the type of YYSTYPE.
88 */
89#define YYSTYPE core_YYSTYPE
90
91/*
92 * Each call to yylex must set yylloc to the location of the found token
93 * (expressed as a byte offset from the start of the input text).
94 * When we parse a token that requires multiple lexer rules to process,
95 * this should be done in the first such rule, else yylloc will point
96 * into the middle of the token.
97 */
98#define SET_YYLLOC() (*(yylloc) = yytext - yyextra->scanbuf)
99
100/*
101 * Advance yylloc by the given number of bytes.
102 */
103#define ADVANCE_YYLLOC(delta) ( *(yylloc) += (delta) )
104
105/*
106 * Sometimes, we do want yylloc to point into the middle of a token; this is
107 * useful for instance to throw an error about an escape sequence within a
108 * string literal. But if we find no error there, we want to revert yylloc
109 * to the token start, so that that's the location reported to the parser.
110 * Use PUSH_YYLLOC/POP_YYLLOC to save/restore yylloc around such code.
111 * (Currently the implied "stack" is just one location, but someday we might
112 * need to nest these.)
113 */
114#define PUSH_YYLLOC() (yyextra->save_yylloc = *(yylloc))
115#define POP_YYLLOC() (*(yylloc) = yyextra->save_yylloc)
116
117#define startlit() ( yyextra->literallen = 0 )
118static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
119static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner);
120static char *litbufdup(core_yyscan_t yyscanner);
121static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner);
122static int process_integer_literal(const char *token, YYSTYPE *lval, int base);
123static void addunicode(char32_t c, yyscan_t yyscanner);
124
125#define yyerror(msg) scanner_yyerror(msg, yyscanner)
126
127#define lexer_errposition() scanner_errposition(*(yylloc), yyscanner)
128
uint16_t uint16
Definition c.h:617
void * yyscan_t
Definition cubedata.h:65
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
@ BACKSLASH_QUOTE_SAFE_ENCODING
Definition parser.h:52
char * c
static int fb(int x)
int YYSTYPE
static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
Definition scan.l:1309
static int process_integer_literal(const char *token, YYSTYPE *lval, int base)
Definition scan.l:1344
static char * litbufdup(core_yyscan_t yyscanner)
Definition scan.l:1328
static void fprintf_to_ereport(const char *fmt, const char *msg)
Definition scan.l:57
int backslash_quote
Definition scan.l:69
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
Definition scan.l:1293
static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner)
Definition scan.l:1380
static void addunicode(char32_t c, yyscan_t yyscanner)
Definition scan.l:1361
const uint16 ScanKeywordTokens[]
Definition scan.l:80
void * core_yyscan_t
Definition scanner.h:118
129%}
130
131%option reentrant
132%option bison-bridge
133%option bison-locations
134%option 8bit
135%option never-interactive
136%option nodefault
137%option noinput
138%option nounput
139%option noyywrap
140%option noyyalloc
141%option noyyrealloc
142%option noyyfree
143%option warn
144%option prefix="core_yy"
145%option extra-type="core_yy_extra_type *"
146
147/*
148 * OK, here is a short description of lex/flex rules behavior.
149 * The longest pattern which matches an input string is always chosen.
150 * For equal-length patterns, the first occurring in the rules list is chosen.
151 * INITIAL is the starting state, to which all non-conditional rules apply.
152 * Exclusive states change parsing rules while the state is active. When in
153 * an exclusive state, only those rules defined for that state apply.
154 *
155 * We use exclusive states for quoted strings, extended comments,
156 * and to eliminate parsing troubles for numeric strings.
157 * Exclusive states:
158 * <xb> bit string literal
159 * <xc> extended C-style comments
160 * <xd> delimited identifiers (double-quoted identifiers)
161 * <xh> hexadecimal byte string
162 * <xq> standard quoted strings
163 * <xqs> quote stop (detect continued strings)
164 * <xe> extended quoted strings (support backslash escape sequences)
165 * <xdolq> $foo$ quoted strings
166 * <xui> quoted identifier with Unicode escapes
167 * <xus> quoted string with Unicode escapes
168 * <xeu> Unicode surrogate pair in extended quoted string
169 *
170 * Remember to add an <<EOF>> case whenever you add a new exclusive state!
171 * The default one is probably not the right thing.
172 */
173
174%x xb
175%x xc
176%x xd
177%x xh
178%x xq
179%x xqs
180%x xe
181%x xdolq
182%x xui
183%x xus
184%x xeu
185
186/*
187 * In order to make the world safe for Windows and Mac clients as well as
188 * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n
189 * sequence will be seen as two successive newlines, but that doesn't cause
190 * any problems. Comments that start with -- and extend to the next
191 * newline are treated as equivalent to a single whitespace character.
192 *
193 * NOTE a fine point: if there is no newline following --, we will absorb
194 * everything to the end of the input as a comment. This is correct. Older
195 * versions of Postgres failed to recognize -- as a comment if the input
196 * did not end with a newline.
197 *
198 * non_newline_space tracks all the other space characters except newlines.
199 *
200 * XXX if you change the set of whitespace characters, fix scanner_isspace()
201 * to agree.
202 */
203
204space [ \t\n\r\f\v]
205non_newline_space [ \t\f\v]
206newline [\n\r]
207non_newline [^\n\r]
208
209comment ("--"{non_newline}*)
210
211whitespace ({space}+|{comment})
212
213/*
214 * SQL requires at least one newline in the whitespace separating
215 * string literals that are to be concatenated. Silly, but who are we
216 * to argue? Note that {whitespace_with_newline} should not have * after
217 * it, whereas {whitespace} should generally have a * after it...
218 */
219
220special_whitespace ({space}+|{comment}{newline})
221non_newline_whitespace ({non_newline_space}|{comment})
222whitespace_with_newline ({non_newline_whitespace}*{newline}{special_whitespace}*)
223
224quote '
225/* If we see {quote} then {quotecontinue}, the quoted string continues */
226quotecontinue {whitespace_with_newline}{quote}
227
228/*
229 * {quotecontinuefail} is needed to avoid lexer backup when we fail to match
230 * {quotecontinue}. It might seem that this could just be {whitespace}*,
231 * but if there's a dash after {whitespace_with_newline}, it must be consumed
232 * to see if there's another dash --- which would start a {comment} and thus
233 * allow continuation of the {quotecontinue} token.
234 */
235quotecontinuefail {whitespace}*"-"?
236
237/* Bit string
238 * It is tempting to scan the string for only those characters
239 * which are allowed. However, this leads to silently swallowed
240 * characters if illegal characters are included in the string.
241 * For example, if xbinside is [01] then B'ABCD' is interpreted
242 * as a zero-length string, and the ABCD' is lost!
243 * Better to pass the string forward and let the input routines
244 * validate the contents.
245 */
246xbstart [bB]{quote}
247xbinside [^']*
248
249/* Hexadecimal byte string */
250xhstart [xX]{quote}
251xhinside [^']*
252
253/* National character */
254xnstart [nN]{quote}
255
256/* Quoted string that allows backslash escapes */
257xestart [eE]{quote}
258xeinside [^\\']+
259xeescape [\\][^0-7]
260xeoctesc [\\][0-7]{1,3}
261xehexesc [\\]x[0-9A-Fa-f]{1,2}
262xeunicode [\\](u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})
263xeunicodefail [\\](u[0-9A-Fa-f]{0,3}|U[0-9A-Fa-f]{0,7})
264
265/* Extended quote
266 * xqdouble implements embedded quote, ''''
267 */
268xqstart {quote}
269xqdouble {quote}{quote}
270xqinside [^']+
271
272/* $foo$ style quotes ("dollar quoting")
273 * The quoted string starts with $foo$ where "foo" is an optional string
274 * in the form of an identifier, except that it may not contain "$",
275 * and extends to the first occurrence of an identical string.
276 * There is *no* processing of the quoted text.
277 *
278 * {dolqfailed} is an error rule to avoid scanner backup when {dolqdelim}
279 * fails to match its trailing "$".
280 */
281dolq_start [A-Za-z\200-\377_]
282dolq_cont [A-Za-z\200-\377_0-9]
283dolqdelim \$({dolq_start}{dolq_cont}*)?\$
284dolqfailed \${dolq_start}{dolq_cont}*
285dolqinside [^$]+
286
287/* Double quote
288 * Allows embedded spaces and other special characters into identifiers.
289 */
290dquote \"
291xdstart {dquote}
292xdstop {dquote}
293xddouble {dquote}{dquote}
294xdinside [^"]+
295
296/* Quoted identifier with Unicode escapes */
297xuistart [uU]&{dquote}
298
299/* Quoted string with Unicode escapes */
300xusstart [uU]&{quote}
301
302/* error rule to avoid backup */
303xufailed [uU]&
304
305
306/* C-style comments
307 *
308 * The "extended comment" syntax closely resembles allowable operator syntax.
309 * The tricky part here is to get lex to recognize a string starting with
310 * slash-star as a comment, when interpreting it as an operator would produce
311 * a longer match --- remember lex will prefer a longer match! Also, if we
312 * have something like plus-slash-star, lex will think this is a 3-character
313 * operator whereas we want to see it as a + operator and a comment start.
314 * The solution is two-fold:
315 * 1. append {op_chars}* to xcstart so that it matches as much text as
316 * {operator} would. Then the tie-breaker (first matching rule of same
317 * length) ensures xcstart wins. We put back the extra stuff with yyless()
318 * in case it contains a star-slash that should terminate the comment.
319 * 2. In the operator rule, check for slash-star within the operator, and
320 * if found throw it back with yyless(). This handles the plus-slash-star
321 * problem.
322 * Dash-dash comments have similar interactions with the operator rule.
323 */
324xcstart \/\*{op_chars}*
325xcstop \*+\/
326xcinside [^*/]+
327
328ident_start [A-Za-z\200-\377_]
329ident_cont [A-Za-z\200-\377_0-9\$]
330
331identifier {ident_start}{ident_cont}*
332
333/* Assorted special-case operators and operator-like tokens */
334typecast "::"
335dot_dot \.\.
336colon_equals ":="
337
338/*
339 * These operator-like tokens (unlike the above ones) also match the {operator}
340 * rule, which means that they might be overridden by a longer match if they
341 * are followed by a comment start or a + or - character. Accordingly, if you
342 * add to this list, you must also add corresponding code to the {operator}
343 * block to return the correct token in such cases. (This is not needed in
344 * psqlscan.l since the token value is ignored there.)
345 */
346equals_greater "=>"
347less_equals "<="
348greater_equals ">="
349less_greater "<>"
350not_equals "!="
351/* Note there is no need for left_arrow, since "<-" is not a single operator. */
352right_arrow "->"
353
354/*
355 * "self" is the set of chars that should be returned as single-character
356 * tokens. "op_chars" is the set of chars that can make up "Op" tokens,
357 * which can be one or more characters long (but if a single-char token
358 * appears in the "self" set, it is not to be returned as an Op). Note
359 * that the sets overlap, but each has some chars that are not in the other.
360 *
361 * If you change either set, adjust the character lists appearing in the
362 * rule for "operator"!
363 */
364self [,()\[\].;\:\|\+\-\*\/\%\^<>\=]
365op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%<>\=]
366operator {op_chars}+
367
368/*
369 * Numbers
370 *
371 * Unary minus is not part of a number here. Instead we pass it separately to
372 * the parser, and there it gets coerced via doNegate().
373 *
374 * {numericfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
375 *
376 * {realfail} is added to prevent the need for scanner
377 * backup when the {real} rule fails to match completely.
378 */
379decdigit [0-9]
380hexdigit [0-9A-Fa-f]
381octdigit [0-7]
382bindigit [0-1]
383
384decinteger {decdigit}(_?{decdigit})*
385hexinteger 0[xX](_?{hexdigit})+
386octinteger 0[oO](_?{octdigit})+
387bininteger 0[bB](_?{bindigit})+
388
389hexfail 0[xX]_?
390octfail 0[oO]_?
391binfail 0[bB]_?
392
393numeric (({decinteger}\.{decinteger}?)|(\.{decinteger}))
394numericfail {decinteger}\.\.
395
396real ({decinteger}|{numeric})[Ee][-+]?{decinteger}
397realfail ({decinteger}|{numeric})[Ee][-+]
398
399/* Positional parameters don't accept underscores. */
400param \${decdigit}+
401
402/*
403 * An identifier immediately following an integer literal is disallowed because
404 * in some cases it's ambiguous what is meant: for example, 0x1234 could be
405 * either a hexinteger or a decinteger "0" and an identifier "x1234". We can
406 * detect such problems by seeing if integer_junk matches a longer substring
407 * than any of the XXXinteger patterns (decinteger, hexinteger, octinteger,
408 * bininteger). One "junk" pattern is sufficient because
409 * {decinteger}{identifier} will match all the same strings we'd match with
410 * {hexinteger}{identifier} etc.
411 *
412 * Note that the rule for integer_junk must appear after the ones for
413 * XXXinteger to make this work correctly: 0x1234 will match both hexinteger
414 * and integer_junk, and we need hexinteger to be chosen in that case.
415 *
416 * Also disallow strings matched by numeric_junk, real_junk and param_junk
417 * for consistency.
418 */
419integer_junk {decinteger}{identifier}
420numeric_junk {numeric}{identifier}
421real_junk {real}{identifier}
422param_junk \${decdigit}+{identifier}
423
424other .
425
426/*
427 * Dollar quoted strings are totally opaque, and no escaping is done on them.
428 * Other quoted strings must allow some special characters such as single-quote
429 * and newline.
430 * Embedded single-quotes are implemented both in the SQL standard
431 * style of two adjacent single quotes "''" and in the Postgres/Java style
432 * of escaped-quote "\'".
433 * Other embedded escaped characters are matched explicitly and the leading
434 * backslash is dropped from the string.
435 * Note that xcstart must appear before operator, as explained above!
436 * Also whitespace (comment) must appear before operator.
437 */
438
440
441{whitespace} {
442 /* ignore */
443 }
444
445{xcstart} {
446 /* Set location in case of syntax error in comment */
447 SET_YYLLOC();
448 yyextra->xcdepth = 0;
449 BEGIN(xc);
450 /* Put back any characters past slash-star; see above */
451 yyless(2);
452 }
#define yyextra
Definition scan.l:1102
#define SET_YYLLOC()
Definition scan.l:98
453
454<xc>{
455{xcstart} {
456 (yyextra->xcdepth)++;
457 /* Put back any characters past slash-star; see above */
458 yyless(2);
459 }
460
461{xcstop} {
462 if (yyextra->xcdepth <= 0)
463 BEGIN(INITIAL);
464 else
465 (yyextra->xcdepth)--;
466 }
467
468{xcinside} {
469 /* ignore */
470 }
471
472{op_chars} {
473 /* ignore */
474 }
475
476\*+ {
477 /* ignore */
478 }
479
480<<EOF>> {
481 yyerror("unterminated /* comment");
482 }
#define yyerror(msg)
Definition scan.l:125
483} /* <xc> */
484
485{xbstart} {
486 /* Binary bit type.
487 * At some point we should simply pass the string
488 * forward to the parser and label it there.
489 * In the meantime, place a leading "b" on the string
490 * to mark it for the input routine as a binary string.
491 */
492 SET_YYLLOC();
493 BEGIN(xb);
494 startlit();
495 addlitchar('b', yyscanner);
496 }
#define startlit()
Definition scan.l:117
497<xh>{xhinside} |
498<xb>{xbinside} {
499 addlit(yytext, yyleng, yyscanner);
500 }
#define yyleng
Definition scan.l:1108
501<xb><<EOF>> { yyerror("unterminated bit string literal"); }
502
503{xhstart} {
504 /* Hexadecimal bit type.
505 * At some point we should simply pass the string
506 * forward to the parser and label it there.
507 * In the meantime, place a leading "x" on the string
508 * to mark it for the input routine as a hex string.
509 */
510 SET_YYLLOC();
511 BEGIN(xh);
512 startlit();
513 addlitchar('x', yyscanner);
514 }
515<xh><<EOF>> { yyerror("unterminated hexadecimal string literal"); }
516
517{xnstart} {
518 /* National character.
519 * We will pass this along as a normal character string,
520 * but preceded with an internally-generated "NCHAR".
521 */
522 int kwnum;
523
524 SET_YYLLOC();
525 yyless(1); /* eat only 'n' this time */
526
527 kwnum = ScanKeywordLookup("nchar",
528 yyextra->keywordlist);
529 if (kwnum >= 0)
530 {
531 yylval->keyword = GetScanKeyword(kwnum,
532 yyextra->keywordlist);
533 return yyextra->keyword_tokens[kwnum];
534 }
535 else
536 {
537 /* If NCHAR isn't a keyword, just return "n" */
538 yylval->str = pstrdup("n");
539 return IDENT;
540 }
541 }
int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)
Definition kwlookup.c:38
static const char * GetScanKeyword(int n, const ScanKeywordList *keywords)
Definition kwlookup.h:39
char * pstrdup(const char *in)
Definition mcxt.c:1781
542
543{xqstart} {
544 yyextra->saw_non_ascii = false;
545 SET_YYLLOC();
546 BEGIN(xq);
547 startlit();
548 }
549{xestart} {
550 yyextra->saw_non_ascii = false;
551 SET_YYLLOC();
552 BEGIN(xe);
553 startlit();
554 }
555{xusstart} {
556 SET_YYLLOC();
557 BEGIN(xus);
558 startlit();
559 }
560
561<xb,xh,xq,xe,xus>{quote} {
562 /*
563 * When we are scanning a quoted string and see an end
564 * quote, we must look ahead for a possible continuation.
565 * If we don't see one, we know the end quote was in fact
566 * the end of the string. To reduce the lexer table size,
567 * we use a single "xqs" state to do the lookahead for all
568 * types of strings.
569 */
570 yyextra->state_before_str_stop = YYSTATE;
571 BEGIN(xqs);
572 }
573<xqs>{quotecontinue} {
574 /*
575 * Found a quote continuation, so return to the in-quote
576 * state and continue scanning the literal. Nothing is
577 * added to the literal's contents.
578 */
579 BEGIN(yyextra->state_before_str_stop);
580 }
581<xqs>{quotecontinuefail} |
582<xqs>{other} |
583<xqs><<EOF>> {
584 /*
585 * Failed to see a quote continuation. Throw back
586 * everything after the end quote, and handle the string
587 * according to the state we were in previously.
588 */
589 yyless(0);
590 BEGIN(INITIAL);
591
592 switch (yyextra->state_before_str_stop)
593 {
594 case xb:
595 yylval->str = litbufdup(yyscanner);
596 return BCONST;
597 case xh:
598 yylval->str = litbufdup(yyscanner);
599 return XCONST;
600 case xq:
601 case xe:
602 /*
603 * Check that the data remains valid, if it might
604 * have been made invalid by unescaping any chars.
605 */
606 if (yyextra->saw_non_ascii)
607 pg_verifymbstr(yyextra->literalbuf,
608 yyextra->literallen,
609 false);
610 yylval->str = litbufdup(yyscanner);
611 return SCONST;
612 case xus:
613 yylval->str = litbufdup(yyscanner);
614 return USCONST;
615 default:
616 yyerror("unhandled previous state in xqs");
617 }
618 }
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition mbutils.c:1684
619
620<xq,xe,xus>{xqdouble} {
621 addlitchar('\'', yyscanner);
622 }
623<xq,xus>{xqinside} {
624 addlit(yytext, yyleng, yyscanner);
625 }
626<xe>{xeinside} {
627 addlit(yytext, yyleng, yyscanner);
628 }
629<xe>{xeunicode} {
630 char32_t c = strtoul(yytext + 2, NULL, 16);
631
632 /* Remember start of overall string token ... */
633 PUSH_YYLLOC();
634 /* ... and set the error cursor to point at this esc seq */
635 SET_YYLLOC();
636
638 {
639 yyextra->utf16_first_part = c;
640 BEGIN(xeu);
641 }
643 yyerror("invalid Unicode surrogate pair");
644 else
645 addunicode(c, yyscanner);
646
647 /* Restore yylloc to be start of string token */
648 POP_YYLLOC();
649 }
static bool is_utf16_surrogate_first(char32_t c)
Definition pg_wchar.h:525
static bool is_utf16_surrogate_second(char32_t c)
Definition pg_wchar.h:531
#define PUSH_YYLLOC()
Definition scan.l:114
#define POP_YYLLOC()
Definition scan.l:115
650<xeu>{xeunicode} {
651 char32_t c = strtoul(yytext + 2, NULL, 16);
652
653 /* Remember start of overall string token ... */
654 PUSH_YYLLOC();
655 /* ... and set the error cursor to point at this esc seq */
656 SET_YYLLOC();
657
659 yyerror("invalid Unicode surrogate pair");
660
661 c = surrogate_pair_to_codepoint(yyextra->utf16_first_part, c);
662
663 addunicode(c, yyscanner);
664
665 /* Restore yylloc to be start of string token */
666 POP_YYLLOC();
667
668 BEGIN(xe);
669 }
static char32_t surrogate_pair_to_codepoint(char16_t first, char16_t second)
Definition pg_wchar.h:537
670<xeu>. |
671<xeu>\n |
672<xeu><<EOF>> {
673 /* Set the error cursor to point at missing esc seq */
674 SET_YYLLOC();
675 yyerror("invalid Unicode surrogate pair");
676 }
677<xe,xeu>{xeunicodefail} {
678 /* Set the error cursor to point at malformed esc seq */
679 SET_YYLLOC();
682 errmsg("invalid Unicode escape"),
683 errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."),
685 }
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
static char * errmsg
#define lexer_errposition()
Definition scan.l:127
686<xe>{xeescape} {
687 if (yytext[1] == '\'')
688 {
689 if (yyextra->backslash_quote == BACKSLASH_QUOTE_OFF ||
690 (yyextra->backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&
694 errmsg("unsafe use of \\' in a string literal"),
695 errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),
697 }
699 yyscanner);
700 }
int pg_get_client_encoding(void)
Definition mbutils.c:345
@ BACKSLASH_QUOTE_OFF
Definition parser.h:50
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition pg_wchar.h:284
701<xe>{xeoctesc} {
702 unsigned char c = strtoul(yytext + 1, NULL, 8);
703
704 addlitchar(c, yyscanner);
705 if (c == '\0' || IS_HIGHBIT_SET(c))
706 yyextra->saw_non_ascii = true;
707 }
#define IS_HIGHBIT_SET(ch)
Definition c.h:1246
708<xe>{xehexesc} {
709 unsigned char c = strtoul(yytext + 2, NULL, 16);
710
711 addlitchar(c, yyscanner);
712 if (c == '\0' || IS_HIGHBIT_SET(c))
713 yyextra->saw_non_ascii = true;
714 }
715<xe>. {
716 /* This is only needed for \ just before EOF */
717 addlitchar(yytext[0], yyscanner);
718 }
719<xq,xe,xus><<EOF>> { yyerror("unterminated quoted string"); }
720
721{dolqdelim} {
722 SET_YYLLOC();
723 yyextra->dolqstart = pstrdup(yytext);
724 BEGIN(xdolq);
725 startlit();
726 }
727{dolqfailed} {
728 SET_YYLLOC();
729 /* throw back all but the initial "$" */
730 yyless(1);
731 /* and treat it as {other} */
732 return yytext[0];
733 }
734<xdolq>{dolqdelim} {
735 if (strcmp(yytext, yyextra->dolqstart) == 0)
736 {
737 pfree(yyextra->dolqstart);
738 yyextra->dolqstart = NULL;
739 BEGIN(INITIAL);
740 yylval->str = litbufdup(yyscanner);
741 return SCONST;
742 }
743 else
744 {
745 /*
746 * When we fail to match $...$ to dolqstart, transfer
747 * the $... part to the output, but put back the final
748 * $ for rescanning. Consider $delim$...$junk$delim$
749 */
750 addlit(yytext, yyleng - 1, yyscanner);
751 yyless(yyleng - 1);
752 }
753 }
void pfree(void *pointer)
Definition mcxt.c:1616
754<xdolq>{dolqinside} {
755 addlit(yytext, yyleng, yyscanner);
756 }
757<xdolq>{dolqfailed} {
758 addlit(yytext, yyleng, yyscanner);
759 }
760<xdolq>. {
761 /* This is only needed for $ inside the quoted text */
762 addlitchar(yytext[0], yyscanner);
763 }
764<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
765
766{xdstart} {
767 SET_YYLLOC();
768 BEGIN(xd);
769 startlit();
770 }
771{xuistart} {
772 SET_YYLLOC();
773 BEGIN(xui);
774 startlit();
775 }
776<xd>{xdstop} {
777 char *ident;
778
779 BEGIN(INITIAL);
780 if (yyextra->literallen == 0)
781 yyerror("zero-length delimited identifier");
782 ident = litbufdup(yyscanner);
783 if (yyextra->literallen >= NAMEDATALEN)
784 truncate_identifier(ident, yyextra->literallen, true);
785 yylval->str = ident;
786 return IDENT;
787 }
#define ident
#define NAMEDATALEN
void truncate_identifier(char *ident, int len, bool warn)
Definition scansup.c:81
788<xui>{dquote} {
789 BEGIN(INITIAL);
790 if (yyextra->literallen == 0)
791 yyerror("zero-length delimited identifier");
792 /* can't truncate till after we de-escape the ident */
793 yylval->str = litbufdup(yyscanner);
794 return UIDENT;
795 }
796<xd,xui>{xddouble} {
797 addlitchar('"', yyscanner);
798 }
799<xd,xui>{xdinside} {
800 addlit(yytext, yyleng, yyscanner);
801 }
802<xd,xui><<EOF>> { yyerror("unterminated quoted identifier"); }
803
804{xufailed} {
805 char *ident;
806
807 SET_YYLLOC();
808 /* throw back all but the initial u/U */
809 yyless(1);
810 /* and treat it as {identifier} */
812 yylval->str = ident;
813 return IDENT;
814 }
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition scansup.c:38
815
816{typecast} {
817 SET_YYLLOC();
818 return TYPECAST;
819 }
820
821{dot_dot} {
822 SET_YYLLOC();
823 return DOT_DOT;
824 }
825
826{colon_equals} {
827 SET_YYLLOC();
828 return COLON_EQUALS;
829 }
830
831{equals_greater} {
832 SET_YYLLOC();
833 return EQUALS_GREATER;
834 }
835
836{less_equals} {
837 SET_YYLLOC();
838 return LESS_EQUALS;
839 }
840
841{greater_equals} {
842 SET_YYLLOC();
843 return GREATER_EQUALS;
844 }
845
846{less_greater} {
847 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
848 SET_YYLLOC();
849 return NOT_EQUALS;
850 }
851
852{not_equals} {
853 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
854 SET_YYLLOC();
855 return NOT_EQUALS;
856 }
857
858{right_arrow} {
859 SET_YYLLOC();
860 return RIGHT_ARROW;
861 }
862
863{self} {
864 SET_YYLLOC();
865 return yytext[0];
866 }
867
868{operator} {
869 /*
870 * Check for embedded slash-star or dash-dash; those
871 * are comment starts, so operator must stop there.
872 * Note that slash-star or dash-dash at the first
873 * character will match a prior rule, not this one.
874 */
875 int nchars = yyleng;
876 char *slashstar = strstr(yytext, "/*");
877 char *dashdash = strstr(yytext, "--");
878
879 if (slashstar && dashdash)
880 {
881 /* if both appear, take the first one */
882 if (slashstar > dashdash)
884 }
885 else if (!slashstar)
887 if (slashstar)
888 nchars = slashstar - yytext;
889
890 /*
891 * For SQL compatibility, '+' and '-' cannot be the
892 * last char of a multi-char operator unless the operator
893 * contains chars that are not in SQL operators.
894 * The idea is to lex '=-' as two operators, but not
895 * to forbid operator names like '?-' that could not be
896 * sequences of SQL operators.
897 */
898 if (nchars > 1 &&
899 (yytext[nchars - 1] == '+' ||
900 yytext[nchars - 1] == '-'))
901 {
902 int ic;
903
904 for (ic = nchars - 2; ic >= 0; ic--)
905 {
906 char c = yytext[ic];
907 if (c == '~' || c == '!' || c == '@' ||
908 c == '#' || c == '^' || c == '&' ||
909 c == '|' || c == '`' || c == '?' ||
910 c == '%')
911 break;
912 }
913 if (ic < 0)
914 {
915 /*
916 * didn't find a qualifying character, so remove
917 * all trailing [+-]
918 */
919 do {
920 nchars--;
921 } while (nchars > 1 &&
922 (yytext[nchars - 1] == '+' ||
923 yytext[nchars - 1] == '-'));
924 }
925 }
926
927 SET_YYLLOC();
928
929 if (nchars < yyleng)
930 {
931 /* Strip the unwanted chars from the token */
932 yyless(nchars);
933 /*
934 * If what we have left is only one char, and it's
935 * one of the characters matching "self", then
936 * return it as a character token the same way
937 * that the "self" rule would have.
938 */
939 if (nchars == 1 &&
940 strchr(",()[].;:|+-*/%^<>=", yytext[0]))
941 return yytext[0];
942 /*
943 * Likewise, if what we have left is two chars, and
944 * those match the tokens ">=", "<=", "=>", "<>" or
945 * "!=", then we must return the appropriate token
946 * rather than the generic Op.
947 */
948 if (nchars == 2)
949 {
950 if (yytext[0] == '=' && yytext[1] == '>')
951 return EQUALS_GREATER;
952 if (yytext[0] == '>' && yytext[1] == '=')
953 return GREATER_EQUALS;
954 if (yytext[0] == '<' && yytext[1] == '=')
955 return LESS_EQUALS;
956 if (yytext[0] == '<' && yytext[1] == '>')
957 return NOT_EQUALS;
958 if (yytext[0] == '!' && yytext[1] == '=')
959 return NOT_EQUALS;
960 if (yytext[0] == '-' && yytext[1] == '>')
961 return RIGHT_ARROW;
962 }
963 }
964
965 /*
966 * Complain if operator is too long. Unlike the case
967 * for identifiers, we make this an error not a notice-
968 * and-truncate, because the odds are we are looking at
969 * a syntactic mistake anyway.
970 */
971 if (nchars >= NAMEDATALEN)
972 yyerror("operator too long");
973
974 yylval->str = pstrdup(yytext);
975 return Op;
976 }
977
978{param} {
980 int32 val;
981
982 SET_YYLLOC();
983 val = pg_strtoint32_safe(yytext + 1, (Node *) &escontext);
984 if (escontext.error_occurred)
985 yyerror("parameter number too large");
986 yylval->ival = val;
987 return PARAM;
988 }
int32_t int32
Definition c.h:614
long val
Definition informix.c:689
int32 pg_strtoint32_safe(const char *s, Node *escontext)
Definition numutils.c:388
Definition nodes.h:135
989{param_junk} {
990 SET_YYLLOC();
991 yyerror("trailing junk after parameter");
992 }
993
994{decinteger} {
995 SET_YYLLOC();
997 }
998{hexinteger} {
999 SET_YYLLOC();
1001 }
1002{octinteger} {
1003 SET_YYLLOC();
1005 }
1006{bininteger} {
1007 SET_YYLLOC();
1009 }
1010{hexfail} {
1011 SET_YYLLOC();
1012 yyerror("invalid hexadecimal integer");
1013 }
1014{octfail} {
1015 SET_YYLLOC();
1016 yyerror("invalid octal integer");
1017 }
1018{binfail} {
1019 SET_YYLLOC();
1020 yyerror("invalid binary integer");
1021 }
1022{numeric} {
1023 SET_YYLLOC();
1024 yylval->str = pstrdup(yytext);
1025 return FCONST;
1026 }
1027{numericfail} {
1028 /* throw back the .., and treat as integer */
1029 yyless(yyleng - 2);
1030 SET_YYLLOC();
1032 }
1033{real} {
1034 SET_YYLLOC();
1035 yylval->str = pstrdup(yytext);
1036 return FCONST;
1037 }
1038{realfail} {
1039 SET_YYLLOC();
1040 yyerror("trailing junk after numeric literal");
1041 }
1042{integer_junk} {
1043 SET_YYLLOC();
1044 yyerror("trailing junk after numeric literal");
1045 }
1046{numeric_junk} {
1047 SET_YYLLOC();
1048 yyerror("trailing junk after numeric literal");
1049 }
1050{real_junk} {
1051 SET_YYLLOC();
1052 yyerror("trailing junk after numeric literal");
1053 }
1054
1055
1056{identifier} {
1057 int kwnum;
1058 char *ident;
1059
1060 SET_YYLLOC();
1061
1062 /* Is it a keyword? */
1064 yyextra->keywordlist);
1065 if (kwnum >= 0)
1066 {
1067 yylval->keyword = GetScanKeyword(kwnum,
1068 yyextra->keywordlist);
1069 return yyextra->keyword_tokens[kwnum];
1070 }
1071
1072 /*
1073 * No. Convert the identifier to lower case, and truncate
1074 * if necessary.
1075 */
1077 yylval->str = ident;
1078 return IDENT;
1079 }
1080
1081{other} {
1082 SET_YYLLOC();
1083 return yytext[0];
1084 }
1085
1086<<EOF>> {
1087 SET_YYLLOC();
1088 yyterminate();
1089 }
1090
1091%%
1092
1093/* LCOV_EXCL_STOP */
1094
1095/*
1096 * Arrange access to yyextra for subroutines of the main yylex() function.
1097 * We expect each subroutine to have a yyscanner parameter. Rather than
1098 * use the yyget_xxx functions, which might or might not get inlined by the
1099 * compiler, we cheat just a bit and cast yyscanner to the right type.
1100 */
1101#undef yyextra
1102#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
1103
1104/* Likewise for a couple of other things we need. */
1105#undef yylloc
1106#define yylloc (((struct yyguts_t *) yyscanner)->yylloc_r)
1107#undef yyleng
1108#define yyleng (((struct yyguts_t *) yyscanner)->yyleng_r)
1109
1110
1111/*
1112 * scanner_errposition
1113 * Report a lexer or grammar error cursor position, if possible.
1114 *
1115 * This is expected to be used within an ereport() call, or via an error
1116 * callback such as setup_scanner_errposition_callback(). The return value
1117 * is a dummy (always 0, in fact).
1118 *
1119 * Note that this can only be used for messages emitted during raw parsing
1120 * (essentially, scan.l, parser.c, and gram.y), since it requires the
1121 * yyscanner struct to still be available.
1122 */
1123int
1124scanner_errposition(int location, core_yyscan_t yyscanner)
1125{
1126 int pos;
1127
1128 if (location < 0)
1129 return 0; /* no-op if location is unknown */
1130
1131 /* Convert byte offset to character number */
1132 pos = pg_mbstrlen_with_len(yyextra->scanbuf, location) + 1;
1133 /* And pass it to the ereport mechanism */
1134 return errposition(pos);
1135}
1136
1137/*
1138 * Error context callback for inserting scanner error location.
1139 *
1140 * Note that this will be called for *any* error occurring while the
1141 * callback is installed. We avoid inserting an irrelevant error location
1142 * if the error is a query cancel --- are there any other important cases?
1143 */
1144static void
1146{
1148
1150 (void) scanner_errposition(scbstate->location, scbstate->yyscanner);
1151}
1152
1153/*
1154 * setup_scanner_errposition_callback
1155 * Arrange for non-scanner errors to report an error position
1156 *
1157 * Sometimes the scanner calls functions that aren't part of the scanner
1158 * subsystem and can't reasonably be passed the yyscanner pointer; yet
1159 * we would like any errors thrown in those functions to be tagged with an
1160 * error location. Use this function to set up an error context stack
1161 * entry that will accomplish that. Usage pattern:
1162 *
1163 * declare a local variable "ScannerCallbackState scbstate"
1164 * ...
1165 * setup_scanner_errposition_callback(&scbstate, yyscanner, location);
1166 * call function that might throw error;
1167 * cancel_scanner_errposition_callback(&scbstate);
1168 */
1169void
1171 core_yyscan_t yyscanner,
1172 int location)
1173{
1174 /* Setup error traceback support for ereport() */
1175 scbstate->yyscanner = yyscanner;
1176 scbstate->location = location;
1177 scbstate->errcallback.callback = scb_error_callback;
1178 scbstate->errcallback.arg = scbstate;
1179 scbstate->errcallback.previous = error_context_stack;
1180 error_context_stack = &scbstate->errcallback;
1181}
1182
1183/*
1184 * Cancel a previously-set-up errposition callback.
1185 */
1186void
1188{
1189 /* Pop the error context stack */
1190 error_context_stack = scbstate->errcallback.previous;
1191}
1192
1193/*
1194 * scanner_yyerror
1195 * Report a lexer or grammar error.
1196 *
1197 * The message's cursor position is whatever YYLLOC was last set to,
1198 * ie, the start of the current token if called within yylex(), or the
1199 * most recently lexed token if called from the grammar.
1200 * This is OK for syntax error messages from the Bison parser, because Bison
1201 * parsers report error as soon as the first unparsable token is reached.
1202 * Beware of using yyerror for other purposes, as the cursor position might
1203 * be misleading!
1204 */
1205void
1206scanner_yyerror(const char *message, core_yyscan_t yyscanner)
1207{
1208 const char *loc = yyextra->scanbuf + *yylloc;
1209
1210 if (*loc == YY_END_OF_BUFFER_CHAR)
1211 {
1212 ereport(ERROR,
1214 /* translator: %s is typically the translation of "syntax error" */
1215 errmsg("%s at end of input", _(message)),
1217 }
1218 else
1219 {
1220 ereport(ERROR,
1222 /* translator: first %s is typically the translation of "syntax error" */
1223 errmsg("%s at or near \"%s\"", _(message), loc),
1225 }
1226}
1227
1228
1229/*
1230 * Called before any actual parsing is done
1231 */
1233scanner_init(const char *str,
1235 const ScanKeywordList *keywordlist,
1236 const uint16 *keyword_tokens)
1237{
1238 Size slen = strlen(str);
1239 yyscan_t scanner;
1240
1241 if (yylex_init(&scanner) != 0)
1242 elog(ERROR, "yylex_init() failed: %m");
1243
1244 core_yyset_extra(yyext, scanner);
1245
1246 yyext->keywordlist = keywordlist;
1247 yyext->keyword_tokens = keyword_tokens;
1248
1249 yyext->backslash_quote = backslash_quote;
1250
1251 /*
1252 * Make a scan buffer with special termination needed by flex.
1253 */
1254 yyext->scanbuf = (char *) palloc(slen + 2);
1255 yyext->scanbuflen = slen;
1256 memcpy(yyext->scanbuf, str, slen);
1257 yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
1258 yy_scan_buffer(yyext->scanbuf, slen + 2, scanner);
1259
1260 /* initialize literal buffer to a reasonable but expansible size */
1261 yyext->literalalloc = 1024;
1262 yyext->literalbuf = (char *) palloc(yyext->literalalloc);
1263 yyext->literallen = 0;
1264
1265 return scanner;
1266}
1267
1268
1269/*
1270 * Called after parsing is done to clean up after scanner_init()
1271 */
1272void
1274{
1275 /*
1276 * We don't bother to call yylex_destroy(), because all it would do is
1277 * pfree a small amount of control storage. It's cheaper to leak the
1278 * storage until the parsing context is destroyed. The amount of space
1279 * involved is usually negligible compared to the output parse tree
1280 * anyway.
1281 *
1282 * We do bother to pfree the scanbuf and literal buffer, but only if they
1283 * represent a nontrivial amount of space. The 8K cutoff is arbitrary.
1284 */
1285 if (yyextra->scanbuflen >= 8192)
1286 pfree(yyextra->scanbuf);
1287 if (yyextra->literalalloc >= 8192)
1288 pfree(yyextra->literalbuf);
1289}
1290
1291
1292static void
1293addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
1294{
1295 /* enlarge buffer if needed */
1296 if ((yyextra->literallen + yleng) >= yyextra->literalalloc)
1297 {
1298 yyextra->literalalloc = pg_nextpower2_32(yyextra->literallen + yleng + 1);
1299 yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1300 yyextra->literalalloc);
1301 }
1302 /* append new data */
1303 memcpy(yyextra->literalbuf + yyextra->literallen, ytext, yleng);
1304 yyextra->literallen += yleng;
1305}
1306
1307
1308static void
1309addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
1310{
1311 /* enlarge buffer if needed */
1312 if ((yyextra->literallen + 1) >= yyextra->literalalloc)
1313 {
1314 yyextra->literalalloc *= 2;
1315 yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1316 yyextra->literalalloc);
1317 }
1318 /* append new data */
1319 yyextra->literalbuf[yyextra->literallen] = ychar;
1320 yyextra->literallen += 1;
1321}
1322
1323
1324/*
1325 * Create a palloc'd copy of literalbuf, adding a trailing null.
1326 */
1327static char *
1329{
1330 int llen = yyextra->literallen;
1331 char *new;
1332
1333 new = palloc(llen + 1);
1334 memcpy(new, yyextra->literalbuf, llen);
1335 new[llen] = '\0';
1336 return new;
1337}
1338
1339/*
1340 * Process {decinteger}, {hexinteger}, etc. Note this will also do the right
1341 * thing with {numeric}, ie digits and a decimal point.
1342 */
1343static int
1344process_integer_literal(const char *token, YYSTYPE *lval, int base)
1345{
1347 int32 val;
1348
1349 val = pg_strtoint32_safe(token, (Node *) &escontext);
1350 if (escontext.error_occurred)
1351 {
1352 /* integer too large (or contains decimal pt), treat it as a float */
1353 lval->str = pstrdup(token);
1354 return FCONST;
1355 }
1356 lval->ival = val;
1357 return ICONST;
1358}
1359
1360static void
1361addunicode(char32_t c, core_yyscan_t yyscanner)
1362{
1365
1367 yyerror("invalid Unicode escape value");
1368
1369 /*
1370 * We expect that pg_unicode_to_server() will complain about any
1371 * unconvertible code point, so we don't have to set saw_non_ascii.
1372 */
1374 pg_unicode_to_server(c, (unsigned char *) buf);
1376 addlit(buf, strlen(buf), yyscanner);
1377}
1378
1379static unsigned char
1380unescape_single_char(unsigned char c, core_yyscan_t yyscanner)
1381{
1382 switch (c)
1383 {
1384 case 'b':
1385 return '\b';
1386 case 'f':
1387 return '\f';
1388 case 'n':
1389 return '\n';
1390 case 'r':
1391 return '\r';
1392 case 't':
1393 return '\t';
1394 case 'v':
1395 return '\v';
1396 default:
1397 /* check for backslash followed by non-7-bit-ASCII */
1398 if (c == '\0' || IS_HIGHBIT_SET(c))
1399 yyextra->saw_non_ascii = true;
1400
1401 return c;
1402 }
1403}
1404
1405/*
1406 * Interface functions to make flex use palloc() instead of malloc().
1407 * It'd be better to make these static, but flex insists otherwise.
1408 */
1409
1410void *
1412{
1413 return palloc(bytes);
1414}
1415
1416void *
1417core_yyrealloc(void *ptr, yy_size_t bytes, core_yyscan_t yyscanner)
1418{
1419 if (ptr)
1420 return repalloc(ptr, bytes);
1421 else
1422 return palloc(bytes);
1423}
1424
1425void
1426core_yyfree(void *ptr, core_yyscan_t yyscanner)
1427{
1428 if (ptr)
1429 pfree(ptr);
1430}
size_t Size
Definition c.h:691
Datum arg
Definition elog.c:1322
ErrorContextCallback * error_context_stack
Definition elog.c:99
#define _(x)
Definition elog.c:95
int geterrcode(void)
#define elog(elevel,...)
Definition elog.h:226
int errposition(int cursorpos)
const char * str
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition mbutils.c:1185
void pg_unicode_to_server(char32_t c, unsigned char *s)
Definition mbutils.c:875
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void * palloc(Size size)
Definition mcxt.c:1387
static uint32 pg_nextpower2_32(uint32 num)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define MAX_UNICODE_EQUIVALENT_STRING
Definition pg_wchar.h:329
static bool is_valid_unicode_codepoint(char32_t c)
Definition pg_wchar.h:519
int scanner_errposition(int location, core_yyscan_t yyscanner)
Definition scan.l:1124
core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
Definition scan.l:1233
#define yylloc
Definition scan.l:1106
void * core_yyrealloc(void *ptr, yy_size_t bytes, core_yyscan_t yyscanner)
Definition scan.l:1417
static void scb_error_callback(void *arg)
Definition scan.l:1145
void setup_scanner_errposition_callback(ScannerCallbackState *scbstate, core_yyscan_t yyscanner, int location)
Definition scan.l:1170
void scanner_finish(core_yyscan_t yyscanner)
Definition scan.l:1273
void cancel_scanner_errposition_callback(ScannerCallbackState *scbstate)
Definition scan.l:1187
void * core_yyalloc(yy_size_t bytes, core_yyscan_t yyscanner)
Definition scan.l:1411
void core_yyfree(void *ptr, core_yyscan_t yyscanner)
Definition scan.l:1426
void scanner_yyerror(const char *message, core_yyscan_t yyscanner)
Definition scan.l:1206
struct ErrorContextCallback * previous
Definition elog.h:297