mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
Add DECLARE STATEMENT support to ECPG.
DECLARE STATEMENT is a statement that lets users declare an identifier pointing at a connection. This identifier will be used in other embedded dynamic SQL statement such as PREPARE, EXECUTE, DECLARE CURSOR and so on. When connecting to a non-default connection, the AT clause can be used in a DECLARE STATEMENT once and is no longer needed in every dynamic SQL statement. This makes ECPG applications easier and more efficient. Moreover, writing code without designating connection explicitly improves portability. Authors: Ideriha-san ("Ideriha, Takeshi" <ideriha.takeshi@jp.fujitsu.com>) Kuroda-san ("Kuroda, Hayato" <kuroda.hayato@jp.fujitsu.com>) Discussion: https://postgr.es/m4E72940DA2BF16479384A86D54D0988A565669DF@G01JPEXMBKW04
This commit is contained in:
@@ -28,6 +28,7 @@ struct _include_path *include_paths = NULL;
|
||||
struct cursor *cur = NULL;
|
||||
struct typedefs *types = NULL;
|
||||
struct _defines *defines = NULL;
|
||||
struct declared_name_st *g_declared_list = NULL;
|
||||
|
||||
static void
|
||||
help(const char *progname)
|
||||
@@ -111,6 +112,48 @@ add_preprocessor_define(char *define)
|
||||
defines->next = pd;
|
||||
}
|
||||
|
||||
static void
|
||||
free_argument(struct arguments *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
free_argument(arg->next);
|
||||
|
||||
/*
|
||||
* Don't free variables in it because the original codes don't free it either
|
||||
* variables are static structures instead of allocating
|
||||
*/
|
||||
free(arg);
|
||||
}
|
||||
|
||||
static void
|
||||
free_cursor(struct cursor *c)
|
||||
{
|
||||
if (c == NULL)
|
||||
return;
|
||||
|
||||
free_cursor(c->next);
|
||||
free_argument(c->argsinsert);
|
||||
free_argument(c->argsresult);
|
||||
|
||||
free(c->name);
|
||||
free(c->function);
|
||||
free(c->command);
|
||||
free(c->prepared_name);
|
||||
free(c);
|
||||
}
|
||||
|
||||
static void
|
||||
free_declared_stmt(struct declared_name_st *st)
|
||||
{
|
||||
if (st == NULL)
|
||||
return;
|
||||
|
||||
free_declared_stmt(st->next);
|
||||
free(st);
|
||||
}
|
||||
|
||||
#define ECPG_GETOPT_LONG_REGRESSION 1
|
||||
int
|
||||
main(int argc, char *const argv[])
|
||||
@@ -348,29 +391,18 @@ main(int argc, char *const argv[])
|
||||
struct typedefs *typeptr;
|
||||
|
||||
/* remove old cursor definitions if any are still there */
|
||||
for (ptr = cur; ptr != NULL;)
|
||||
if (cur)
|
||||
{
|
||||
struct cursor *this = ptr;
|
||||
struct arguments *l1,
|
||||
*l2;
|
||||
|
||||
free(ptr->command);
|
||||
free(ptr->connection);
|
||||
free(ptr->name);
|
||||
for (l1 = ptr->argsinsert; l1; l1 = l2)
|
||||
{
|
||||
l2 = l1->next;
|
||||
free(l1);
|
||||
}
|
||||
for (l1 = ptr->argsresult; l1; l1 = l2)
|
||||
{
|
||||
l2 = l1->next;
|
||||
free(l1);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
free(this);
|
||||
free_cursor(cur);
|
||||
cur = NULL;
|
||||
}
|
||||
|
||||
/* remove old declared statements if any are still there */
|
||||
if (g_declared_list)
|
||||
{
|
||||
free_declared_stmt(g_declared_list);
|
||||
g_declared_list = NULL;
|
||||
}
|
||||
cur = NULL;
|
||||
|
||||
/* remove non-pertinent old defines as well */
|
||||
while (defines && !defines->pertinent)
|
||||
@@ -487,6 +519,18 @@ main(int argc, char *const argv[])
|
||||
|
||||
free(input_filename);
|
||||
}
|
||||
|
||||
if(g_declared_list)
|
||||
{
|
||||
free_declared_stmt(g_declared_list);
|
||||
g_declared_list = NULL;
|
||||
}
|
||||
|
||||
if(cur)
|
||||
{
|
||||
free_cursor(cur);
|
||||
cur = NULL;
|
||||
}
|
||||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
Reference in New Issue
Block a user