]> granicus.if.org Git - postgresql/commitdiff
Implement PREPARE AS statement for ECPG.
authorMichael Meskes <meskes@postgresql.org>
Wed, 22 May 2019 02:58:29 +0000 (04:58 +0200)
committerMichael Meskes <meskes@postgresql.org>
Wed, 22 May 2019 02:58:29 +0000 (04:58 +0200)
Besides implementing the new statement this change fix some issues with the
parsing of PREPARE and EXECUTE statements. The different forms of these
statements are now all handled in a ujnified way.

Author: Matsumura-san <matsumura.ryo@jp.fujitsu.com>

16 files changed:
src/interfaces/ecpg/ecpglib/ecpglib_extern.h
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/include/ecpgtype.h
src/interfaces/ecpg/preproc/check_rules.pl
src/interfaces/ecpg/preproc/ecpg.addons
src/interfaces/ecpg/preproc/ecpg.header
src/interfaces/ecpg/preproc/output.c
src/interfaces/ecpg/preproc/parse.pl
src/interfaces/ecpg/preproc/type.h
src/interfaces/ecpg/test/ecpg_schedule
src/interfaces/ecpg/test/expected/sql-prepareas.c [new file with mode: 0644]
src/interfaces/ecpg/test/expected/sql-prepareas.stderr [new file with mode: 0644]
src/interfaces/ecpg/test/expected/sql-prepareas.stdout [new file with mode: 0644]
src/interfaces/ecpg/test/sql/Makefile
src/interfaces/ecpg/test/sql/prepareas.pgc [new file with mode: 0644]

index 1ec2bf49f055332ce32b30839571995354201050..d63efd5459ece122f463edca9d8443653f86e863 100644 (file)
@@ -231,6 +231,7 @@ char           *ecpg_prepared(const char *, struct connection *);
 bool           ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn);
 void           ecpg_log(const char *format,...) pg_attribute_printf(1, 2);
 bool           ecpg_auto_prepare(int, const char *, const int, char **, const char *);
+bool           ecpg_register_prepared_stmt(struct statement *);
 void           ecpg_init_sqlca(struct sqlca_t *sqlca);
 
 struct sqlda_compat *ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_MODE);
index 8e61339ae30c3864f89c83fb90408ffb46365f82..2db1b6205861cd0a05771191438a328c06c683f8 100644 (file)
@@ -488,6 +488,23 @@ sprintf_float_value(char *ptr, float value, const char *delim)
                sprintf(ptr, "%.15g%s", value, delim);
 }
 
+static char*
+convert_bytea_to_string(char *from_data, int from_len, int lineno)
+{
+       char *to_data;
+       int to_len = ecpg_hex_enc_len(from_len) + 4 + 1; /* backslash + 'x' + quote + quote */
+
+       to_data = ecpg_alloc(to_len, lineno);
+       if (!to_data)
+               return NULL;
+
+       strcpy(to_data, "'\\x");
+       ecpg_hex_encode(from_data, from_len, to_data + 3);
+       strcpy(to_data + 3 + ecpg_hex_enc_len(from_len), "\'");
+
+       return to_data;
+}
+
 bool
 ecpg_store_input(const int lineno, const bool force_indicator, const struct variable *var,
                                 char **tobeinserted_p, bool quote)
@@ -1433,6 +1450,36 @@ ecpg_build_params(struct statement *stmt)
                 */
                else if (stmt->command[position] == '0')
                {
+                       if (stmt->statement_type == ECPGst_prepare ||
+                               stmt->statement_type == ECPGst_exec_with_exprlist)
+                       {
+                               /* Add double quote both side for embedding statement name. */
+                               char *str = ecpg_alloc(strlen(tobeinserted) + 2 + 1, stmt->lineno);
+                               sprintf(str, "\"%s\"", tobeinserted);
+                               ecpg_free(tobeinserted);
+                               tobeinserted = str;
+                       }
+                       if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
+                       {
+                               ecpg_free_params(stmt, false);
+                               return false;
+                       }
+                       tobeinserted = NULL;
+               }
+               else if (stmt->statement_type == ECPGst_exec_with_exprlist)
+               {
+
+                       if (binary_format)
+                       {
+                               char *p = convert_bytea_to_string(tobeinserted, binary_length, stmt->lineno);
+                               if (!p)
+                               {
+                                       ecpg_free_params(stmt, false);
+                                       return false;
+                               }
+                               tobeinserted = p;
+                       }
+
                        if (!insert_tobeinserted(position, 2, stmt, tobeinserted))
                        {
                                ecpg_free_params(stmt, false);
@@ -1493,8 +1540,12 @@ ecpg_build_params(struct statement *stmt)
                        var = var->next;
        }
 
-       /* Check if there are unmatched things left. */
-       if (next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)
+       /*
+        * Check if there are unmatched things left.
+        * PREPARE AS has no parameter. Check other statement.
+        */
+       if (stmt->statement_type != ECPGst_prepare &&
+               next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0)
        {
                ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS,
                                   ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
@@ -1560,8 +1611,18 @@ ecpg_execute(struct statement *stmt)
                                                                                 (const int *) stmt->paramlengths,
                                                                                 (const int *) stmt->paramformats,
                                                                                 0);
+
                        ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno);
                }
