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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers