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 1102 of file scan.l.

◆ yyleng

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

Definition at line 1108 of file scan.l.

◆ yylloc

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

Definition at line 1106 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 1293 of file scan.l.

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;
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:1102
1305}

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 1309 of file scan.l.

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}

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

◆ addunicode()

static void addunicode ( char32_t  c,
yyscan_t  yyscanner 
)
static

Definition at line 1361 of file scan.l.

1362{
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define MAX_UNICODE_EQUIVALENT_STRING
Definition pg_wchar.h:329
1365
1367 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
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);
void pg_unicode_to_server(char32_t c, unsigned char *s)
Definition mbutils.c:875
#define yylloc
Definition scan.l:1106
void setup_scanner_errposition_callback(ScannerCallbackState *scbstate, core_yyscan_t yyscanner, int location)
Definition scan.l:1170
void cancel_scanner_errposition_callback(ScannerCallbackState *scbstate)
Definition scan.l:1187
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
Definition scan.l:1293
1377}

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 1187 of file scan.l.

1188{
1189 /* Pop the error context stack */
1190 error_context_stack = scbstate->errcallback.previous;
ErrorContextCallback * error_context_stack
Definition elog.c:99
struct ErrorContextCallback * previous
Definition elog.h:297
1191}

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 1411 of file scan.l.

1412{
1413 return palloc(bytes);
void * palloc(Size size)
Definition mcxt.c:1387
1414}

References palloc().

◆ core_yyfree()

void core_yyfree ( void ptr,
core_yyscan_t  yyscanner 
)

Definition at line 1426 of file scan.l.

1427{
1428 if (ptr)
1429 pfree(ptr);
void pfree(void *pointer)
Definition mcxt.c:1616
1430}

References pfree().

◆ core_yyrealloc()

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

Definition at line 1417 of file scan.l.

1418{
1419 if (ptr)
1420 return repalloc(ptr, bytes);
1421 else
1422 return palloc(bytes);
1423}

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 int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#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 1328 of file scan.l.

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}

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

◆ process_integer_literal()

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

Definition at line 1344 of file scan.l.

1345{
1347 int32 val;
int32_t int32
Definition c.h:614
long val
Definition informix.c:689
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;
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
1358}

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 1124 of file scan.l.

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);
int errposition(int cursorpos)
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition mbutils.c:1185
1135}

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 1273 of file scan.l.

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}

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 1233 of file scan.l.

1237{
1238 Size slen = strlen(str);
1239 yyscan_t scanner;
size_t Size
Definition c.h:691
void * yyscan_t
Definition cubedata.h:65
const char * str
1240
1241 if (yylex_init(&scanner) != 0)
1242 elog(ERROR, "yylex_init() failed: %m");
#define elog(elevel,...)
Definition elog.h:226
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;
int backslash_quote
Definition scan.l:69
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}

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 1206 of file scan.l.

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 }
int errcode(int sqlerrcode)
Definition elog.c:874
#define _(x)
Definition elog.c:95
static char * errmsg
#define lexer_errposition()
Definition scan.l:127
1226}

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 1145 of file scan.l.

1146{
Datum arg
Definition elog.c:1322
1148
1150 (void) scanner_errposition(scbstate->location, scbstate->yyscanner);
int geterrcode(void)
int scanner_errposition(int location, core_yyscan_t yyscanner)
Definition scan.l:1124
1151}

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 1170 of file scan.l.

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;
static void scb_error_callback(void *arg)
Definition scan.l:1145
1181}

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 1380 of file scan.l.

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;
#define IS_HIGHBIT_SET(ch)
Definition c.h:1246
1400
1401 return c;
1402 }
1403}

References IS_HIGHBIT_SET, and yyextra.

◆ yylex()

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

Definition at line 439 of file scan.l.

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 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 }
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 }
static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
Definition scan.l:1309
#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
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
static char * litbufdup(core_yyscan_t yyscanner)
Definition scan.l:1328
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();
#define PUSH_YYLLOC()
Definition scan.l:114
636
638 {
639 yyextra->utf16_first_part = c;
640 BEGIN(xeu);
641 }
643 yyerror("invalid Unicode surrogate pair");
644 else
645 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:1361
646
647 /* Restore yylloc to be start of string token */
648 POP_YYLLOC();
649 }
#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);
static char32_t surrogate_pair_to_codepoint(char16_t first, char16_t second)
Definition pg_wchar.h:537
662
663 addunicode(c, yyscanner);
664
665 /* Restore yylloc to be start of string token */
666 POP_YYLLOC();
667
668 BEGIN(xe);
669 }
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 errhint(const char *fmt,...) pg_attribute_printf(1
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_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:1380
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 }
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 }
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;
#define 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 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 }
989{param_junk} {
990 SET_YYLLOC();
991 yyerror("trailing junk after parameter");
992 }
993
994{decinteger} {
995 SET_YYLLOC();
997 }
static int process_integer_literal(const char *token, YYSTYPE *lval, int base)
Definition scan.l:1344
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%%

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().