+
+               if (stmt->statement_type == ECPGst_prepare)
+               {
+                       if(! ecpg_register_prepared_stmt(stmt))
+                       {
+                               ecpg_free_params(stmt, true);
+                               return false;
+                       }
+               }
        }
 
        ecpg_free_params(stmt, true);
@@ -1874,6 +1935,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
        enum ECPGttype type;
        struct variable **list;
        char       *prepname;
+       bool            is_prepared_name_set;
 
        *stmt_out = NULL;
 
@@ -1975,6 +2037,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
                        return false;
                }
        }
+       /* name of PREPARE AS will be set in loop of inlist */
 
        stmt->connection = con;
        stmt->lineno = lineno;
@@ -2004,6 +2067,8 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
         *------
         */
 
+       is_prepared_name_set = false;
+
        list = &(stmt->inlist);
 
        type = va_arg(args, enum ECPGttype);
@@ -2092,6 +2157,12 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
                                *list = var;
                        else
                                ptr->next = var;
+
+                       if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)
+                       {
+                               stmt->name = ecpg_strdup(var->value, lineno);
+                               is_prepared_name_set = true;
+                       }
                }
 
                type = va_arg(args, enum ECPGttype);
@@ -2105,6 +2176,13 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator,
                return false;
        }
 
+       if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare)
+       {
+               ecpg_raise(lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("<empty>"));
+               ecpg_do_epilogue(stmt);
+               return false;
+       }
+
        /* initialize auto_mem struct */
        ecpg_clear_auto_mem();
 
index 0ef85c9de18ad8cd0da145ab853909b40f638eee..83de5e88b1e2e6bdc3db3e77baf7c5b8f7fc9883 100644 (file)
@@ -56,6 +56,60 @@ isvarchar(unsigned char c)
        return false;
 }
 
+bool
+ecpg_register_prepared_stmt(struct statement *stmt)
+{
+       struct statement *prep_stmt;
+       struct prepared_statement *this;
+       struct connection *con = NULL;
+       struct prepared_statement *prev = NULL;
+       char *real_connection_name;
+       int lineno = stmt->lineno;
+
+    real_connection_name = ecpg_get_con_name_by_declared_name(stmt->name);
+    if (real_connection_name == NULL)
+        real_connection_name = stmt->connection->name;
+
+    con = ecpg_get_connection(real_connection_name);
+    if (!ecpg_init(con, real_connection_name, stmt->lineno))
+        return false;
+
+    /* check if we already have prepared this statement */
+    this = ecpg_find_prepared_statement(stmt->name, con, &prev);
+    if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
+        return false;
+
+    /* allocate new statement */
+    this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno);
+    if (!this)
+        return false;
+
+    prep_stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno);
+    if (!stmt)
+    {
+        ecpg_free(this);
+        return false;
+    }
+    memset(prep_stmt, 0, sizeof(struct statement));
+
+    /* create statement */
+    prep_stmt->lineno = lineno;
+    prep_stmt->connection = con;
+    prep_stmt->command = ecpg_strdup(stmt->command, lineno);
+    prep_stmt->inlist = prep_stmt->outlist = NULL;
+    this->name = ecpg_strdup(stmt->name, lineno);
+    this->stmt = prep_stmt;
+    this->prepared = true;
+
+    if (con->prep_stmts == NULL)
+        this->next = NULL;
+    else
+        this->next = con->prep_stmts;
+
+    con->prep_stmts = this;
+    return true;
+}
+
 static bool
 replace_variables(char **text, int lineno)
 {
index 4a7e8e781f7effa5dba83b6bd9904acc78e64743..cdeb43d18fa26c50973c95d427078ffe57d146c6 100644 (file)
@@ -97,7 +97,9 @@ enum ECPG_statement_type
        ECPGst_normal,
        ECPGst_execute,
        ECPGst_exec_immediate,
-       ECPGst_prepnormal
+       ECPGst_prepnormal,
+       ECPGst_prepare,
+       ECPGst_exec_with_exprlist
 };
 
 enum ECPG_cursor_statement_type
index 9d8c708d0f23f63f1a3c6e5ad849040cf5655e19..b6f0d0e67bc8588c928cb23843c8f398b767fac7 100644 (file)
@@ -39,8 +39,11 @@ my %replace_line = (
        'ExecuteStmtEXECUTEnameexecute_param_clause' =>
          'EXECUTE prepared_name execute_param_clause execute_rest',
 
-       'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'
-         => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
+       'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' =>
+         'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest' ,
+
+       'ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' =>
+         'CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest' ,
 
        'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
          'PREPARE prepared_name prep_type_clause AS PreparableStmt');
