Hello this small patch replace redundant plpgsql_dstring functionality.
regards Pavel Stehule
*** ./src/pl/plpgsql/src/gram.y.orig 2009-05-27 12:56:10.000000000 +0200 --- ./src/pl/plpgsql/src/gram.y 2009-05-27 13:59:37.000000000 +0200 *************** *** 17,22 **** --- 17,23 ---- #include "plpgsql.h" #include "catalog/pg_type.h" + #include "lib/stringinfo.h" #include "parser/parser.h" *************** *** 1978,1984 **** { int tok; int lno; ! PLpgSQL_dstring ds; int parenlevel = 0; int nparams = 0; int params[MAX_EXPR_PARAMS]; --- 1979,1985 ---- { int tok; int lno; ! StringInfoData ds; int parenlevel = 0; int nparams = 0; int params[MAX_EXPR_PARAMS]; *************** *** 1986,1993 **** PLpgSQL_expr *expr; lno = plpgsql_scanner_lineno(); ! plpgsql_dstring_init(&ds); ! plpgsql_dstring_append(&ds, sqlstart); for (;;) { --- 1987,1994 ---- PLpgSQL_expr *expr; lno = plpgsql_scanner_lineno(); ! initStringInfo(&ds); ! appendStringInfoString(&ds, sqlstart); for (;;) { *************** *** 2029,2035 **** } if (plpgsql_SpaceScanned) ! plpgsql_dstring_append(&ds, " "); switch (tok) { --- 2030,2036 ---- } if (plpgsql_SpaceScanned) ! appendStringInfoChar(&ds, ' '); switch (tok) { *************** *** 2037,2061 **** snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.scalar->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; case T_ROW: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.row->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; case T_RECORD: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.rec->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; default: ! plpgsql_dstring_append(&ds, yytext); break; } } --- 2038,2062 ---- snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.scalar->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; case T_ROW: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.row->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; case T_RECORD: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.rec->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; default: ! appendStringInfoString(&ds, yytext); break; } } *************** *** 2065,2076 **** expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int)); expr->dtype = PLPGSQL_DTYPE_EXPR; ! expr->query = pstrdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) expr->params[nparams] = params[nparams]; ! plpgsql_dstring_free(&ds); if (valid_sql) check_sql_expr(expr->query); --- 2066,2077 ---- expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int)); expr->dtype = PLPGSQL_DTYPE_EXPR; ! expr->query = pstrdup(ds.data); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) expr->params[nparams] = params[nparams]; ! pfree(ds.data); if (valid_sql) check_sql_expr(expr->query); *************** *** 2082,2088 **** read_datatype(int tok) { int lno; ! PLpgSQL_dstring ds; char *type_name; PLpgSQL_type *result; bool needspace = false; --- 2083,2089 ---- read_datatype(int tok) { int lno; ! StringInfoData ds; char *type_name; PLpgSQL_type *result; bool needspace = false; *************** *** 2100,2106 **** return yylval.dtype; } ! plpgsql_dstring_init(&ds); while (tok != ';') { --- 2101,2107 ---- return yylval.dtype; } ! initStringInfo(&ds); while (tok != ';') { *************** *** 2122,2137 **** else if (tok == ')') parenlevel--; if (needspace) ! plpgsql_dstring_append(&ds, " "); needspace = true; ! plpgsql_dstring_append(&ds, yytext); tok = yylex(); } plpgsql_push_back_token(tok); ! type_name = plpgsql_dstring_get(&ds); if (type_name[0] == '\0') yyerror("missing data type declaration"); --- 2123,2138 ---- else if (tok == ')') parenlevel--; if (needspace) ! appendStringInfoChar(&ds, ' '); needspace = true; ! appendStringInfoString(&ds, yytext); tok = yylex(); } plpgsql_push_back_token(tok); ! type_name = ds.data; if (type_name[0] == '\0') yyerror("missing data type declaration"); *************** *** 2140,2146 **** result = plpgsql_parse_datatype(type_name); ! plpgsql_dstring_free(&ds); return result; } --- 2141,2147 ---- result = plpgsql_parse_datatype(type_name); ! pfree(ds.data); return result; } *************** *** 2148,2154 **** static PLpgSQL_stmt * make_execsql_stmt(const char *sqlstart, int lineno) { ! PLpgSQL_dstring ds; int nparams = 0; int params[MAX_EXPR_PARAMS]; char buf[32]; --- 2149,2155 ---- static PLpgSQL_stmt * make_execsql_stmt(const char *sqlstart, int lineno) { ! StringInfoData ds; int nparams = 0; int params[MAX_EXPR_PARAMS]; char buf[32]; *************** *** 2161,2168 **** bool have_into = false; bool have_strict = false; ! plpgsql_dstring_init(&ds); ! plpgsql_dstring_append(&ds, sqlstart); /* * We have to special-case the sequence INSERT INTO, because we don't want --- 2162,2169 ---- bool have_into = false; bool have_strict = false; ! initStringInfo(&ds); ! appendStringInfoString(&ds, sqlstart); /* * We have to special-case the sequence INSERT INTO, because we don't want *************** *** 2196,2202 **** } if (plpgsql_SpaceScanned) ! plpgsql_dstring_append(&ds, " "); switch (tok) { --- 2197,2203 ---- } if (plpgsql_SpaceScanned) ! appendStringInfoChar(&ds, ' '); switch (tok) { *************** *** 2204,2240 **** snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.scalar->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; case T_ROW: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.row->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; case T_RECORD: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.rec->dno, params, &nparams)); ! plpgsql_dstring_append(&ds, buf); break; default: ! plpgsql_dstring_append(&ds, yytext); break; } } expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int)); expr->dtype = PLPGSQL_DTYPE_EXPR; ! expr->query = pstrdup(plpgsql_dstring_get(&ds)); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) expr->params[nparams] = params[nparams]; ! plpgsql_dstring_free(&ds); check_sql_expr(expr->query); --- 2205,2241 ---- snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.scalar->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; case T_ROW: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.row->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; case T_RECORD: snprintf(buf, sizeof(buf), " $%d ", assign_expr_param(yylval.rec->dno, params, &nparams)); ! appendStringInfoString(&ds, buf); break; default: ! appendStringInfoString(&ds, yytext); break; } } expr = palloc(sizeof(PLpgSQL_expr) + sizeof(int) * nparams - sizeof(int)); expr->dtype = PLPGSQL_DTYPE_EXPR; ! expr->query = pstrdup(ds.data); expr->plan = NULL; expr->nparams = nparams; while(nparams-- > 0) expr->params[nparams] = params[nparams]; ! pfree(ds.data); check_sql_expr(expr->query); *************** *** 3023,3030 **** PLpgSQL_expr *expr = cwt->expr; int nparams = expr->nparams; PLpgSQL_expr *new_expr; ! PLpgSQL_dstring ds; ! char buff[32]; /* Must add the CASE variable as an extra param to expression */ if (nparams >= MAX_EXPR_PARAMS) --- 3024,3030 ---- PLpgSQL_expr *expr = cwt->expr; int nparams = expr->nparams; PLpgSQL_expr *new_expr; ! StringInfoData ds; /* Must add the CASE variable as an extra param to expression */ if (nparams >= MAX_EXPR_PARAMS) *************** *** 3041,3062 **** new_expr->nparams = nparams + 1; new_expr->params[nparams] = t_varno; /* And do the string hacking */ ! plpgsql_dstring_init(&ds); ! ! plpgsql_dstring_append(&ds, "SELECT $"); ! snprintf(buff, sizeof(buff), "%d", nparams + 1); ! plpgsql_dstring_append(&ds, buff); ! plpgsql_dstring_append(&ds, " IN ("); ! /* copy expression query without SELECT keyword */ ! Assert(strncmp(expr->query, "SELECT ", 7) == 0); ! plpgsql_dstring_append(&ds, expr->query + 7); ! plpgsql_dstring_append_char(&ds, ')'); ! new_expr->query = pstrdup(plpgsql_dstring_get(&ds)); ! plpgsql_dstring_free(&ds); pfree(expr->query); pfree(expr); --- 3041,3059 ---- new_expr->nparams = nparams + 1; new_expr->params[nparams] = t_varno; + /* copy expression query without SELECT keyword (expr->query + 7) */ + Assert(strncmp(expr->query, "SELECT ", 7) == 0); + /* And do the string hacking */ ! initStringInfo(&ds); ! appendStringInfo(&ds, "SELECT $%d IN(%s)", ! nparams + 1, ! expr->query + 7); ! new_expr->query = pstrdup(ds.data); ! pfree(ds.data); pfree(expr->query); pfree(expr); *** ./src/pl/plpgsql/src/pl_exec.c.orig 2009-05-27 12:56:28.000000000 +0200 --- ./src/pl/plpgsql/src/pl_exec.c 2009-05-27 13:52:04.000000000 +0200 *************** *** 22,27 **** --- 22,28 ---- #include "catalog/pg_type.h" #include "executor/spi_priv.h" #include "funcapi.h" + #include "lib/stringinfo.h" #include "nodes/nodeFuncs.h" #include "parser/scansup.h" #include "storage/proc.h" *************** *** 2388,2398 **** if (stmt->message) { ! PLpgSQL_dstring ds; ListCell *current_param; char *cp; ! plpgsql_dstring_init(&ds); current_param = list_head(stmt->params); for (cp = stmt->message; *cp; cp++) --- 2389,2399 ---- if (stmt->message) { ! StringInfoData ds; ListCell *current_param; char *cp; ! initStringInfo(&ds); current_param = list_head(stmt->params); for (cp = stmt->message; *cp; cp++) *************** *** 2410,2416 **** if (cp[1] == '%') { ! plpgsql_dstring_append_char(&ds, cp[1]); cp++; continue; } --- 2411,2417 ---- if (cp[1] == '%') { ! appendStringInfoChar(&ds, '%'); cp++; continue; } *************** *** 2429,2440 **** extval = "<NULL>"; else extval = convert_value_to_string(paramvalue, paramtypeid); ! plpgsql_dstring_append(&ds, extval); current_param = lnext(current_param); exec_eval_cleanup(estate); } else ! plpgsql_dstring_append_char(&ds, cp[0]); } /* --- 2430,2441 ---- extval = "<NULL>"; else extval = convert_value_to_string(paramvalue, paramtypeid); ! appendStringInfoString(&ds, extval); current_param = lnext(current_param); exec_eval_cleanup(estate); } else ! appendStringInfoChar(&ds, cp[0]); } /* *************** *** 2446,2453 **** (errcode(ERRCODE_SYNTAX_ERROR), errmsg("too many parameters specified for RAISE"))); ! err_message = plpgsql_dstring_get(&ds); ! /* No dstring_free here, the pfree(err_message) does it */ } foreach(lc, stmt->options) --- 2447,2454 ---- (errcode(ERRCODE_SYNTAX_ERROR), errmsg("too many parameters specified for RAISE"))); ! err_message = ds.data; ! /* No pfree(ds.data), the pfree(err_message) does it */ } foreach(lc, stmt->options) *** ./src/pl/plpgsql/src/pl_funcs.c.orig 2009-05-27 13:56:57.000000000 +0200 --- ./src/pl/plpgsql/src/pl_funcs.c 2009-05-27 13:58:44.000000000 +0200 *************** *** 29,118 **** /* ---------- - * plpgsql_dstring_init Dynamic string initialization - * ---------- - */ - void - plpgsql_dstring_init(PLpgSQL_dstring *ds) - { - ds->value = palloc(ds->alloc = 512); - ds->used = 1; - ds->value[0] = '\0'; - } - - - /* ---------- - * plpgsql_dstring_free Dynamic string destruction - * ---------- - */ - void - plpgsql_dstring_free(PLpgSQL_dstring *ds) - { - pfree(ds->value); - } - - static void - plpgsql_dstring_expand(PLpgSQL_dstring *ds, int needed) - { - /* Don't allow truncating the string */ - Assert(needed > ds->alloc); - Assert(ds->used <= ds->alloc); - - /* Might have to double more than once, if needed is large */ - do - { - ds->alloc *= 2; - } while (needed > ds->alloc); - ds->value = repalloc(ds->value, ds->alloc); - } - - /* ---------- - * plpgsql_dstring_append Dynamic string extending - * ---------- - */ - void - plpgsql_dstring_append(PLpgSQL_dstring *ds, const char *str) - { - int len = strlen(str); - int needed = ds->used + len; - - if (needed > ds->alloc) - plpgsql_dstring_expand(ds, needed); - - memcpy(&(ds->value[ds->used - 1]), str, len); - ds->used += len; - ds->value[ds->used - 1] = '\0'; - } - - /* ---------- - * plpgsql_dstring_append_char Append a single character - * to a dynamic string - * ---------- - */ - void - plpgsql_dstring_append_char(PLpgSQL_dstring *ds, char c) - { - if (ds->used == ds->alloc) - plpgsql_dstring_expand(ds, ds->used + 1); - - ds->value[ds->used - 1] = c; - ds->value[ds->used] = '\0'; - ds->used++; - } - - - /* ---------- - * plpgsql_dstring_get Dynamic string get value - * ---------- - */ - char * - plpgsql_dstring_get(PLpgSQL_dstring *ds) - { - return ds->value; - } - - - /* ---------- * plpgsql_ns_init Initialize the namestack * ---------- */ --- 29,34 ---- *** ./src/pl/plpgsql/src/plpgsql.h.orig 2009-05-27 12:56:41.000000000 +0200 --- ./src/pl/plpgsql/src/plpgsql.h 2009-05-27 13:57:55.000000000 +0200 *************** *** 148,161 **** typedef struct - { /* Dynamic string control structure */ - int alloc; - int used; /* Including NUL terminator */ - char *value; - } PLpgSQL_dstring; - - - typedef struct { /* Postgres data type */ char *typname; /* (simple) name of the type */ Oid typoid; /* OID of the data type */ --- 148,153 ---- *************** *** 852,867 **** SubTransactionId parentSubid, void *arg); /* ---------- - * Functions for the dynamic string handling in pl_funcs.c - * ---------- - */ - extern void plpgsql_dstring_init(PLpgSQL_dstring *ds); - extern void plpgsql_dstring_free(PLpgSQL_dstring *ds); - extern void plpgsql_dstring_append(PLpgSQL_dstring *ds, const char *str); - extern void plpgsql_dstring_append_char(PLpgSQL_dstring *ds, char c); - extern char *plpgsql_dstring_get(PLpgSQL_dstring *ds); - - /* ---------- * Functions for namestack handling in pl_funcs.c * ---------- */ --- 844,849 ----
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers