PostgreSQL Source Code git master
Loading...
Searching...
No Matches
scan.l File Reference
#include "postgres.h"
#include <ctype.h>
#include <unistd.h>
#include "common/string.h"
#include "gramparse.h"
#include "nodes/miscnodes.h"
#include "parser/parser.h"
#include "parser/scansup.h"
#include "port/pg_bitutils.h"
#include "mb/pg_wchar.h"
#include "utils/builtins.h"
#include "parser/kwlist.h"

Go to the source code of this file.

Macros

#define fprintf(file, fmt, msg)   fprintf_to_ereport(fmt, msg)
 
#define PG_KEYWORD(kwname, value, category, collabel)   value,
 
#define YYSTYPE   core_YYSTYPE
 
#define SET_YYLLOC()   (*(yylloc) = yytext - yyextra->scanbuf)
 
#define ADVANCE_YYLLOC(delta)   ( *(yylloc) += (delta) )
 
#define PUSH_YYLLOC()   (yyextra->save_yylloc = *(yylloc))
 
#define POP_YYLLOC()   (*(yylloc) = yyextra->save_yylloc)
 
#define startlit()   ( yyextra->literallen = 0 )
 
#define yyerror(msg)   scanner_yyerror(msg, yyscanner)
 
#define lexer_errposition()   scanner_errposition(*(yylloc), yyscanner)
 
#define yyextra   (((struct yyguts_t *) yyscanner)->yyextra_r)
 
#define yylloc   (((struct yyguts_t *) yyscanner)->yylloc_r)
 
#define yyleng   (((struct yyguts_t *) yyscanner)->yyleng_r)
 

Functions

static void fprintf_to_ereport (const char *fmt, const char *msg)
 
static void addlit (char *ytext, int yleng, core_yyscan_t yyscanner)
 
static void addlitchar (unsigned char ychar, core_yyscan_t yyscanner)
 
static charlitbufdup (core_yyscan_t yyscanner)
 
static unsigned char unescape_single_char (unsigned char c, core_yyscan_t yyscanner)
 
static int process_integer_literal (const char *token, YYSTYPE *lval, int base)
 
static void addunicode (char32_t c, yyscan_t yyscanner)
 
int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
 
int scanner_errposition (int location, core_yyscan_t yyscanner)
 
static void scb_error_callback (void *arg)
 
void setup_scanner_errposition_callback (ScannerCallbackState *scbstate, core_yyscan_t yyscanner, int location)
 
void cancel_scanner_errposition_callback (ScannerCallbackState *scbstate)
 
void scanner_yyerror (const char *message, core_yyscan_t yyscanner)
 
core_yyscan_t scanner_init (const char *str, core_yy_extra_type *yyext, const ScanKeywordList *keywordlist, const uint16 *keyword_tokens)
 
void scanner_finish (core_yyscan_t yyscanner)
 
voidcore_yyalloc (yy_size_t bytes, core_yyscan_t yyscanner)
 
voidcore_yyrealloc (void *ptr, yy_size_t bytes, core_yyscan_t yyscanner)
 
void core_yyfree (void *ptr, core_yyscan_t yyscanner)
 

Variables

int backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING
 
const uint16 ScanKeywordTokens []
 

Macro Definition Documentation

◆ ADVANCE_YYLLOC

#define ADVANCE_YYLLOC (   delta)    ( *(yylloc) += (delta) )

Definition at line 103 of file scan.l.

◆ fprintf

#define fprintf (   file,
  fmt,
  msg 
)    fprintf_to_ereport(fmt, msg)

Definition at line 54 of file scan.l.

◆ lexer_errposition

#define lexer_errposition ( )    scanner_errposition(*(yylloc), yyscanner)

Definition at line 127 of file scan.l.

◆ PG_KEYWORD

#define PG_KEYWORD (   kwname,
  value,
  category,
  collabel 
)    value,

Definition at line 78 of file scan.l.

◆ POP_YYLLOC

#define POP_YYLLOC ( )    (*(yylloc) = yyextra->save_yylloc)

Definition at line 115 of file scan.l.

◆ PUSH_YYLLOC

#define PUSH_YYLLOC ( )    (yyextra->save_yylloc = *(yylloc))

Definition at line 114 of file scan.l.

◆ SET_YYLLOC

#define SET_YYLLOC ( )    (*(yylloc) = yytext - yyextra->scanbuf)

Definition at line 98 of file scan.l.

◆ startlit

#define startlit ( )    ( yyextra->literallen = 0 )

Definition at line 117 of file scan.l.

◆ yyerror

#define yyerror (   msg)    scanner_yyerror(msg, yyscanner)

Definition at line 125 of file scan.l.

◆ yyextra

#define yyextra   (((struct yyguts_t *) yyscanner)->yyextra_r)