index e8052819b0dccd87fae06be61b566826983756e0..4e303753027d81d3170b6040c817dec6621d0a54 100644 (file)
@@ -20,13 +20,54 @@ ECPG: stmtSelectStmt block
 ECPG: stmtUpdateStmt block
        { output_statement($1, 1, ECPGst_prepnormal); }
 ECPG: stmtExecuteStmt block
-       { output_statement($1, 1, ECPGst_execute); }
-ECPG: stmtPrepareStmt block
        {
                if ($1.type == NULL || strlen($1.type) == 0)
+                       output_statement($1.name, 1, ECPGst_execute);
+               else
+               {
+                       if ($1.name[0] != '"')
+                               /* case of char_variable */
+                               add_variable_to_tail(&argsinsert, find_variable($1.name), &no_indicator);
+                       else
+                       {
+                               /* case of ecpg_ident or CSTRING */
+                               char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+                               char *str = mm_strdup($1.name + 1);
+
+                               /* It must be cut off double quotation because new_variable() double-quotes. */
+                               str[strlen(str) - 1] = '\0';
+                               sprintf(length, "%d", (int) strlen(str));
+                               add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
+                       }
+                       output_statement(cat_str(3, mm_strdup("execute"), mm_strdup("$0"), $1.type), 0, ECPGst_exec_with_exprlist);
+               }
+       }
+ECPG: stmtPrepareStmt block
+       {
+               if ($1.type == NULL)
                        output_prepare_statement($1.name, $1.stmt);
+               else if (strlen($1.type) == 0)
+               {
+                       char *stmt = cat_str(3, mm_strdup("\""), $1.stmt, mm_strdup("\""));
+                       output_prepare_statement($1.name, stmt);
+               }
                else
-                       output_statement(cat_str(5, mm_strdup("prepare"), $1.name, $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_normal);
+               {
+                       if ($1.name[0] != '"')
+                               /* case of char_variable */
+                               add_variable_to_tail(&argsinsert, find_variable($1.name), &no_indicator);
+                       else
+                       {
+                               char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+                               char *str = mm_strdup($1.name + 1);
+
+                               /* It must be cut off double quotation because new_variable() double-quotes. */
+                               str[strlen(str) - 1] = '\0';
+                               sprintf(length, "%d", (int) strlen(str));
+                               add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
+                       }
+                       output_statement(cat_str(5, mm_strdup("prepare"), mm_strdup("$0"), $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_prepare);
+               }
        }
 ECPG: stmtTransactionStmt block
        {
@@ -276,11 +317,15 @@ ECPG: cursor_namename rule
                        $1 = curname;
                        $$ = $1;
                }
+ECPG: ExplainableStmtExecuteStmt block
+       {
+               $$ = $1.name;
+       }
 ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
        {
                $$.name = $2;
                $$.type = $3;
-               $$.stmt = cat_str(3, mm_strdup("\""), $5, mm_strdup("\""));
+               $$.stmt = $5;
        }
        | PREPARE prepared_name FROM execstring
        {
@@ -289,7 +334,18 @@ ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
                $$.stmt = $4;
        }
 ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
-       { $$ = $2; }
+       {
+               $$.name = $2;
+               $$.type = $3;
+       }
+ECPG: ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block
+       {
+               $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table"),$4,mm_strdup("as execute"),$7,$8,$9);
+       }
+ECPG: ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block
+       {
+               $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table if not exists"),$7,mm_strdup("as execute"),$10,$11,$12);
+       }
 ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block
        {
                struct cursor *ptr, *this;
index 366dc231caf0ee7789f3b6cd034dfa4b5b7a3a8e..18b7bec6af86168b4142f288ae999e138557ebb7 100644 (file)
@@ -593,4 +593,5 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum,
        struct  fetch_desc      descriptor;
        struct  su_symbol       struct_union;
        struct  prep            prep;
+       struct  exec            exec;
 }
index 6b46ae6ccaf1259f5fb025e48a992a755def4b0d..1851809e63f9e2abe1f91dc92d50923b10bd0789 100644 (file)
@@ -128,24 +128,30 @@ static char *ecpg_statement_type_name[] = {
        "ECPGst_normal",
        "ECPGst_execute",
        "ECPGst_exec_immediate",
-       "ECPGst_prepnormal"
+       "ECPGst_prepnormal",
+       "ECPGst_prepare",
+       "ECPGst_exec_with_exprlist"
 };
 
 void
 output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st)
 {
        fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks);
+
+       if (st == ECPGst_prepnormal && !auto_prepare)
+               st = ECPGst_normal;
+
+       /*
+        * In following cases, stmt is CSTRING or char_variable. They must be output directly.
+        * - prepared_name of EXECUTE without exprlist
+        * - execstring of EXECUTE IMMEDIATE
+        */
+       fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]);
        if (st == ECPGst_execute || st == ECPGst_exec_immediate)
