summaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/preproc
diff options
context:
space:
mode:
authorMichael Meskes <meskes@postgresql.org>2003-06-13 10:50:58 +0000
committerMichael Meskes <meskes@postgresql.org>2003-06-13 10:50:58 +0000
commit26188e8c1751a2ef97fb6192fbc1bbc9f313a4d6 (patch)
tree664f93ef0ae0f58d9deaeb44cf5a35113fe605ab /src/interfaces/ecpg/preproc
parenta2d08b99c2a2d5fff3e883098588fb2fe2d664dc (diff)
- Enable FETCH without INTO.
- Compatibility functions for INFORMIX handling of DECLARE statement.
Diffstat (limited to 'src/interfaces/ecpg/preproc')
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.c5
-rw-r--r--src/interfaces/ecpg/preproc/extern.h3
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y49
3 files changed, 51 insertions, 6 deletions
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index d219047df7d..bba130792d2 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.72 2003/05/30 08:39:00 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.73 2003/06/13 10:50:57 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -359,6 +359,9 @@ main(int argc, char *const argv[])
/* and structure member lists */
memset(struct_member_list, 0, sizeof(struct_member_list));
+ /* and our variable counter for Informix compatibility */
+ ecpg_informix_var = 0;
+
/* finally the actual connection */
connection = NULL;
diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h
index bc0cceaae99..ae6c5bc2049 100644
--- a/src/interfaces/ecpg/preproc/extern.h
+++ b/src/interfaces/ecpg/preproc/extern.h
@@ -17,7 +17,8 @@ extern int braces_open,
auto_create_c,
system_includes,
ret_value,
- struct_level;
+ struct_level,
+ ecpg_informix_var;
extern char *descriptor_index;
extern char *descriptor_name;
extern char *connection;
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 83015d04a59..fa622f314bd 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.230 2003/06/11 06:39:12 meskes Exp $ */
+/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.231 2003/06/13 10:50:57 meskes Exp $ */
/* Copyright comment */
%{
@@ -11,6 +11,7 @@
*/
int struct_level = 0;
int braces_open; /* brace level counter */
+int ecpg_informix_var = 0;
char errortext[128];
char *connection = NULL;
char *input_filename = NULL;
@@ -141,6 +142,7 @@ make3_str(char *str1, char *str2, char *str3)
return(res_str);
}
+/* and the rest */
static char *
make_name(void)
{
@@ -186,6 +188,36 @@ create_questionmarks(char *name, bool array)
return(result);
}
+static char *
+adjust_informix(struct arguments *list)
+{
+ /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+ * This breaks standard and leads to some very dangerous programming.
+ * Since they do, we have to work around and accept their syntax as well.
+ * But we will do so ONLY in Informix mode.
+ * We have to change the variables to our own struct and just store the pointer instead of the variable */
+
+ struct arguments *ptr;
+ char *result = make_str("");
+
+ for (ptr = list; ptr != NULL; ptr = ptr->next)
+ {
+ char temp[sizeof(int)+sizeof(", &()")];
+ char *original_var;
+
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->variable->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+ ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+ }
+
+ return result;
+}
+
%}
%union {
@@ -1098,7 +1130,10 @@ opt_drop_behavior: CASCADE { $$ = make_str("cascade"); }
*
*****************************************************************************/
-ClosePortalStmt: CLOSE name { $$ = cat2_str(make_str("close"), $2); }
+ClosePortalStmt: CLOSE name
+ {
+ $$ = cat2_str(make_str("close"), $2);
+ }
;
/*****************************************************************************
@@ -1734,6 +1769,10 @@ FetchStmt: FETCH fetch_direction from_in name ecpg_into_using
{ $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
| FETCH name ecpg_into_using
{ $$ = cat2_str(make_str("fetch"), $2); }
+ | FETCH fetch_direction from_in name
+ { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
+ | FETCH name
+ { $$ = cat2_str(make_str("fetch"), $2); }
| MOVE fetch_direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE name
@@ -2630,10 +2669,12 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
this->argsinsert = argsinsert;
this->argsresult = argsresult;
argsinsert = argsresult = NULL;
-
cur = this;
- $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ if (compat == ECPG_COMPAT_INFORMIX)
+ $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ else
+ $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
}
;