diff options
Diffstat (limited to 'src/interfaces/ecpg/ecpglib/execute.c')
-rw-r--r-- | src/interfaces/ecpg/ecpglib/execute.c | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 8e61339ae30..2db1b620586 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("<empty>")); + ecpg_do_epilogue(stmt); + return false; + } + /* initialize auto_mem struct */ ecpg_clear_auto_mem(); |