-       {
-               fprintf(base_yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt);
-       }
+               fprintf(base_yyout, "%s, ", stmt);
        else
        {
-               if (st == ECPGst_prepnormal && auto_prepare)
-                       fputs("ECPGst_prepnormal, \"", base_yyout);
-               else
-                       fputs("ECPGst_normal, \"", base_yyout);
-
+               fputs("\"", base_yyout);
                output_escaped_str(stmt, false);
                fputs("\", ", base_yyout);
        }
index 6f67a5e942985f25f30b9067ad1f14560ec21641..ceabe4e37c7b8fb9a40680ef8bea4b4e0cae1333 100644 (file)
@@ -58,6 +58,7 @@ my %replace_string = (
 # ECPG-only replace_types are defined in ecpg-replace_types
 my %replace_types = (
        'PrepareStmt'      => '<prep>',
+       'ExecuteStmt'      => '<exec>',
        'opt_array_bounds' => '<index>',
 
        # "ignore" means: do not create type and rules for this non-term-id
@@ -102,11 +103,13 @@ my %replace_line = (
          'RETURNING target_list opt_ecpg_into',
        'ExecuteStmtEXECUTEnameexecute_param_clause' =>
          'EXECUTE prepared_name execute_param_clause execute_rest',
-       'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'
-         => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
+       'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' =>
+         'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest',
+       'ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' =>
+         'CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest',
        'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
          'PREPARE prepared_name prep_type_clause AS PreparableStmt',
-       'var_nameColId' => 'ECPGColId',);
+       'var_nameColId' => 'ECPGColId');
 
 preload_addons();
 
index 94377ff8067fad6393c86ee32956a641c33032fe..4d6afd93b8a039c9feaab7a53741c9cc4cb6ab10 100644 (file)
@@ -106,6 +106,12 @@ struct prep
        char       *type;
 };
 
