ecpg: put all string-valued tokens returned by pgc.l in local storage.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 27 Nov 2024 17:44:03 +0000 (12:44 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 27 Nov 2024 17:50:23 +0000 (12:50 -0500)
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

src/interfaces/ecpg/preproc/parser.c
src/interfaces/ecpg/preproc/pgc.l

index 373c93fc04ae355b3f84d24abd15a746bd59a80a..181417fb39c300c25a4acc4c829b9c357760d893 100644 (file)
@@ -203,7 +203,9 @@ filtered_base_yylex(void)
                                base_yytext = cur_yytext;
 
                                /* 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);
 
                                /* Clear have_lookahead, thereby consuming all three tokens */
index f3c03482aec61956691f30426f61510920c5c702..82708013ee6bae636e122b1d466eda3ac8de7cb1 100644 (file)
@@ -641,26 +641,26 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                                case xb:
                                                        if (literalbuf[strspn(literalbuf, "01")] != '\0')
                                                                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;
                                                case xh:
                                                        if (literalbuf[strspn(literalbuf, "0123456789abcdefABCDEF")] != '\0')
                                                                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;
                                                case xq:
                                                        /* fallthrough */
                                                case xqc:
-                                                       base_yylval.str = psprintf("'%s'", literalbuf);
+                                                       base_yylval.str = make3_str("'", literalbuf, "'");
                                                        return SCONST;
                                                case xe:
-                                                       base_yylval.str = psprintf("E'%s'", literalbuf);
+                                                       base_yylval.str = make3_str("E'", literalbuf, "'");
                                                        return SCONST;
                                                case xn:
-                                                       base_yylval.str = psprintf("N'%s'", literalbuf);
+                                                       base_yylval.str = make3_str("N'", literalbuf, "'");
                                                        return SCONST;
                                                case xus:
-                                                       base_yylval.str = psprintf("U&'%s'", literalbuf);
+                                                       base_yylval.str = make3_str("U&'", literalbuf, "'");
                                                        return USCONST;
                                                default:
                                                        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);
                                                dolqstart = NULL;
                                                BEGIN(SQL);
-                                               base_yylval.str = mm_strdup(literalbuf);
+                                               base_yylval.str = loc_strdup(literalbuf);
                                                return SCONST;
                                        }
                                        else
@@ -778,12 +778,12 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                         * PREPARE and EXECUTE IMMEDIATE, which can certainly be
                                         * longer than NAMEDATALEN.
                                         */
-                                       base_yylval.str = mm_strdup(literalbuf);
+                                       base_yylval.str = loc_strdup(literalbuf);
                                        return CSTRING;
                                }
 <xdc>{xdstop}  {
                                        BEGIN(state_before_str_start);
-                                       base_yylval.str = mm_strdup(literalbuf);
+                                       base_yylval.str = loc_strdup(literalbuf);
                                        return CSTRING;
                                }
 <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
                                         * not as it does not change the result.
                                         */
-                                       base_yylval.str = psprintf("U&\"%s\"", literalbuf);
+                                       base_yylval.str = make3_str("U&\"", literalbuf, "\"");
                                        return UIDENT;
                                }
 <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;
                                }
 
@@ -990,7 +990,7 @@ cppline                     {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                }
 
 {ip}                   {
-                                       base_yylval.str = mm_strdup(yytext);
+                                       base_yylval.str = loc_strdup(yytext);
                                        return IP;
                                }
 }  /* <SQL> */
@@ -1003,7 +1003,7 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                        return process_integer_literal(yytext, &base_yylval, 16);
                                }
 {numeric}              {
-                                       base_yylval.str = mm_strdup(yytext);
+                                       base_yylval.str = loc_strdup(yytext);
                                        return FCONST;
                                }
 {numericfail}  {
@@ -1012,7 +1012,7 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                        return process_integer_literal(yytext, &base_yylval, 10);
                                }
 {real}                 {
-                                       base_yylval.str = mm_strdup(yytext);
+                                       base_yylval.str = loc_strdup(yytext);
                                        return FCONST;
                                }
 {realfail}             {
@@ -1048,7 +1048,7 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                }
 
 :{identifier}((("->"|\.){identifier})|(\[{array}\]))*  {
-                                       base_yylval.str = mm_strdup(yytext + 1);
+                                       base_yylval.str = loc_strdup(yytext + 1);
                                        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
                                                 * get out of step with the backend.
                                                 */
-                                               base_yylval.str = mm_strdup(yytext);
+                                               base_yylval.str = loc_strdup(yytext);
                                                return IDENT;
                                        }
                                }
@@ -1124,7 +1124,7 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                        }
                                        else
                                        {
-                                               base_yylval.str = mm_strdup(yytext);
+                                               base_yylval.str = loc_strdup(yytext);
                                                return CPP_LINE;
                                        }
                                }
@@ -1136,12 +1136,12 @@ cppline                 {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                        }
                                        else
                                        {
-                                               base_yylval.str = mm_strdup(yytext);
+                                               base_yylval.str = loc_strdup(yytext);
                                                return CPP_LINE;
                                        }
                                }
 <C,SQL>{cppline} {
-                                       base_yylval.str = mm_strdup(yytext);
+                                       base_yylval.str = loc_strdup(yytext);
                                        return CPP_LINE;
                                }
 <C>{identifier}        {
@@ -1167,7 +1167,7 @@ cppline                   {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                                                        return kwvalue;
                                                else
                                                {
-                                                       base_yylval.str = mm_strdup(yytext);
+                                                       base_yylval.str = loc_strdup(yytext);
                                                        return IDENT;
                                                }
                                        }
@@ -1685,7 +1685,7 @@ process_integer_literal(const char *token, YYSTYPE *lval, int base)
        if (*endptr != '\0' || errno == ERANGE)
        {
                /* integer too large (or contains decimal pt), treat it as a float */
-               lval->str = mm_strdup(token);
+               lval->str = loc_strdup(token);
                return FCONST;
        }
        lval->ival = val;