From: Michael Meskes Date: Wed, 22 May 2019 02:58:29 +0000 (+0200) Subject: Implement PREPARE AS statement for ECPG. X-Git-Tag: REL_12_BETA2~134 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1dc6ab465986a62b308dd1bb8da316b5ed9685a;p=postgresql Implement PREPARE AS statement for ECPG. 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 --- 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_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; 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; +}