+struct exec
+{
+       char       *name;
+       char       *type;
+};
+
 struct this_type
 {
        enum ECPGttype type_enum;
index 939381e7bc54bc43f412a1481ea6f0e16b83342b..e034c5a420c3cdd78464146a1739634e99611f22 100644 (file)
@@ -52,6 +52,7 @@ test: sql/quote
 test: sql/show
 test: sql/insupd
 test: sql/parser
+test: sql/prepareas
 test: sql/declare
 test: thread/thread
 test: thread/thread_implicit
diff --git a/src/interfaces/ecpg/test/expected/sql-prepareas.c b/src/interfaces/ecpg/test/expected/sql-prepareas.c
new file mode 100644 (file)
index 0000000..b925c4b
--- /dev/null
@@ -0,0 +1,664 @@
+/* Processed by ecpg (regression mode) */
+/* These include files are added by the preprocessor */
+#include <ecpglib.h>
+#include <ecpgerrno.h>
+#include <sqlca.h>
+/* End of automatic include section */
+#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+#line 1 "prepareas.pgc"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#line 1 "regression.h"
+
+
+
+
+
+
+#line 5 "prepareas.pgc"
+
+/* exec sql whenever sqlerror  sqlprint ; */
+#line 6 "prepareas.pgc"
+
+
+static void
+check_result_of_insert(void)
+{
+       /* exec sql begin declare section */
+             
+       
+#line 12 "prepareas.pgc"
+ int ivar1 = 0 , ivar2 = 0 ;
+/* exec sql end declare section */
+#line 13 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select c1 , c2 from test", ECPGt_EOIT, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 15 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 15 "prepareas.pgc"
+
+       printf("%d %d\n", ivar1, ivar2);
+}
+
+int main(void)
+{
+       /* exec sql begin declare section */
+             
+           
+       
+#line 22 "prepareas.pgc"
+ int ivar1 = 1 , ivar2 = 2 ;
+#line 23 "prepareas.pgc"
+ char v_include_dq_name [ 16 ] , v_include_ws_name [ 16 ] , v_normal_name [ 16 ] , v_query [ 64 ] ;
+/* exec sql end declare section */
+#line 24 "prepareas.pgc"
+
+
+       strcpy(v_normal_name, "normal_name");
+       strcpy(v_include_dq_name, "include_\"_name");
+       strcpy(v_include_ws_name, "include_ _name");
+       strcpy(v_query, "insert into test values(?,?)");
+
+       /*
+        * preparing for test
+        */
+       { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); 
+#line 34 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 34 "prepareas.pgc"
+
+       { ECPGtrans(__LINE__, NULL, "begin");
+#line 35 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 35 "prepareas.pgc"
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table test ( c1 int , c2 int )", ECPGt_EOIT, ECPGt_EORT);
+#line 36 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 36 "prepareas.pgc"
+
+       { ECPGtrans(__LINE__, NULL, "commit work");
+#line 37 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 37 "prepareas.pgc"
+
+       { ECPGtrans(__LINE__, NULL, "begin");
+#line 38 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 38 "prepareas.pgc"
+
+
+       /*
+        * Non dynamic statement
+        */
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 43 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 43 "prepareas.pgc"
+
+       printf("+++++ Test for prepnormal +++++\n");
+       printf("insert into test values(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test values ( $1  , $2  )", 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 46 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 46 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 49 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 49 "prepareas.pgc"
+
+       printf("+++++ Test for execute immediate +++++\n");
+       printf("execute immediate \"insert into test values(1,2)\"\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_immediate, "insert into test values(1,2)", ECPGt_EOIT, ECPGt_EORT);
+#line 52 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 52 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       /*
+        * PREPARE FROM
+        */
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 58 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 58 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE ident FROM CString +++++\n");
+       printf("prepare ident_name from \"insert into test values(?,?)\"\n");
+       { ECPGprepare(__LINE__, NULL, 0, "ident_name", "insert into test values(?,?)");
+#line 61 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 61 "prepareas.pgc"
+
+       printf("execute ident_name using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "ident_name", 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 63 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 63 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 66 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 66 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE char_variable_normal_name FROM char_variable +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, v_normal_name, v_query);
+#line 69 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 69 "prepareas.pgc"
+
+       printf("execute :v_normal_name using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, v_normal_name, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 71 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 71 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 74 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 74 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE char_variable_inc_dq_name FROM char_variable +++++\n");
+       printf("prepare :v_include_dq_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, v_include_dq_name, v_query);
+#line 77 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 77 "prepareas.pgc"
+
+       printf("execute :v_include_dq_name using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, v_include_dq_name, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 79 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 79 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 82 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 82 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE char_variable_inc_ws_name FROM char_variable +++++\n");
+       printf("prepare :v_include_ws_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, v_include_ws_name, v_query);
+#line 85 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 85 "prepareas.pgc"
+
+       printf("execute :v_include_ws_name using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, v_include_ws_name, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 87 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 87 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 90 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 90 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE CString_inc_ws_name FROM char_variable +++++\n");
+       printf("prepare \"include_ _name\" from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, "include_ _name", v_query);
+#line 93 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 93 "prepareas.pgc"
+
+       printf("exec sql execute \"include_ _name\" using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "include_ _name", 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 95 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 95 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 98 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 98 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE CString_normal_name FROM char_variable +++++\n");
+       printf("prepare \"norma_name\" from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, "normal_name", v_query);
+#line 101 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 101 "prepareas.pgc"
+
+       printf("exec sql execute \"normal_name\" using :ivar1,:ivar2\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "normal_name", 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 103 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 103 "prepareas.pgc"
+
+       check_result_of_insert();
+
+       /*
+        * PREPARE AS
+        */
+       { ECPGdeallocate(__LINE__, 0, NULL, "ident_name");
+#line 109 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 109 "prepareas.pgc"
+
+       { ECPGdeallocate(__LINE__, 0, NULL, "normal_name");
+#line 110 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 110 "prepareas.pgc"
+
+       { ECPGdeallocate(__LINE__, 0, NULL, "include_ _name");
+#line 111 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 111 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 113 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 113 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE ident(typelist) AS +++++\n");
+       printf("prepare ident_name(int,int) as insert into test values($1,$2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_prepare, "prepare $0 ( int , int ) as insert into test values ( $1 , $2 )", 
+       ECPGt_const,"ident_name",(long)10,(long)1,strlen("ident_name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 116 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 116 "prepareas.pgc"
+
+       printf("execute ident_name(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_const,"ident_name",(long)10,(long)1,strlen("ident_name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 118 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 118 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "ident_name");
+#line 120 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 120 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 122 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 122 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE CString_normal_name(typelist) AS +++++\n");
+       printf("prepare \"normal_name\"(int,int) as insert into test values($1,$2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_prepare, "prepare $0 ( int , int ) as insert into test values ( $1 , $2 )", 
+       ECPGt_const,"normal_name",(long)11,(long)1,strlen("normal_name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 125 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 125 "prepareas.pgc"
+
+       printf("execute \"normal_name\"(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_const,"normal_name",(long)11,(long)1,strlen("normal_name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 127 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 127 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "normal_name");
+#line 129 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 129 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 131 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 131 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE CString_include_ws_name(typelist) AS +++++\n");
+       printf("prepare \"include_ _name\"(int,int) as insert into test values($1,$2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_prepare, "prepare $0 ( int , int ) as insert into test values ( $1 , $2 )", 
+       ECPGt_const,"include_ _name",(long)14,(long)1,strlen("include_ _name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 134 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 134 "prepareas.pgc"
+
+       printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_const,"include_ _name",(long)14,(long)1,strlen("include_ _name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 136 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 136 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "include_ _name");
+#line 138 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 138 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 140 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 140 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE char_variable_normal_name(typelist) AS +++++\n");
+       printf("prepare :v_normal_name(int,int) as insert into test values($1,$2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_prepare, "prepare $0 ( int , int ) as insert into test values ( $1 , $2 )", 
+       ECPGt_char,(v_normal_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 143 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 143 "prepareas.pgc"
+
+       printf("execute :v_normal_name(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_char,(v_normal_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 145 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 145 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "normal_name");
+#line 147 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 147 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 149 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 149 "prepareas.pgc"
+
+       printf("+++++ Test for PREPARE char_variable_include_ws_name(typelist) AS +++++\n");
+       printf("prepare :v_include_ws_name(int,int) as insert into test values($1,$2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_prepare, "prepare $0 ( int , int ) as insert into test values ( $1 , $2 )", 
+       ECPGt_char,(v_include_ws_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 152 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 152 "prepareas.pgc"
+
+       printf("execute :v_include_ws_name(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_char,(v_include_ws_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 154 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 154 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "include_ _name");
+#line 156 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 156 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 158 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 158 "prepareas.pgc"
+
+       printf("+++++ Test for EXECUTE :v_normal_name(const,const) +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, v_normal_name, v_query);
+#line 161 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 161 "prepareas.pgc"
+
+       printf("execute :v_normal_name(1,2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( 1 , 2 )", 
+       ECPGt_char,(v_normal_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 163 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 163 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "normal_name");
+#line 165 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 165 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 167 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 167 "prepareas.pgc"
+
+       printf("+++++ Test for EXECUTE :v_normal_name(expr,expr) +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, v_normal_name, v_query);
+#line 170 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 170 "prepareas.pgc"
+
+       printf("execute :v_normal_name(0+1,1+1)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( 0 + 1 , 1 + 1 )", 
+       ECPGt_char,(v_normal_name),(long)16,(long)1,(16)*sizeof(char), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 172 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 172 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "normal_name");
+#line 174 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 174 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 176 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 176 "prepareas.pgc"
+
+       printf("+++++ Test for combination PREPARE FROM and EXECUTE ident(typelist) +++++\n");
+       printf("prepare ident_name from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, "ident_name", v_query);
+#line 179 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 179 "prepareas.pgc"
+
+       printf("execute ident_name(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_const,"ident_name",(long)10,(long)1,strlen("ident_name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 181 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 181 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "ident_name");
+#line 183 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 183 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT);
+#line 185 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 185 "prepareas.pgc"
+
+       printf("+++++ Test for combination PREPARE FROM and EXECUTE CString_include_ws_name(typelist) +++++\n");
+       printf("prepare \"include_ _name\" from :v_query\n");
+       { ECPGprepare(__LINE__, NULL, 0, "include_ _name", v_query);
+#line 188 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 188 "prepareas.pgc"
+
+       printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_exec_with_exprlist, "execute $0 ( $1  , $2  )", 
+       ECPGt_const,"include_ _name",(long)14,(long)1,strlen("include_ _name"), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar1),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
+       ECPGt_int,&(ivar2),(long)1,(long)1,sizeof(int), 
+       ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+#line 190 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 190 "prepareas.pgc"
+
+       check_result_of_insert();
+       { ECPGdeallocate(__LINE__, 0, NULL, "include_ _name");
+#line 192 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 192 "prepareas.pgc"
+
+
+       { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test", ECPGt_EOIT, ECPGt_EORT);
+#line 194 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 194 "prepareas.pgc"
+
+       { ECPGtrans(__LINE__, NULL, "commit work");
+#line 195 "prepareas.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 195 "prepareas.pgc"
+
+
+       return 0;
+}
diff --git a/src/interfaces/ecpg/test/expected/sql-prepareas.stderr b/src/interfaces/ecpg/test/expected/sql-prepareas.stderr
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/interfaces/ecpg/test/expected/sql-prepareas.stdout b/src/interfaces/ecpg/test/expected/sql-prepareas.stdout
new file mode 100644 (file)
index 0000000..d875442
--- /dev/null
@@ -0,0 +1,66 @@
++++++ Test for prepnormal +++++
+insert into test values(:ivar1,:ivar2)
+1 2
++++++ Test for execute immediate +++++
+execute immediate "insert into test values(1,2)"
+1 2
++++++ Test for PREPARE ident FROM CString +++++
+prepare ident_name from "insert into test values(?,?)"
+execute ident_name using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE char_variable_normal_name FROM char_variable +++++
+prepare :v_normal_name from :v_query
+execute :v_normal_name using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE char_variable_inc_dq_name FROM char_variable +++++
+prepare :v_include_dq_name from :v_query
+execute :v_include_dq_name using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE char_variable_inc_ws_name FROM char_variable +++++
+prepare :v_include_ws_name from :v_query
+execute :v_include_ws_name using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE CString_inc_ws_name FROM char_variable +++++
+prepare "include_ _name" from :v_query
+exec sql execute "include_ _name" using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE CString_normal_name FROM char_variable +++++
+prepare "norma_name" from :v_query
+exec sql execute "normal_name" using :ivar1,:ivar2
+1 2
++++++ Test for PREPARE ident(typelist) AS +++++
+prepare ident_name(int,int) as insert into test values($1,$2)
+execute ident_name(:ivar1,:ivar2)
+1 2
++++++ Test for PREPARE CString_normal_name(typelist) AS +++++
+prepare "normal_name"(int,int) as insert into test values($1,$2)
+execute "normal_name"(:ivar1,:ivar2)
+1 2
++++++ Test for PREPARE CString_include_ws_name(typelist) AS +++++
+prepare "include_ _name"(int,int) as insert into test values($1,$2)
+execute "include_ _name"(:ivar1,:ivar2)
+1 2
++++++ Test for PREPARE char_variable_normal_name(typelist) AS +++++
+prepare :v_normal_name(int,int) as insert into test values($1,$2)
+execute :v_normal_name(:ivar1,:ivar2)
+1 2
++++++ Test for PREPARE char_variable_include_ws_name(typelist) AS +++++
+prepare :v_include_ws_name(int,int) as insert into test values($1,$2)
+execute :v_include_ws_name(:ivar1,:ivar2)
+1 2
++++++ Test for EXECUTE :v_normal_name(const,const) +++++
+prepare :v_normal_name from :v_query
+execute :v_normal_name(1,2)
+1 2
++++++ Test for EXECUTE :v_normal_name(expr,expr) +++++
+prepare :v_normal_name from :v_query
+execute :v_normal_name(0+1,1+1)
+1 2
++++++ Test for combination PREPARE FROM and EXECUTE ident(typelist) +++++
+prepare ident_name from :v_query
+execute ident_name(:ivar1,:ivar2)
+1 2
++++++ Test for combination PREPARE FROM and EXECUTE CString_include_ws_name(typelist) +++++
+prepare "include_ _name" from :v_query
+execute "include_ _name"(:ivar1,:ivar2)
+1 2
index 4e018ccb524ba23e37776ed04169f1071f41749f..876ca8df3e644c87bf6d92295a7820ac19be7603 100644 (file)
@@ -27,7 +27,8 @@ TESTS = array array.c \
         twophase twophase.c \
         insupd insupd.c \
                declare declare.c \
-               bytea bytea.c
+               bytea bytea.c \
+               prepareas prepareas.c
 
 all: $(TESTS)
 
diff --git a/src/interfaces/ecpg/test/sql/prepareas.pgc b/src/interfaces/ecpg/test/sql/prepareas.pgc
new file mode 100644 (file)
index 0000000..85f03d7
--- /dev/null
@@ -0,0 +1,198 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+exec sql include ../regression;
+exec sql whenever sqlerror sqlprint;
+
+static void
+check_result_of_insert(void)
+{
+       exec sql begin declare section;
+       int ivar1 = 0, ivar2 = 0;
+       exec sql end declare section;
+
+       exec sql select c1,c2 into :ivar1,:ivar2 from test;
+       printf("%d %d\n", ivar1, ivar2);
+}
+
+int main(void)
+{
+       exec sql begin declare section;
+       int ivar1 = 1, ivar2 = 2;
+       char v_include_dq_name[16], v_include_ws_name[16], v_normal_name[16], v_query[64];
+       exec sql end declare section;
+
+       strcpy(v_normal_name, "normal_name");
+       strcpy(v_include_dq_name, "include_\"_name");
+       strcpy(v_include_ws_name, "include_ _name");
+       strcpy(v_query, "insert into test values(?,?)");
+
+       /*
+        * preparing for test
+        */
+       exec sql connect to REGRESSDB1;
+       exec sql begin;
+       exec sql create table test (c1 int, c2 int);
+       exec sql commit work;
+       exec sql begin;
+
+       /*
+        * Non dynamic statement
+        */
+       exec sql truncate test;
+       printf("+++++ Test for prepnormal +++++\n");
+       printf("insert into test values(:ivar1,:ivar2)\n");
+       exec sql insert into test values(:ivar1,:ivar2);
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for execute immediate +++++\n");
+       printf("execute immediate \"insert into test values(1,2)\"\n");
+       exec sql execute immediate "insert into test values(1,2)";
+       check_result_of_insert();
+
+       /*
+        * PREPARE FROM
+        */
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE ident FROM CString +++++\n");
+       printf("prepare ident_name from \"insert into test values(?,?)\"\n");
+       exec sql prepare ident_name from "insert into test values(?,?)";
+       printf("execute ident_name using :ivar1,:ivar2\n");
+       exec sql execute ident_name using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE char_variable_normal_name FROM char_variable +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       exec sql prepare :v_normal_name from :v_query;
+       printf("execute :v_normal_name using :ivar1,:ivar2\n");
+       exec sql execute :v_normal_name using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE char_variable_inc_dq_name FROM char_variable +++++\n");
+       printf("prepare :v_include_dq_name from :v_query\n");
+       exec sql prepare :v_include_dq_name from :v_query;
+       printf("execute :v_include_dq_name using :ivar1,:ivar2\n");
+       exec sql execute :v_include_dq_name using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE char_variable_inc_ws_name FROM char_variable +++++\n");
+       printf("prepare :v_include_ws_name from :v_query\n");
+       exec sql prepare :v_include_ws_name from :v_query;
+       printf("execute :v_include_ws_name using :ivar1,:ivar2\n");
+       exec sql execute :v_include_ws_name using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE CString_inc_ws_name FROM char_variable +++++\n");
+       printf("prepare \"include_ _name\" from :v_query\n");
+       exec sql prepare "include_ _name" from :v_query;
+       printf("exec sql execute \"include_ _name\" using :ivar1,:ivar2\n");
+       exec sql execute "include_ _name" using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE CString_normal_name FROM char_variable +++++\n");
+       printf("prepare \"norma_name\" from :v_query\n");
+       exec sql prepare "normal_name" from :v_query;
+       printf("exec sql execute \"normal_name\" using :ivar1,:ivar2\n");
+       exec sql execute "normal_name" using :ivar1,:ivar2;
+       check_result_of_insert();
+
+       /*
+        * PREPARE AS
+        */
+       exec sql deallocate "ident_name";
+       exec sql deallocate "normal_name";
+       exec sql deallocate "include_ _name";
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE ident(typelist) AS +++++\n");
+       printf("prepare ident_name(int,int) as insert into test values($1,$2)\n");
+       exec sql prepare ident_name(int,int) as insert into test values($1,$2);
+       printf("execute ident_name(:ivar1,:ivar2)\n");
+       exec sql execute ident_name(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "ident_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE CString_normal_name(typelist) AS +++++\n");
+       printf("prepare \"normal_name\"(int,int) as insert into test values($1,$2)\n");
+       exec sql prepare "normal_name"(int,int) as insert into test values($1,$2);
+       printf("execute \"normal_name\"(:ivar1,:ivar2)\n");
+       exec sql execute "normal_name"(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "normal_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE CString_include_ws_name(typelist) AS +++++\n");
+       printf("prepare \"include_ _name\"(int,int) as insert into test values($1,$2)\n");
+       exec sql prepare "include_ _name"(int,int) as insert into test values($1,$2);
+       printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+       exec sql execute "include_ _name"(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "include_ _name";
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE char_variable_normal_name(typelist) AS +++++\n");
+       printf("prepare :v_normal_name(int,int) as insert into test values($1,$2)\n");
+       exec sql prepare :v_normal_name(int,int) as insert into test values($1,$2);
+       printf("execute :v_normal_name(:ivar1,:ivar2)\n");
+       exec sql execute :v_normal_name(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "normal_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for PREPARE char_variable_include_ws_name(typelist) AS +++++\n");
+       printf("prepare :v_include_ws_name(int,int) as insert into test values($1,$2)\n");
+       exec sql prepare :v_include_ws_name(int,int) as insert into test values($1,$2);
+       printf("execute :v_include_ws_name(:ivar1,:ivar2)\n");
+       exec sql execute :v_include_ws_name(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "include_ _name";
+
+       exec sql truncate test;
+       printf("+++++ Test for EXECUTE :v_normal_name(const,const) +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       exec sql prepare :v_normal_name from :v_query;
+       printf("execute :v_normal_name(1,2)\n");
+       exec sql execute :v_normal_name(1,2);
+       check_result_of_insert();
+       exec sql deallocate "normal_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for EXECUTE :v_normal_name(expr,expr) +++++\n");
+       printf("prepare :v_normal_name from :v_query\n");
+       exec sql prepare :v_normal_name from :v_query;
+       printf("execute :v_normal_name(0+1,1+1)\n");
+       exec sql execute :v_normal_name(0+1,1+1);
+       check_result_of_insert();
+       exec sql deallocate "normal_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for combination PREPARE FROM and EXECUTE ident(typelist) +++++\n");
+       printf("prepare ident_name from :v_query\n");
+       exec sql prepare ident_name from :v_query;
+       printf("execute ident_name(:ivar1,:ivar2)\n");
+       exec sql execute ident_name(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "ident_name";
+
+       exec sql truncate test;
+       printf("+++++ Test for combination PREPARE FROM and EXECUTE CString_include_ws_name(typelist) +++++\n");
+       printf("prepare \"include_ _name\" from :v_query\n");
+       exec sql prepare "include_ _name" from :v_query;
+       printf("execute \"include_ _name\"(:ivar1,:ivar2)\n");
+       exec sql execute "include_ _name"(:ivar1,:ivar2);
+       check_result_of_insert();
+       exec sql deallocate "include_ _name";
+
+       exec sql drop table test;
+       exec sql commit work;
+
+       return 0;
+}