diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index 1ec2bf49f0..d63efd5459 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -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); diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 8e61339ae3..2db1b62058 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -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("")); + ecpg_do_epilogue(stmt); + return false; + } + /* initialize auto_mem struct */ ecpg_clear_auto_mem(); diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c index 0ef85c9de1..83de5e88b1 100644 --- a/src/interfaces/ecpg/ecpglib/prepare.c +++ b/src/interfaces/ecpg/ecpglib/prepare.c @@ -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) { diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 4a7e8e781f..cdeb43d18f 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -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 diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl index 9d8c708d0f..b6f0d0e67b 100644 --- a/src/interfaces/ecpg/preproc/check_rules.pl +++ b/src/interfaces/ecpg/preproc/check_rules.pl @@ -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'); diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons index e8052819b0..4e30375302 100644 --- a/src/interfaces/ecpg/preproc/ecpg.addons +++ b/src/interfaces/ecpg/preproc/ecpg.addons @@ -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_prepare_statement($1.name, $1.stmt); + output_statement($1.name, 1, ECPGst_execute); 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 + { + /* 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 + { + 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; diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index 366dc231ca..18b7bec6af 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -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; } diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index 6b46ae6cca..1851809e63 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -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); } diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl index 6f67a5e942..ceabe4e37c 100644 --- a/src/interfaces/ecpg/preproc/parse.pl +++ b/src/interfaces/ecpg/preproc/parse.pl @@ -58,6 +58,7 @@ my %replace_string = ( # ECPG-only replace_types are defined in ecpg-replace_types my %replace_types = ( 'PrepareStmt' => '', + 'ExecuteStmt' => '', 'opt_array_bounds' => '', # "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(); diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index 94377ff806..4d6afd93b8 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -106,6 +106,12 @@ struct prep char *type; }; +struct exec +{ + char *name; + char *type; +}; + struct this_type { enum ECPGttype type_enum; diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule index 939381e7bc..e034c5a420 100644 --- a/src/interfaces/ecpg/test/ecpg_schedule +++ b/src/interfaces/ecpg/test/ecpg_schedule @@ -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 index 0000000000..b925c4b5e5 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-prepareas.c @@ -0,0 +1,664 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include +#include +#include +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "prepareas.pgc" +#include +#include +#include + + +#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 index 0000000000..e69de29bb2 diff --git a/src/interfaces/ecpg/test/expected/sql-prepareas.stdout b/src/interfaces/ecpg/test/expected/sql-prepareas.stdout new file mode 100644 index 0000000000..d87544235e --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-prepareas.stdout @@ -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 diff --git a/src/interfaces/ecpg/test/sql/Makefile b/src/interfaces/ecpg/test/sql/Makefile index 4e018ccb52..876ca8df3e 100644 --- a/src/interfaces/ecpg/test/sql/Makefile +++ b/src/interfaces/ecpg/test/sql/Makefile @@ -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 index 0000000000..85f03d7e7d --- /dev/null +++ b/src/interfaces/ecpg/test/sql/prepareas.pgc @@ -0,0 +1,198 @@ +#include +#include +#include + +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; +}