Definition at line 1093 of file scan.l.

◆ yyleng

#define yyleng   (((struct yyguts_t *) yyscanner)->yyleng_r)

Definition at line 1099 of file scan.l.

◆ yylloc

#define yylloc   (((struct yyguts_t *) yyscanner)->yylloc_r)

Definition at line 1097 of file scan.l.

◆ YYSTYPE

Definition at line 89 of file scan.l.

Function Documentation

◆ addlit()

static void addlit ( char ytext,
int  yleng,
core_yyscan_t  yyscanner 
)
static

Definition at line 1284 of file scan.l.

1285{
1286 /* enlarge buffer if needed */
1287 if ((yyextra->literallen + yleng) >= yyextra->literalalloc)
1288 {
1289 yyextra->literalalloc = pg_nextpower2_32(yyextra->literallen + yleng + 1);
1290 yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1291 yyextra->literalalloc);
1292 }
1293 /* append new data */
1294 memcpy(yyextra->literalbuf + yyextra->literallen, ytext, yleng);
1295 yyextra->literallen += yleng;
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
static uint32 pg_nextpower2_32(uint32 num)
static int fb(int x)
#define yyextra
Definition scan.l:1093
1296}

References fb(), pg_nextpower2_32(), repalloc(), and yyextra.

Referenced by addunicode().

◆ addlitchar()

static void addlitchar ( unsigned char  ychar,
core_yyscan_t  yyscanner 
)
static

Definition at line 1300 of file scan.l.

1301{
1302 /* enlarge buffer if needed */
1303 if ((yyextra->literallen + 1) >= yyextra->literalalloc)
1304 {
1305 yyextra->literalalloc *= 2;
1306 yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1307 yyextra->literalalloc);
1308 }
1309 /* append new data */
1310 yyextra->literalbuf[yyextra->literallen] = ychar;
1311 yyextra->literallen += 1;
1312}

References fb(), repalloc(), and yyextra.

◆ addunicode()

static void addunicode ( char32_t  c,
yyscan_t  yyscanner 
)
static

Definition at line 1352 of file scan.l.

1353{
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define MAX_UNICODE_EQUIVALENT_STRING
Definition pg_wchar.h:329
1356
1358 yyerror("invalid Unicode escape value");
static bool is_valid_unicode_codepoint(char32_t c)
Definition pg_wchar.h:519
char * c
#define yyerror(msg)
Definition scan.l:125
1359
1360 /*
1361 * We expect that pg_unicode_to_server() will complain about any
1362 * unconvertible code point, so we don't have to set saw_non_ascii.
1363 */
1365 pg_unicode_to_server(c, (unsigned char *) buf);
1367 addlit(buf, strlen(buf), yyscanner);
void pg_unicode_to_server(char32_t c, unsigned char *s)
Definition mbutils.c:867
#define yylloc
Definition scan.l:1097
void setup_scanner_errposition_callback(ScannerCallbackState *scbstate, core_yyscan_t yyscanner, int location)
Definition scan.l:1161
void cancel_scanner_errposition_callback(ScannerCallbackState *scbstate)
Definition scan.l:1178
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
Definition scan.l:1284
1368}

References addlit(), buf, cancel_scanner_errposition_callback(), fb(), is_valid_unicode_codepoint(), MAX_UNICODE_EQUIVALENT_STRING, pg_unicode_to_server(), setup_scanner_errposition_callback(), yyerror, and yylloc.

◆ cancel_scanner_errposition_callback()

void cancel_scanner_errposition_callback ( ScannerCallbackState scbstate)

Definition at line 1178 of file scan.l.

1179{
1180 /* Pop the error context stack */
1181 error_context_stack = scbstate->errcallback.previous;
ErrorContextCallback * error_context_stack
Definition elog.c:95
struct ErrorContextCallback * previous
Definition elog.h:297
1182}

References error_context_stack, fb(), and ErrorContextCallback::previous.

Referenced by addunicode(), and str_udeescape().

◆ core_yyalloc()

void * core_yyalloc ( yy_size_t  bytes,
core_yyscan_t  yyscanner 
)

Definition at line 1402 of file scan.l.

1403{
1404 return palloc(bytes);
void * palloc(Size size)
Definition mcxt.c:1387
1405}

References palloc().

◆ core_yyfree()

void core_yyfree ( void ptr,
core_yyscan_t  yyscanner 
)

Definition at line 1417 of file scan.l.

1418{
1419 if (ptr)
1420 pfree(ptr);
void pfree(void *pointer)
Definition mcxt.c:1616
1421}

References pfree().

◆ core_yyrealloc()

void * core_yyrealloc ( void ptr,
yy_size_t  bytes,
core_yyscan_t  yyscanner 
)

Definition at line 1408 of file scan.l.

