1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

ecpg: put all string-valued tokens returned by pgc.l in local storage.

This didn't work earlier in the patch series (I think some of
the strings were ending up in data-type-related structures),
but apparently we're now clean enough for it.  This considerably
reduces process-lifespan memory leakage.

Discussion: https://postgr.es/m/2011420.1713493114@sss.pgh.pa.us
This commit is contained in:
Tom Lane
2024-11-27 12:44:03 -05:00
parent 0e6060790d
commit 85312d95e9
2 changed files with 24 additions and 22 deletions

View File

@ -203,7 +203,9 @@ filtered_base_yylex(void)
base_yytext = cur_yytext; base_yytext = cur_yytext;
/* Combine 3 tokens into 1 */ /* Combine 3 tokens into 1 */
base_yylval.str = psprintf("%s UESCAPE %s", base_yylval.str, escstr); base_yylval.str = make3_str(base_yylval.str,
" UESCAPE ",
escstr);
base_yylloc = loc_strdup(base_yylval.str); base_yylloc = loc_strdup(base_yylval.str);
/* Clear have_lookahead, thereby consuming all three tokens */ /* Clear have_lookahead, thereby consuming all three tokens */

View File

@ -641,26 +641,26 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
case xb: case xb:
if (literalbuf[strspn(literalbuf, "01")] != '\0') if (literalbuf[strspn(literalbuf, "01")] != '\0')
mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string literal"); mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string literal");
base_yylval.str = psprintf("b'%s'", literalbuf); base_yylval.str = make3_str("b'", literalbuf, "'");
return BCONST; return BCONST;
case xh: case xh:
if (literalbuf[strspn(literalbuf, "0123456789abcdefABCDEF")] != '\0') if (literalbuf[strspn(literalbuf, "0123456789abcdefABCDEF")] != '\0')
mmerror(PARSE_ERROR, ET_ERROR, "invalid hexadecimal string literal"); mmerror(PARSE_ERROR, ET_ERROR, "invalid hexadecimal string literal");
base_yylval.str = psprintf("x'%s'", literalbuf); base_yylval.str = make3_str("x'", literalbuf, "'");
return XCONST; return XCONST;
case xq: case xq:
/* fallthrough */ /* fallthrough */
case xqc: case xqc:
base_yylval.str = psprintf("'%s'", literalbuf); base_yylval.str = make3_str("'", literalbuf, "'");
return SCONST; return SCONST;
case xe: case xe:
base_yylval.str = psprintf("E'%s'", literalbuf); base_yylval.str = make3_str("E'", literalbuf, "'");
return SCONST; return SCONST;
case xn: case xn:
base_yylval.str = psprintf("N'%s'", literalbuf); base_yylval.str = make3_str("N'", literalbuf, "'");
return SCONST; return SCONST;
case xus: case xus:
base_yylval.str = psprintf("U&'%s'", literalbuf); base_yylval.str = make3_str("U&'", literalbuf, "'");
return USCONST; return USCONST;
default: default:
mmfatal(PARSE_ERROR, "unhandled previous state in xqs\n"); mmfatal(PARSE_ERROR, "unhandled previous state in xqs\n");
@ -724,7 +724,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
free(dolqstart); free(dolqstart);
dolqstart = NULL; dolqstart = NULL;
BEGIN(SQL); BEGIN(SQL);
base_yylval.str = mm_strdup(literalbuf); base_yylval.str = loc_strdup(literalbuf);
return SCONST; return SCONST;
} }
else else
@ -778,12 +778,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
* PREPARE and EXECUTE IMMEDIATE, which can certainly be * PREPARE and EXECUTE IMMEDIATE, which can certainly be
* longer than NAMEDATALEN. * longer than NAMEDATALEN.
*/ */
base_yylval.str = mm_strdup(literalbuf); base_yylval.str = loc_strdup(literalbuf);
return CSTRING; return CSTRING;
} }
<xdc>{xdstop} { <xdc>{xdstop} {
BEGIN(state_before_str_start); BEGIN(state_before_str_start);
base_yylval.str = mm_strdup(literalbuf); base_yylval.str = loc_strdup(literalbuf);
return CSTRING; return CSTRING;
} }
<xui>{dquote} { <xui>{dquote} {
@ -795,7 +795,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
* The backend will truncate the identifier here. We do * The backend will truncate the identifier here. We do
* not as it does not change the result. * not as it does not change the result.
*/ */
base_yylval.str = psprintf("U&\"%s\"", literalbuf); base_yylval.str = make3_str("U&\"", literalbuf, "\"");
return UIDENT; return UIDENT;
} }
<xd,xui>{xddouble} { <xd,xui>{xddouble} {
@ -971,7 +971,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
} }
} }
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return Op; return Op;
} }
@ -990,7 +990,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
} }
{ip} { {ip} {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return IP; return IP;
} }
} /* <SQL> */ } /* <SQL> */
@ -1003,7 +1003,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return process_integer_literal(yytext, &base_yylval, 16); return process_integer_literal(yytext, &base_yylval, 16);
} }
{numeric} { {numeric} {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return FCONST; return FCONST;
} }
{numericfail} { {numericfail} {
@ -1012,7 +1012,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return process_integer_literal(yytext, &base_yylval, 10); return process_integer_literal(yytext, &base_yylval, 10);
} }
{real} { {real} {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return FCONST; return FCONST;
} }
{realfail} { {realfail} {
@ -1048,7 +1048,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
} }
:{identifier}((("->"|\.){identifier})|(\[{array}\]))* { :{identifier}((("->"|\.){identifier})|(\[{array}\]))* {
base_yylval.str = mm_strdup(yytext + 1); base_yylval.str = loc_strdup(yytext + 1);
return CVARIABLE; return CVARIABLE;
} }
@ -1085,7 +1085,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
* to do so; that's just another way that ecpg could * to do so; that's just another way that ecpg could
* get out of step with the backend. * get out of step with the backend.
*/ */
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return IDENT; return IDENT;
} }
} }
@ -1124,7 +1124,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
} }
else else
{ {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return CPP_LINE; return CPP_LINE;
} }
} }
@ -1136,12 +1136,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
} }
else else
{ {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return CPP_LINE; return CPP_LINE;
} }
} }
<C,SQL>{cppline} { <C,SQL>{cppline} {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return CPP_LINE; return CPP_LINE;
} }
<C>{identifier} { <C>{identifier} {
@ -1167,7 +1167,7 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return kwvalue; return kwvalue;
else else
{ {
base_yylval.str = mm_strdup(yytext); base_yylval.str = loc_strdup(yytext);
return IDENT; return IDENT;
} }
} }
@ -1685,7 +1685,7 @@ process_integer_literal(const char *token, YYSTYPE *lval, int base)
if (*endptr != '\0' || errno == ERANGE) if (*endptr != '\0' || errno == ERANGE)
{ {
/* integer too large (or contains decimal pt), treat it as a float */ /* integer too large (or contains decimal pt), treat it as a float */
lval->str = mm_strdup(token); lval->str = loc_strdup(token);
return FCONST; return FCONST;
} }
lval->ival = val; lval->ival = val;