|
|
|
|
Quelle repl_scanner.l
Sprache: unbekannt
|
|
Spracherkennung für: .l vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
%top{
/*-------------------------------------------------------------------------
*
* repl_scanner.l
* a lexical scanner for the replication commands
*
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/replication/repl_scanner.l
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "nodes/parsenodes.h"
#include "utils/builtins.h"
#include "parser/scansup.h"
/*
* NB: include repl_gram.h only AFTER including walsender_private.h, because
* walsender_private includes headers that define XLogRecPtr.
*/
#include "replication/walsender_private.h"
#include "repl_gram.h"
}
%{
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
static void
fprintf_to_ereport(const char *fmt, const char *msg)
{
ereport(ERROR, (errmsg_internal("%s", msg)));
}
struct replication_yy_extra_type
{
/* Pushed-back token (we only handle one) */
int repl_pushed_back_token;
/* Work area for collecting literals */
StringInfoData litbuf;
};
static void startlit(yyscan_t yyscanner);
static char *litbufdup(yyscan_t yyscanner);
static void addlit(char *ytext, int yleng, yyscan_t yyscanner);
static void addlitchar(unsigned char ychar, yyscan_t yyscanner);
/* LCOV_EXCL_START */
%}
%option reentrant
%option bison-bridge
%option 8bit
%option never-interactive
%option nodefault
%option noinput
%option nounput
%option noyywrap
%option noyyalloc
%option noyyrealloc
%option noyyfree
%option warn
%option prefix="replication_yy"
%option extra-type="struct replication_yy_extra_type *"
/*
* Exclusive states:
* <xd> delimited identifiers (double-quoted identifiers)
* <xq> standard single-quoted strings
*/
%x xd
%x xq
space [ \t\n\r\f\v]
quote '
quotestop {quote}
/* Extended quote
* xqdouble implements embedded quote, ''''
*/
xqstart {quote}
xqdouble {quote}{quote}
xqinside [^']+
/* Double quote
* Allows embedded spaces and other special characters into identifiers.
*/
dquote \"
xdstart {dquote}
xdstop {dquote}
xddouble {dquote}{dquote}
xdinside [^"]+
digit [0-9]
hexdigit [0-9A-Fa-f]
ident_start [A-Za-z\200-\377_]
ident_cont [A-Za-z\200-\377_0-9\$]
identifier {ident_start}{ident_cont}*
%%
%{
/* This code is inserted at the start of replication_yylex() */
/* If we have a pushed-back token, return that. */
if (yyextra->repl_pushed_back_token)
{
int result = yyextra->repl_pushed_back_token;
yyextra->repl_pushed_back_token = 0;
return result;
}
%}
BASE_BACKUP { return K_BASE_BACKUP; }
IDENTIFY_SYSTEM { return K_IDENTIFY_SYSTEM; }
READ_REPLICATION_SLOT { return K_READ_REPLICATION_SLOT; }
SHOW { return K_SHOW; }
TIMELINE { return K_TIMELINE; }
START_REPLICATION { return K_START_REPLICATION; }
CREATE_REPLICATION_SLOT { return K_CREATE_REPLICATION_SLOT; }
DROP_REPLICATION_SLOT { return K_DROP_REPLICATION_SLOT; }
ALTER_REPLICATION_SLOT { return K_ALTER_REPLICATION_SLOT; }
TIMELINE_HISTORY { return K_TIMELINE_HISTORY; }
PHYSICAL { return K_PHYSICAL; }
RESERVE_WAL { return K_RESERVE_WAL; }
LOGICAL { return K_LOGICAL; }
SLOT { return K_SLOT; }
TEMPORARY { return K_TEMPORARY; }
TWO_PHASE { return K_TWO_PHASE; }
EXPORT_SNAPSHOT { return K_EXPORT_SNAPSHOT; }
NOEXPORT_SNAPSHOT { return K_NOEXPORT_SNAPSHOT; }
USE_SNAPSHOT { return K_USE_SNAPSHOT; }
WAIT { return K_WAIT; }
UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; }
{space}+ { /* do nothing */ }
{digit}+ {
yylval->uintval = strtoul(yytext, NULL, 10);
return UCONST;
}
{hexdigit}+\/{hexdigit}+ {
uint32 hi,
lo;
if (sscanf(yytext, "%X/%X", &hi, &lo) != 2)
replication_yyerror(NULL, yyscanner, "invalid streaming start location");
yylval->recptr = ((uint64) hi) << 32 | lo;
return RECPTR;
}
{xqstart} {
BEGIN(xq);
startlit(yyscanner);
}
<xq>{quotestop} {
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
return SCONST;
}
<xq>{xqdouble} {
addlitchar('\'', yyscanner);
}
<xq>{xqinside} {
addlit(yytext, yyleng, yyscanner);
}
{xdstart} {
BEGIN(xd);
startlit(yyscanner);
}
<xd>{xdstop} {
int len;
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
len = strlen(yylval->str);
truncate_identifier(yylval->str, len, true);
return IDENT;
}
<xd>{xdinside} {
addlit(yytext, yyleng, yyscanner);
}
{identifier} {
int len = strlen(yytext);
yylval->str = downcase_truncate_identifier(yytext, len, true);
return IDENT;
}
. {
/* Any char not recognized above is returned as itself */
return yytext[0];
}
<xq,xd><<EOF>> { replication_yyerror(NULL, yyscanner, "unterminated quoted string"); }
<<EOF>> {
yyterminate();
}
%%
/* LCOV_EXCL_STOP */
/* see scan.l */
#undef yyextra
#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
static void
startlit(yyscan_t yyscanner)
{
initStringInfo(&yyextra->litbuf);
}
static char *
litbufdup(yyscan_t yyscanner)
{
return yyextra->litbuf.data;
}
static void
addlit(char *ytext, int yleng, yyscan_t yyscanner)
{
appendBinaryStringInfo(&yyextra->litbuf, ytext, yleng);
}
static void
addlitchar(unsigned char ychar, yyscan_t yyscanner)
{
appendStringInfoChar(&yyextra->litbuf, ychar);
}
/*
* (The first argument is enforced by Bison to match the first argument of
* yyparse(), but it is not used here.)
*/
void
replication_yyerror(Node **replication_parse_result_p, yyscan_t yyscanner, const char *message)
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg_internal("%s", message)));
}
void
replication_scanner_init(const char *str, yyscan_t *yyscannerp)
{
yyscan_t yyscanner;
struct replication_yy_extra_type *yyext = palloc0_object(struct replication_yy_extra_type);
if (yylex_init(yyscannerp) != 0)
elog(ERROR, "yylex_init() failed: %m");
yyscanner = *yyscannerp;
yyset_extra(yyext, yyscanner);
yy_scan_string(str, yyscanner);
}
void
replication_scanner_finish(yyscan_t yyscanner)
{
pfree(yyextra);
yylex_destroy(yyscanner);
}
/*
* Check to see if the first token of a command is a WalSender keyword.
*
* To keep repl_scanner.l minimal, we don't ask it to know every construct
* that the core lexer knows. Therefore, we daren't lex more than the
* first token of a general SQL command. That will usually look like an
* IDENT token here, although some other cases are possible.
*/
bool
replication_scanner_is_replication_command(yyscan_t yyscanner)
{
YYSTYPE dummy;
int first_token = replication_yylex(&dummy, yyscanner);
switch (first_token)
{
case K_IDENTIFY_SYSTEM:
case K_BASE_BACKUP:
case K_START_REPLICATION:
case K_CREATE_REPLICATION_SLOT:
case K_DROP_REPLICATION_SLOT:
case K_ALTER_REPLICATION_SLOT:
case K_READ_REPLICATION_SLOT:
case K_TIMELINE_HISTORY:
case K_UPLOAD_MANIFEST:
case K_SHOW:
/* Yes; push back the first token so we can parse later. */
yyextra->repl_pushed_back_token = first_token;
return true;
default:
/* Nope; we don't bother to push back the token. */
return false;
}
}
/*
* Interface functions to make flex use palloc() instead of malloc().
* It'd be better to make these static, but flex insists otherwise.
*/
void *
yyalloc(yy_size_t size, yyscan_t yyscanner)
{
return palloc(size);
}
void *
yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
{
if (ptr)
return repalloc(ptr, size);
else
return palloc(size);
}
void
yyfree(void *ptr, yyscan_t yyscanner)
{
if (ptr)
pfree(ptr);
}
[Dauer der Verarbeitung: 0.12 Sekunden, vorverarbeitet 2026-08-08]
|
2026-08-25
|
|
|
|
|
Neuigkeiten |
| Aktuelles |
| Motto des Tages |
|
Open Source Software |
|
|
|
Jenseits des Üblichen ....
|
|
Besucherstatistik |
|
|
| Statistik |
| #Sources=141584 |
| #Domains=752002 |
|
|