1409{
1410 if (ptr)
1411 return repalloc(ptr, bytes);
1412 else
1413 return palloc(bytes);
1414}

References palloc(), and repalloc().

◆ fprintf_to_ereport()

static void fprintf_to_ereport ( const char fmt,
const char msg 
)
static

Definition at line 57 of file scan.l.

58{
59 ereport(ERROR, (errmsg_internal("%s", msg)));
int errmsg_internal(const char *fmt,...)
Definition elog.c:1170
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
60}

References ereport, errmsg_internal(), and ERROR.

◆ litbufdup()

static char * litbufdup ( core_yyscan_t  yyscanner)
static

Definition at line 1319 of file scan.l.

1320{
1321 int llen = yyextra->literallen;
1322 char *new;
1323
1324 new = palloc(llen + 1);
1325 memcpy(new, yyextra->literalbuf, llen);
1326 new[llen] = '\0';
1327 return new;
1328}

References fb(), palloc(), and yyextra.

◆ process_integer_literal()

static int process_integer_literal ( const char token,
YYSTYPE lval,
int  base 
)
static

Definition at line 1335 of file scan.l.

1336{
1338 int32 val;
int32_t int32
Definition c.h:542
long val
Definition informix.c:689
1339
1340 val = pg_strtoint32_safe(token, (Node *) &escontext);
1341 if (escontext.error_occurred)
1342 {
1343 /* integer too large (or contains decimal pt), treat it as a float */
1344 lval->str = pstrdup(token);
1345 return FCONST;
1346 }
1347 lval->ival = val;
1348 return ICONST;
char * pstrdup(const char *in)
Definition mcxt.c:1781
int32 pg_strtoint32_safe(const char *s, Node *escontext)
Definition numutils.c:388
Definition nodes.h:135
1349}

References ErrorSaveContext::error_occurred, fb(), pg_strtoint32_safe(), pstrdup(), and val.

◆ scanner_errposition()

int scanner_errposition ( int  location,
core_yyscan_t  yyscanner 
)

Definition at line 1115 of file scan.l.

1116{
1117 int pos;
1118
1119 if (location < 0)
1120 return 0; /* no-op if location is unknown */
1121
1122 /* Convert byte offset to character number */
1123 pos = pg_mbstrlen_with_len(yyextra->scanbuf, location) + 1;
1124 /* And pass it to the ereport mechanism */
1125 return errposition(pos);
int errposition(int cursorpos)
Definition elog.c:1480
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition mbutils.c:1060
1126}

References errposition(), pg_mbstrlen_with_len(), and yyextra.

Referenced by scb_error_callback(), and str_udeescape().

◆ scanner_finish()

void scanner_finish ( core_yyscan_t  yyscanner)

Definition at line 1264 of file scan.l.

1265{
1266 /*
1267 * We don't bother to call yylex_destroy(), because all it would do is
1268 * pfree a small amount of control storage. It's cheaper to leak the
1269 * storage until the parsing context is destroyed. The amount of space
1270 * involved is usually negligible compared to the output parse tree
1271 * anyway.
1272 *
1273 * We do bother to pfree the scanbuf and literal buffer, but only if they
1274 * represent a nontrivial amount of space. The 8K cutoff is arbitrary.
1275 */
1276 if (yyextra->scanbuflen >= 8192)
1277 pfree(yyextra->scanbuf);
1278 if (yyextra->literalalloc >= 8192)
1279 pfree(yyextra->literalbuf);
1280}

References pfree(), and yyextra.

Referenced by fill_in_constant_lengths(), plpgsql_scanner_finish(), and raw_parser().

◆ scanner_init()

core_yyscan_t scanner_init ( const char str,
core_yy_extra_type yyext,
const ScanKeywordList keywordlist,
const uint16 keyword_tokens 
)

Definition at line 1224 of file scan.l.

1228{
1229 Size slen = strlen(str);
1230 yyscan_t scanner;
size_t Size
Definition c.h:619
void * yyscan_t
Definition cubedata.h:65
const char * str
1231
1232 if (yylex_init(&scanner) != 0)
1233 elog(ERROR, "yylex_init() failed: %m");
#define elog(elevel,...)
Definition elog.h:226
1234
1235 core_yyset_extra(yyext, scanner);
1236
1237 yyext->keywordlist = keywordlist;
1238 yyext->keyword_tokens = keyword_tokens;
1239
1240 yyext->backslash_quote = backslash_quote;
int backslash_quote
Definition scan.l:69
1241
1242 /*
1243 * Make a scan buffer with special termination needed by flex.
1244 */
1245 yyext->scanbuf = (char *) palloc(slen + 2);
1246 yyext->scanbuflen = slen;
1247 memcpy(yyext->scanbuf, str, slen);
1248 yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
1249 yy_scan_buffer(yyext->scanbuf, slen + 2, scanner);
1250
1251 /* initialize literal buffer to a reasonable but expansible size */
1252 yyext->literalalloc = 1024;
1253 yyext->literalbuf = (char *) palloc(yyext->literalalloc);
1254 yyext->literallen = 0;
1255
1256 return scanner;
1257}

