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;
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();
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;
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
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";
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
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";
{
if (strcmp(@2, ptr->name) == 0)
{
- if (ptr->connection)
- connection = mm_strdup(ptr->connection);
+ update_connection(ptr->connection);
break;
}
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
regression_mode = false,
auto_prepare = false;
+static const char *progname;
char *output_filename;
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
bool verbose = false,
header_mode = false;
struct _include_path *ip;
- const char *progname;
char my_exec_path[MAXPGPATH];
char include_path[MAXPGPATH];
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);
/*
{
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
at: AT connection_object
{
+ if (connection)
+ free(connection);
connection = mm_strdup(@2);
/*
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();
}
}
| 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();
}
/* 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;
{
$$.su = "struct";
$$.symbol = @2;
+ free(ECPGstruct_sizeof);
ECPGstruct_sizeof = mm_strdup(cat_str(3, "sizeof(",
cat2_str($$.su, $$.symbol),
")"));
s_struct_union: SQL_STRUCT
{
+ free(ECPGstruct_sizeof);
ECPGstruct_sizeof = mm_strdup(""); /* This must not be NULL to
* distinguish from simple types. */
@$ = "struct";
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, "; */");
}
/* 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);
}
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 */
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 */
ptr->argsresult = varptr->next;
else
prevvar->next = varptr->next;
+ free(varptr);
}
}
}
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;
}
prev->next = p->next;
else
*list = p->next;
+ free(p);
}
}