aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/ecpg/preproc/descriptor.c14
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.addons47
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.c2
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.header17
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.trailer31
-rw-r--r--src/interfaces/ecpg/preproc/output.c3
-rw-r--r--src/interfaces/ecpg/preproc/variable.c25
7 files changed, 86 insertions, 53 deletions
diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c
index 9b87d07d09f..e8c7016bdc1 100644
--- a/src/interfaces/ecpg/preproc/descriptor.c
+++ b/src/interfaces/ecpg/preproc/descriptor.c
@@ -344,11 +344,17 @@ descriptor_variable(const char *name, int input)
struct variable *
sqlda_variable(const char *name)
{
- struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
-
- p->name = mm_strdup(name);
- p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
+ /*
+ * Presently, sqlda variables are only needed for the duration of the
+ * current statement. Rather than add infrastructure to manage them,
+ * let's just loc_alloc them.
+ */
+ struct variable *p = (struct variable *) loc_alloc(sizeof(struct variable));
+
+ p->name = loc_strdup(name);
+ p->type = (struct ECPGtype *) loc_alloc(sizeof(struct ECPGtype));
p->type->type = ECPGt_sqlda;
+ p->type->type_name = NULL;
p->type->size = NULL;
p->type->struct_sizeof = NULL;
p->type->u.element = NULL;
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index 935820c8d46..71f7ad26ad8 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -135,6 +135,7 @@ ECPG: rule stmt ViewStmt
fprintf(base_yyout, "{ ECPGdescribe(__LINE__, %d, %d, %s, %s,", compat, $1.input, connection ? connection : "NULL", $1.stmt_name);
dump_variables(argsresult, 1);
+ argsresult = NULL;
fputs("ECPGt_EORT);", base_yyout);
fprintf(base_yyout, "}");
output_line_number();
@@ -181,6 +182,7 @@ ECPG: rule stmt ViewStmt
if ((ptr = add_additional_variables(@1, true)) != NULL)
{
+ free(connection);
connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
output_statement(ptr->command, 0, ECPGst_normal);
ptr->opened = true;
@@ -247,15 +249,13 @@ ECPG: addon var_value NumericOnly
ECPG: addon fetch_args cursor_name
struct cursor *ptr = add_additional_variables(@1, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@1[0] == ':')
@$ = "$0";
ECPG: addon fetch_args from_in cursor_name
struct cursor *ptr = add_additional_variables(@2, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@2[0] == ':')
@$ = cat2_str(@1, "$0");
ECPG: addon fetch_args NEXT opt_from_in cursor_name
@@ -265,16 +265,14 @@ ECPG: addon fetch_args LAST_P opt_from_in cursor_name
ECPG: addon fetch_args ALL opt_from_in cursor_name
struct cursor *ptr = add_additional_variables(@3, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@3[0] == ':')
@$ = cat_str(3, @1, @2, "$0");
ECPG: addon fetch_args SignedIconst opt_from_in cursor_name
struct cursor *ptr = add_additional_variables(@3, false);
bool replace = false;
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@3[0] == ':')
{
@3 = "$0";
@@ -291,8 +289,7 @@ ECPG: addon fetch_args FORWARD ALL opt_from_in cursor_name
ECPG: addon fetch_args BACKWARD ALL opt_from_in cursor_name
struct cursor *ptr = add_additional_variables(@4, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@4[0] == ':')
@$ = cat_str(4, @1, @2, @3, "$0");
ECPG: addon fetch_args ABSOLUTE_P SignedIconst opt_from_in cursor_name
@@ -302,8 +299,7 @@ ECPG: addon fetch_args BACKWARD SignedIconst opt_from_in cursor_name
struct cursor *ptr = add_additional_variables(@4, false);
bool replace = false;
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
if (@4[0] == ':')
{
@4 = "$0";
@@ -412,8 +408,7 @@ ECPG: block ClosePortalStmt CLOSE cursor_name
{
if (strcmp(@2, ptr->name) == 0)
{
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
break;
}
}
@@ -483,8 +478,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @3[0] == ':' ? "$0" : @3;
struct cursor *ptr = add_additional_variables(@3, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "fetch forward", cursor_marker);
}
@@ -493,8 +487,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @4[0] == ':' ? "$0" : @4;
struct cursor *ptr = add_additional_variables(@4, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "fetch forward from", cursor_marker);
}
@@ -503,8 +496,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @3[0] == ':' ? "$0" : @3;
struct cursor *ptr = add_additional_variables(@3, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "fetch backward", cursor_marker);
}
@@ -513,8 +505,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @4[0] == ':' ? "$0" : @4;
struct cursor *ptr = add_additional_variables(@4, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "fetch backward from", cursor_marker);
}
@@ -523,8 +514,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @3[0] == ':' ? "$0" : @3;
struct cursor *ptr = add_additional_variables(@3, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "move forward", cursor_marker);
}
@@ -533,8 +523,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @4[0] == ':' ? "$0" : @4;
struct cursor *ptr = add_additional_variables(@4, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "move forward from", cursor_marker);
}
@@ -543,8 +532,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @3[0] == ':' ? "$0" : @3;
struct cursor *ptr = add_additional_variables(@3, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "move backward", cursor_marker);
}
@@ -553,8 +541,7 @@ ECPG: rule FetchStmt MOVE fetch_args
const char *cursor_marker = @4[0] == ':' ? "$0" : @4;
struct cursor *ptr = add_additional_variables(@4, false);
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
@$ = cat_str(2, "move backward from", cursor_marker);
}
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 73c37631acc..2fcc6f8f996 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -20,6 +20,7 @@ bool autocommit = false,
regression_mode = false,
auto_prepare = false;
+static const char *progname;
char *output_filename;
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
@@ -139,7 +140,6 @@ main(int argc, char *const argv[])
bool verbose = false,
header_mode = false;
struct _include_path *ip;
- const char *progname;
char my_exec_path[MAXPGPATH];
char include_path[MAXPGPATH];
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
index e79b6b0de8c..dde69a39695 100644
--- a/src/interfaces/ecpg/preproc/ecpg.header
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -71,6 +71,7 @@ struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
static struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};
static bool check_declared_list(const char *name);
+static void update_connection(const char *newconn);
/*
@@ -558,12 +559,26 @@ check_declared_list(const char *name)
{
if (connection && strcmp(ptr->connection, connection) != 0)
mmerror(PARSE_ERROR, ET_WARNING, "connection %s is overwritten with %s by DECLARE statement %s", connection, ptr->connection, name);
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
return true;
}
}
return false;
}
+
+/*
+ * If newconn isn't NULL, update the global "connection" variable to that;
+ * otherwise do nothing.
+ */
+static void
+update_connection(const char *newconn)
+{
+ if (newconn)
+ {
+ free(connection);
+ connection = mm_strdup(newconn);
+ }
+}
%}
%expect 0
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
index 321bcbccac7..6f94b832a03 100644
--- a/src/interfaces/ecpg/preproc/ecpg.trailer
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -77,6 +77,8 @@ CreateAsStmt: CREATE OptTemp TABLE create_as_target AS
at: AT connection_object
{
+ if (connection)
+ free(connection);
connection = mm_strdup(@2);
/*
@@ -560,13 +562,12 @@ type_declaration: S_TYPEDEF
var_declaration:
storage_declaration var_type
{
- actual_type[struct_level].type_storage = mm_strdup(@1);
+ actual_type[struct_level].type_storage = loc_strdup(@1);
actual_type[struct_level].type_enum = $2.type_enum;
- actual_type[struct_level].type_str = mm_strdup($2.type_str);
- actual_type[struct_level].type_dimension = mm_strdup($2.type_dimension);
- actual_type[struct_level].type_index = mm_strdup($2.type_index);
- actual_type[struct_level].type_sizeof =
- $2.type_sizeof ? mm_strdup($2.type_sizeof) : NULL;
+ actual_type[struct_level].type_str = $2.type_str;
+ actual_type[struct_level].type_dimension = $2.type_dimension;
+ actual_type[struct_level].type_index = $2.type_index;
+ actual_type[struct_level].type_sizeof = $2.type_sizeof;
actual_startline[struct_level] = hashline_number();
}
@@ -576,13 +577,12 @@ var_declaration:
}
| var_type
{
- actual_type[struct_level].type_storage = mm_strdup("");
+ actual_type[struct_level].type_storage = loc_strdup("");
actual_type[struct_level].type_enum = $1.type_enum;
- actual_type[struct_level].type_str = mm_strdup($1.type_str);
- actual_type[struct_level].type_dimension = mm_strdup($1.type_dimension);
- actual_type[struct_level].type_index = mm_strdup($1.type_index);
- actual_type[struct_level].type_sizeof =
- $1.type_sizeof ? mm_strdup($1.type_sizeof) : NULL;
+ actual_type[struct_level].type_str = $1.type_str;
+ actual_type[struct_level].type_dimension = $1.type_dimension;
+ actual_type[struct_level].type_index = $1.type_index;
+ actual_type[struct_level].type_sizeof = $1.type_sizeof;
actual_startline[struct_level] = hashline_number();
}
@@ -874,7 +874,7 @@ var_type: simple_type
/* Otherwise, it must be a user-defined typedef name */
struct typedefs *this = get_typedef(@1, false);
- $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? mm_strdup("") : mm_strdup(this->name);
+ $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? "" : this->name;
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_index = this->type->type_index;
@@ -1008,6 +1008,7 @@ s_struct_union_symbol: SQL_STRUCT symbol
{
$$.su = "struct";
$$.symbol = @2;
+ free(ECPGstruct_sizeof);
ECPGstruct_sizeof = mm_strdup(cat_str(3, "sizeof(",
cat2_str($$.su, $$.symbol),
")"));
@@ -1021,6 +1022,7 @@ s_struct_union_symbol: SQL_STRUCT symbol
s_struct_union: SQL_STRUCT
{
+ free(ECPGstruct_sizeof);
ECPGstruct_sizeof = mm_strdup(""); /* This must not be NULL to
* distinguish from simple types. */
@$ = "struct";
@@ -1700,18 +1702,21 @@ ECPGVar: SQL_VAR
ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
{
when_error.code = $3.code;
+ free(when_error.command);
when_error.command = $3.command ? mm_strdup($3.command) : NULL;
@$ = cat_str(3, "/* exec sql whenever sqlerror ", $3.str, "; */");
}
| SQL_WHENEVER NOT SQL_FOUND action
{
when_nf.code = $4.code;
+ free(when_nf.command);
when_nf.command = $4.command ? mm_strdup($4.command) : NULL;
@$ = cat_str(3, "/* exec sql whenever not found ", $4.str, "; */");
}
| SQL_WHENEVER SQL_SQLWARNING action
{
when_warn.code = $3.code;
+ free(when_warn.command);
when_warn.command = $3.command ? mm_strdup($3.command) : NULL;
@$ = cat_str(3, "/* exec sql whenever sql_warning ", $3.str, "; */");
}
diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c
index a18904f88bd..b190e9f0cea 100644
--- a/src/interfaces/ecpg/preproc/output.c
+++ b/src/interfaces/ecpg/preproc/output.c
@@ -155,10 +155,11 @@ output_statement(const char *stmt, int whenever_mode, enum ECPG_statement_type s
/* dump variables to C file */
dump_variables(argsinsert, 1);
+ argsinsert = NULL;
fputs("ECPGt_EOIT, ", base_yyout);
dump_variables(argsresult, 1);
+ argsresult = NULL;
fputs("ECPGt_EORT);", base_yyout);
- reset_variables();
whenever_action(whenever_mode | 2);
}
diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c
index e9bdfe56456..ec5afde7d69 100644
--- a/src/interfaces/ecpg/preproc/variable.c
+++ b/src/interfaces/ecpg/preproc/variable.c
@@ -315,10 +315,12 @@ remove_variables(int brace_level)
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
struct arguments *varptr,
- *prevvar;
+ *prevvar,
+ *nextvar;
- for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = varptr->next)
+ for (varptr = prevvar = ptr->argsinsert; varptr != NULL; varptr = nextvar)
{
+ nextvar = varptr->next;
if (p == varptr->variable)
{
/* remove from list */
@@ -326,10 +328,12 @@ remove_variables(int brace_level)
ptr->argsinsert = varptr->next;
else
prevvar->next = varptr->next;
+ free(varptr);
}
}
- for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = varptr->next)
+ for (varptr = prevvar = ptr->argsresult; varptr != NULL; varptr = nextvar)
{
+ nextvar = varptr->next;
if (p == varptr->variable)
{
/* remove from list */
@@ -337,6 +341,7 @@ remove_variables(int brace_level)
ptr->argsresult = varptr->next;
else
prevvar->next = varptr->next;
+ free(varptr);
}
}
}
@@ -376,7 +381,20 @@ struct arguments *argsresult = NULL;
void
reset_variables(void)
{
+ struct arguments *p,
+ *next;
+
+ for (p = argsinsert; p; p = next)
+ {
+ next = p->next;
+ free(p);
+ }
argsinsert = NULL;
+ for (p = argsresult; p; p = next)
+ {
+ next = p->next;
+ free(p);
+ }
argsresult = NULL;
}
@@ -435,6 +453,7 @@ remove_variable_from_list(struct arguments **list, struct variable *var)
prev->next = p->next;
else
*list = p->next;
+ free(p);
}
}