References backslash_quote, elog, ERROR, fb(), palloc(), and str.

Referenced by fill_in_constant_lengths(), plpgsql_scanner_init(), and raw_parser().

◆ scanner_yyerror()

void scanner_yyerror ( const char message,
core_yyscan_t  yyscanner 
)

Definition at line 1197 of file scan.l.

1198{
1199 const char *loc = yyextra->scanbuf + *yylloc;
1200
1201 if (*loc == YY_END_OF_BUFFER_CHAR)
1202 {
1203 ereport(ERROR,
1205 /* translator: %s is typically the translation of "syntax error" */
1206 errmsg("%s at end of input", _(message)),
1208 }
1209 else
1210 {
1211 ereport(ERROR,
1213 /* translator: first %s is typically the translation of "syntax error" */
1214 errmsg("%s at or near \"%s\"", _(message), loc),
1216 }
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define _(x)
Definition elog.c:91
#define lexer_errposition()
Definition scan.l:127
1217}

References _, ereport, errcode(), errmsg(), ERROR, fb(), lexer_errposition, yyextra, and yylloc.

Referenced by base_yylex().

◆ scb_error_callback()

static void scb_error_callback ( void arg)
static

Definition at line 1136 of file scan.l.

1137{
void * arg
1139
1141 (void) scanner_errposition(scbstate->location, scbstate->yyscanner);
int geterrcode(void)
Definition elog.c:1595
int scanner_errposition(int location, core_yyscan_t yyscanner)
Definition scan.l:1115
1142}

References arg, fb(), geterrcode(), and scanner_errposition().

Referenced by setup_scanner_errposition_callback().

◆ setup_scanner_errposition_callback()

void setup_scanner_errposition_callback ( ScannerCallbackState scbstate,
core_yyscan_t  yyscanner,
int  location 
)

Definition at line 1161 of file scan.l.

1164{
1165 /* Setup error traceback support for ereport() */
1166 scbstate->yyscanner = yyscanner;
1167 scbstate->location = location;
1168 scbstate->errcallback.callback = scb_error_callback;
1169 scbstate->errcallback.arg = scbstate;
1170 scbstate->errcallback.previous = error_context_stack;
1171 error_context_stack = &scbstate->errcallback;
static void scb_error_callback(void *arg)
Definition scan.l:1136
1172}

References error_context_stack, fb(), and scb_error_callback().

Referenced by addunicode(), and str_udeescape().

◆ unescape_single_char()

static unsigned char unescape_single_char ( unsigned char  c,
core_yyscan_t  yyscanner 
)
static

Definition at line 1371 of file scan.l.

1372{
1373 switch (c)
1374 {
1375 case 'b':
1376 return '\b';
1377 case 'f':
1378 return '\f';
1379 case 'n':
1380 return '\n';
1381 case 'r':
1382 return '\r';
1383 case 't':
1384 return '\t';
1385 case 'v':
1386 return '\v';
1387 default:
1388 /* check for backslash followed by non-7-bit-ASCII */
1389 if (c == '\0' || IS_HIGHBIT_SET(c))
1390 yyextra->saw_non_ascii = true;
#define IS_HIGHBIT_SET(ch)
Definition c.h:1150
1391
1392 return c;
1393 }
1394}

References IS_HIGHBIT_SET, and yyextra.

◆ yylex()

int yylex ( YYSTYPE yylval_param,
YYLTYPE yylloc_param,
yyscan_t  yyscanner 
)

Definition at line 437 of file scan.l.

439{whitespace} {
440 /* ignore */
441 }
442
443{xcstart} {
444 /* Set location in case of syntax error in comment */
445 SET_YYLLOC();
446 yyextra->xcdepth = 0;
447 BEGIN(xc);
448 /* Put back any characters past slash-star; see above */
449 yyless(2);
450 }
#define SET_YYLLOC()
Definition scan.l:98
451
452<xc>{
453{xcstart} {
454 (yyextra->xcdepth)++;
455 /* Put back any characters past slash-star; see above */
456 yyless(2);
457 }
458
459{xcstop} {
460 if (yyextra->xcdepth <= 0)
461 BEGIN(INITIAL);
462 else
463 (yyextra->xcdepth)--;
464 }
465
466{xcinside} {
467 /* ignore */
468 }
469
470{op_chars} {
471 /* ignore */
472 }
473
474\*+ {
475 /* ignore */
476 }
477
478<<EOF>> {
479 yyerror("unterminated /* comment");
480 }
481} /* <xc> */
482
483{xbstart} {
484 /* Binary bit type.
485 * At some point we should simply pass the string
486 * forward to the parser and label it there.
487 * In the meantime, place a leading "b" on the string
488 * to mark it for the input routine as a binary string.
489 */
490 SET_YYLLOC();
491 BEGIN(xb);
492 startlit();
493 addlitchar('b', yyscanner);
494 }
static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
Definition scan.l:1300
#define startlit()
Definition scan.l:117
495<xh>{xhinside} |
496<xb>{xbinside} {
497 addlit(yytext, yyleng, yyscanner);
498 }
#define yyleng
Definition scan.l:1099
499<xb><<EOF>> { yyerror("unterminated bit string literal"); }
500
501{xhstart} {
502 /* Hexadecimal bit type.
503 * At some point we should simply pass the string
504 * forward to the parser and label it there.
505 * In the meantime, place a leading "x" on the string
506 * to mark it for the input routine as a hex string.
507 */
508 SET_YYLLOC();
509 BEGIN(xh);
510 startlit();
511 addlitchar('x', yyscanner);
512 }
513<xh><<EOF>> { yyerror("unterminated hexadecimal string literal"); }
514
515{xnstart} {
516 /* National character.
517 * We will pass this along as a normal character string,
518 * but preceded with an internally-generated "NCHAR".
519 */
520 int kwnum;
521
522 SET_YYLLOC();
523 yyless(1); /* eat only 'n' this time */
524
525 kwnum = ScanKeywordLookup("nchar",
526 yyextra->keywordlist);
527 if (kwnum >= 0)
528 {
529 yylval->keyword = GetScanKeyword(kwnum,
530 yyextra->keywordlist);
531 return yyextra->keyword_tokens[kwnum];
532 }
533 else
534 {
535 /* If NCHAR isn't a keyword, just return "n" */
536 yylval->str = pstrdup("n");
537 return IDENT;
538 }
539 }
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
540
541{xqstart} {
542 yyextra->saw_non_ascii = false;
543 SET_YYLLOC();
544 BEGIN(xq);
545 startlit();
546 }
547{xestart} {
548 yyextra->saw_non_ascii = false;
549 SET_YYLLOC();
550 BEGIN(xe);
551 startlit();
552 }
553{xusstart} {
554 SET_YYLLOC();
555 BEGIN(xus);
556 startlit();
557 }
558
559<xb,xh,xq,xe,xus>{quote} {
560 /*
561 * When we are scanning a quoted string and see an end
562 * quote, we must look ahead for a possible continuation.
563 * If we don't see one, we know the end quote was in fact
564 * the end of the string. To reduce the lexer table size,
565 * we use a single "xqs" state to do the lookahead for all
566 * types of strings.
567 */
568 yyextra->state_before_str_stop = YYSTATE;
569 BEGIN(xqs);
570 }
571<xqs>{quotecontinue} {
572 /*
573 * Found a quote continuation, so return to the in-quote
574 * state and continue scanning the literal. Nothing is
575 * added to the literal's contents.
576 */
577 BEGIN(yyextra->state_before_str_stop);
578 }
579<xqs>{quotecontinuefail} |
580<xqs>{other} |
581<xqs><<EOF>> {
582 /*
583 * Failed to see a quote continuation. Throw back
584 * everything after the end quote, and handle the string
585 * according to the state we were in previously.
586 */
587 yyless(0);
588 BEGIN(INITIAL);
589
590 switch (yyextra->state_before_str_stop)
591 {
592 case xb:
593 yylval->str = litbufdup(yyscanner);
594 return BCONST;
595 case xh:
596 yylval->str = litbufdup(yyscanner);
597 return XCONST;
598 case xq:
599 case xe:
600 /*
601 * Check that the data remains valid, if it might
602 * have been made invalid by unescaping any chars.
603 */
604 if (yyextra->saw_non_ascii)
605 pg_verifymbstr(yyextra->literalbuf,
606 yyextra->literallen,
607 false);
608 yylval->str = litbufdup(yyscanner);
609 return SCONST;
610 case xus:
611 yylval->str = litbufdup(yyscanner);
612 return USCONST;
613 default:
614 yyerror("unhandled previous state in xqs");
615 }
616 }
bool pg_verifymbstr(const char *mbstr, int len, bool noError)
Definition mbutils.c:1559
static char * litbufdup(core_yyscan_t yyscanner)
Definition scan.l:1319
617
618<xq,xe,xus>{xqdouble} {
619 addlitchar('\'', yyscanner);
620 }
621<xq,xus>{xqinside} {
622 addlit(yytext, yyleng, yyscanner);
623 }
624<xe>{xeinside} {
625 addlit(yytext, yyleng, yyscanner);
626 }
627<xe>{xeunicode} {
628 char32_t c = strtoul(yytext + 2, NULL, 16);
629
630 /* Remember start of overall string token ... */
631 PUSH_YYLLOC();
632 /* ... and set the error cursor to point at this esc seq */
633 SET_YYLLOC();
#define PUSH_YYLLOC()
Definition scan.l:114
634
636 {
637 yyextra->utf16_first_part = c;
638 BEGIN(xeu);
639 }
641 yyerror("invalid Unicode surrogate pair");
642 else
643 addunicode(c, yyscanner);
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
static void addunicode(char32_t c, yyscan_t yyscanner)
Definition scan.l:1352
644
645 /* Restore yylloc to be start of string token */
646 POP_YYLLOC();
647 }
#define POP_YYLLOC()
Definition scan.l:115
648<xeu>{xeunicode} {
649 char32_t c = strtoul(yytext + 2, NULL, 16);
650
651 /* Remember start of overall string token ... */
652 PUSH_YYLLOC();
653 /* ... and set the error cursor to point at this esc seq */
654 SET_YYLLOC();
655
657 yyerror("invalid Unicode surrogate pair");
658
659 c = surrogate_pair_to_codepoint(yyextra->utf16_first_part, c);
static char32_t surrogate_pair_to_codepoint(char16_t first, char16_t second)
Definition pg_wchar.h:537
660
661 addunicode(c, yyscanner);
662
663 /* Restore yylloc to be start of string token */
664 POP_YYLLOC();
665
666 BEGIN(xe);
667 }
668<xeu>. |
669<xeu>\n |
670<xeu><<EOF>> {
671 /* Set the error cursor to point at missing esc seq */
672 SET_YYLLOC();
673 yyerror("invalid Unicode surrogate pair");
674 }
675<xe,xeu>{xeunicodefail} {
676 /* Set the error cursor to point at malformed esc seq */
677 SET_YYLLOC();
680 errmsg("invalid Unicode escape"),
681 errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."),
683 }
int errhint(const char *fmt,...)
Definition elog.c:1330
684<xe>{xeescape} {
685 if (yytext[1] == '\'')
686 {
687 if (yyextra->backslash_quote == BACKSLASH_QUOTE_OFF ||
688 (yyextra->backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&
692 errmsg("unsafe use of \\' in a string literal"),
693 errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),
695 }
697 yyscanner);
698 }
int pg_get_client_encoding(void)
Definition mbutils.c:337
@ BACKSLASH_QUOTE_SAFE_ENCODING
Definition parser.h:52
@ BACKSLASH_QUOTE_OFF
Definition parser.h:50
#define PG_ENCODING_IS_CLIENT_ONLY(_enc)
Definition pg_wchar.h:284
static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner)
Definition scan.l:1371
699<xe>{xeoctesc} {
700 unsigned char c = strtoul(yytext + 1, NULL, 8);
701
702 addlitchar(c, yyscanner);
703 if (c == '\0' || IS_HIGHBIT_SET(c))
704 yyextra->saw_non_ascii = true;
705 }
706<xe>{xehexesc} {
707 unsigned char c = strtoul(yytext + 2, NULL, 16);
708
709 addlitchar(c, yyscanner);
710 if (c == '\0' || IS_HIGHBIT_SET(c))
711 yyextra->saw_non_ascii = true;
712 }
713<xe>. {
714 /* This is only needed for \ just before EOF */
715 addlitchar(yytext[0], yyscanner);
716 }
717<xq,xe,xus><<EOF>> { yyerror("unterminated quoted string"); }
718
719{dolqdelim} {
720 SET_YYLLOC();
721 yyextra->dolqstart = pstrdup(yytext);
722 BEGIN(xdolq);
723 startlit();
724 }
725{dolqfailed} {
726 SET_YYLLOC();
727 /* throw back all but the initial "$" */
728 yyless(1);
729 /* and treat it as {other} */
730 return yytext[0];
731 }
732<xdolq>{dolqdelim} {
733 if (strcmp(yytext, yyextra->dolqstart) == 0)
734 {
735 pfree(yyextra->dolqstart);
736 yyextra->dolqstart = NULL;
737 BEGIN(INITIAL);
738 yylval->str = litbufdup(yyscanner);
739 return SCONST;
740 }
741 else
742 {
743 /*
744 * When we fail to match $...$ to dolqstart, transfer
745 * the $... part to the output, but put back the final
746 * $ for rescanning. Consider $delim$...$junk$delim$
747 */
748 addlit(yytext, yyleng - 1, yyscanner);
749 yyless(yyleng - 1);
750 }
751 }
752<xdolq>{dolqinside} {
753 addlit(yytext, yyleng, yyscanner);
754 }
755<xdolq>{dolqfailed} {
756 addlit(yytext, yyleng, yyscanner);
757 }
758<xdolq>. {
759 /* This is only needed for $ inside the quoted text */
760 addlitchar(yytext[0], yyscanner);
761 }
762<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
763
764{xdstart} {
765 SET_YYLLOC();
766 BEGIN(xd);
767 startlit();
768 }
769{xuistart} {
770 SET_YYLLOC();
771 BEGIN(xui);
772 startlit();
773 }
774<xd>{xdstop} {
775 char *ident;
#define ident
776
777 BEGIN(INITIAL);
778 if (yyextra->literallen == 0)
779 yyerror("zero-length delimited identifier");
780 ident = litbufdup(yyscanner);
781 if (yyextra->literallen >= NAMEDATALEN)
782 truncate_identifier(ident, yyextra->literallen, true);
783 yylval->str = ident;
784 return IDENT;
785 }
#define NAMEDATALEN
void truncate_identifier(char *ident, int len, bool warn)
Definition scansup.c:81
786<xui>{dquote} {
787 BEGIN(INITIAL);
788 if (yyextra->literallen == 0)
789 yyerror("zero-length delimited identifier");
790 /* can't truncate till after we de-escape the ident */
791 yylval->str = litbufdup(yyscanner);
792 return UIDENT;
793 }
794<xd,xui>{xddouble} {
795 addlitchar('"', yyscanner);
796 }
797<xd,xui>{xdinside} {
798 addlit(yytext, yyleng, yyscanner);
799 }
800<xd,xui><<EOF>> { yyerror("unterminated quoted identifier"); }
801
802{xufailed} {
803 char *ident;
804
805 SET_YYLLOC();
806 /* throw back all but the initial u/U */
807 yyless(1);
808 /* and treat it as {identifier} */
810 yylval->str = ident;
811 return IDENT;
812 }
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition scansup.c:38
813
814{typecast} {
815 SET_YYLLOC();
816 return TYPECAST;
817 }
818
819{dot_dot} {
820 SET_YYLLOC();
821 return DOT_DOT;
822 }
823
824{colon_equals} {
825 SET_YYLLOC();
826 return COLON_EQUALS;
827 }
828
829{equals_greater} {
830 SET_YYLLOC();
831 return EQUALS_GREATER;
832 }
833
834{less_equals} {
835 SET_YYLLOC();
836 return LESS_EQUALS;
837 }
838
839{greater_equals} {
840 SET_YYLLOC();
841 return GREATER_EQUALS;
842 }
843
844{less_greater} {
845 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
846 SET_YYLLOC();
847 return NOT_EQUALS;
848 }
849
850{not_equals} {
851 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
852 SET_YYLLOC();
853 return NOT_EQUALS;
854 }
855
856{self} {
857 SET_YYLLOC();
858 return yytext[0];
859 }
860
861{operator} {
862 /*
863 * Check for embedded slash-star or dash-dash; those
864 * are comment starts, so operator must stop there.
865 * Note that slash-star or dash-dash at the first
866 * character will match a prior rule, not this one.
867 */
868 int nchars = yyleng;
869 char *slashstar = strstr(yytext, "/*");
870 char *dashdash = strstr(yytext, "--");
871
872 if (slashstar && dashdash)
873 {
874 /* if both appear, take the first one */
875 if (slashstar > dashdash)
877 }
878 else if (!slashstar)
880 if (slashstar)
881 nchars = slashstar - yytext;
882
883 /*
884 * For SQL compatibility, '+' and '-' cannot be the
885 * last char of a multi-char operator unless the operator
886 * contains chars that are not in SQL operators.
887 * The idea is to lex '=-' as two operators, but not
888 * to forbid operator names like '?-' that could not be
889 * sequences of SQL operators.
890 */
891 if (nchars > 1 &&
892 (yytext[nchars - 1] == '+' ||
893 yytext[nchars - 1] == '-'))
894 {
895 int ic;
896
897 for (ic = nchars - 2; ic >= 0; ic--)
898 {
899 char c = yytext[ic];
900 if (c == '~' || c == '!' || c == '@' ||
901 c == '#' || c == '^' || c == '&' ||
902 c == '|' || c == '`' || c == '?' ||
903 c == '%')
904 break;
905 }
906 if (ic < 0)
907 {
908 /*
909 * didn't find a qualifying character, so remove
910 * all trailing [+-]
911 */
912 do {
913 nchars--;
914 } while (nchars > 1 &&
915 (yytext[nchars - 1] == '+' ||
916 yytext[nchars - 1] == '-'));
917 }
918 }
919
920 SET_YYLLOC();
921
922 if (nchars < yyleng)
923 {
924 /* Strip the unwanted chars from the token */
925 yyless(nchars);
926 /*
927 * If what we have left is only one char, and it's
928 * one of the characters matching "self", then
929 * return it as a character token the same way
930 * that the "self" rule would have.
931 */
932 if (nchars == 1 &&
933 strchr(",()[].;:+-*/%^<>=", yytext[0]))
934 return yytext[0];
935 /*
936 * Likewise, if what we have left is two chars, and
937 * those match the tokens ">=", "<=", "=>", "<>" or
938 * "!=", then we must return the appropriate token
939 * rather than the generic Op.
940 */
941 if (nchars == 2)
942 {
943 if (yytext[0] == '=' && yytext[1] == '>')
944 return EQUALS_GREATER;
945 if (yytext[0] == '>' && yytext[1] == '=')
946 return GREATER_EQUALS;
947 if (yytext[0] == '<' && yytext[1] == '=')
948 return LESS_EQUALS;
949 if (yytext[0] == '<' && yytext[1] == '>')
950 return NOT_EQUALS;
951 if (yytext[0] == '!' && yytext[1] == '=')
952 return NOT_EQUALS;
953 }
954 }
955
956 /*
957 * Complain if operator is too long. Unlike the case
958 * for identifiers, we make this an error not a notice-
959 * and-truncate, because the odds are we are looking at
960 * a syntactic mistake anyway.
961 */
962 if (nchars >= NAMEDATALEN)
963 yyerror("operator too long");
964
965 yylval->str = pstrdup(yytext);
966 return Op;
967 }
968
969{param} {
971 int32 val;
972
973 SET_YYLLOC();
974 val = pg_strtoint32_safe(yytext + 1, (Node *) &escontext);
975 if (escontext.error_occurred)
976 yyerror("parameter number too large");
977 yylval->ival = val;
978 return PARAM;
979 }
980{param_junk} {
981 SET_YYLLOC();
982 yyerror("trailing junk after parameter");
983 }
984
985{decinteger} {
986 SET_YYLLOC();
988 }
static int process_integer_literal(const char *token, YYSTYPE *lval, int base)
Definition scan.l:1335
989{hexinteger} {
990 SET_YYLLOC();
992 }
993{octinteger} {
994 SET_YYLLOC();
996 }
997{bininteger} {
998 SET_YYLLOC();
1000 }
1001{hexfail} {
1002 SET_YYLLOC();
1003 yyerror("invalid hexadecimal integer");
1004 }
1005{octfail} {
1006 SET_YYLLOC();
1007 yyerror("invalid octal integer");
1008 }
1009{binfail} {
1010 SET_YYLLOC();
1011 yyerror("invalid binary integer");
1012 }
1013{numeric} {
1014 SET_YYLLOC();
1015 yylval->str = pstrdup(yytext);
1016 return FCONST;
1017 }
1018{numericfail} {
1019 /* throw back the .., and treat as integer */
1020 yyless(yyleng - 2);
1021 SET_YYLLOC();
1023 }
1024{real} {
1025 SET_YYLLOC();
1026 yylval->str = pstrdup(yytext);
1027 return FCONST;
1028 }
1029{realfail} {
1030 SET_YYLLOC();
1031 yyerror("trailing junk after numeric literal");
1032 }
1033{integer_junk} {
1034 SET_YYLLOC();
1035 yyerror("trailing junk after numeric literal");
1036 }
1037{numeric_junk} {
1038 SET_YYLLOC();
1039 yyerror("trailing junk after numeric literal");
1040 }
1041{real_junk} {
1042 SET_YYLLOC();
1043 yyerror("trailing junk after numeric literal");
1044 }
1045
1046
1047{identifier} {
1048 int kwnum;
1049 char *ident;
1050
1051 SET_YYLLOC();
1052
1053 /* Is it a keyword? */
1055 yyextra->keywordlist);
1056 if (kwnum >= 0)
1057 {
1058 yylval->keyword = GetScanKeyword(kwnum,
1059 yyextra->keywordlist);
1060 return yyextra->keyword_tokens[kwnum];
1061 }
1062
1063 /*
1064 * No. Convert the identifier to lower case, and truncate
1065 * if necessary.
1066 */
1068 yylval->str = ident;
1069 return IDENT;
1070 }
1071
1072{other} {
1073 SET_YYLLOC();
1074 return yytext[0];
1075 }
1076
1077<<EOF>> {
1078 SET_YYLLOC();
1079 yyterminate();
1080 }
1081
1082%%

Variable Documentation

◆ backslash_quote

Definition at line 69 of file scan.l.

Referenced by scanner_init().

◆ ScanKeywordTokens

const uint16 ScanKeywordTokens[]
Initial value:
= {
}

Definition at line 80 of file scan.l.

80 {
81#include "parser/kwlist.h"
82};

Referenced by fill_in_constant_lengths(), and raw_parser().