diff options
Diffstat (limited to 'src/interfaces/ecpg/ecpglib/execute.c')
-rw-r--r-- | src/interfaces/ecpg/ecpglib/execute.c | 170 |
1 files changed, 141 insertions, 29 deletions
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 2bdb558fabd..67681956b09 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -804,6 +804,20 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari *tobeinserted_p = mallocedval; } break; + + case ECPGt_bytea: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); + + if (!(mallocedval = (char *) ecpg_alloc(variable->len, lineno))) + return false; + + memcpy(mallocedval, variable->arr, variable->len); + *tobeinserted_p = mallocedval; + } + break; + case ECPGt_varchar: { struct ECPGgeneric_varchar *variable = @@ -1046,6 +1060,30 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari return true; } +static void +print_param_value(char *value, int len, int is_binary, int lineno, int nth) +{ + char *value_s; + bool malloced = false; + + if (value == NULL) + value_s = "null"; + else if (! is_binary) + value_s = value; + else + { + value_s = ecpg_alloc(ecpg_hex_enc_len(len), lineno); + ecpg_hex_encode(value, len, value_s); + malloced = true; + } + + ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", + lineno, nth, value_s); + + if (malloced) + ecpg_free(value_s); +} + void ecpg_free_params(struct statement *stmt, bool print) { @@ -1054,11 +1092,16 @@ ecpg_free_params(struct statement *stmt, bool print) for (n = 0; n < stmt->nparams; n++) { if (print) - ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", stmt->lineno, n + 1, stmt->paramvalues[n] ? stmt->paramvalues[n] : "null"); + print_param_value(stmt->paramvalues[n], stmt->paramlengths[n], + stmt->paramformats[n], stmt->lineno, n + 1); ecpg_free(stmt->paramvalues[n]); } ecpg_free(stmt->paramvalues); + ecpg_free(stmt->paramlengths); + ecpg_free(stmt->paramformats); stmt->paramvalues = NULL; + stmt->paramlengths = NULL; + stmt->paramformats = NULL; stmt->nparams = 0; } @@ -1094,6 +1137,53 @@ insert_tobeinserted(int position, int ph_len, struct statement *stmt, char *tobe return true; } +static bool +store_input_from_desc(struct statement *stmt, struct descriptor_item *desc_item, + char **tobeinserted) +{ + struct variable var; + + /* + * In case of binary data, only allocate memory and memcpy because + * binary data have been already stored into desc_item->data with + * ecpg_store_input() at ECPGset_desc(). + */ + if (desc_item->is_binary) + { + if (!(*tobeinserted = ecpg_alloc(desc_item->data_len, stmt->lineno))) + return false; + memcpy(*tobeinserted, desc_item->data, desc_item->data_len); + return true; + } + + var.type = ECPGt_char; + var.varcharsize = strlen(desc_item->data); + var.value = desc_item->data; + var.pointer = &(desc_item->data); + var.arrsize = 1; + var.offset = 0; + + if (!desc_item->indicator) + { + var.ind_type = ECPGt_NO_INDICATOR; + var.ind_value = var.ind_pointer = NULL; + var.ind_varcharsize = var.ind_arrsize = var.ind_offset = 0; + } + else + { + var.ind_type = ECPGt_int; + var.ind_value = &(desc_item->indicator); + var.ind_pointer = &(var.ind_value); + var.ind_varcharsize = var.ind_arrsize = 1; + var.ind_offset = 0; + } + + if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &var, tobeinserted, false)) + return false; + + return true; +} + /* * ecpg_build_params * Build statement parameters @@ -1125,8 +1215,13 @@ ecpg_build_params(struct statement *stmt) { char *tobeinserted; int counter = 1; + bool binary_format; + int binary_length; + tobeinserted = NULL; + binary_length = 0; + binary_format = false; /* * A descriptor is a special case since it contains many variables but @@ -1138,7 +1233,6 @@ ecpg_build_params(struct statement *stmt) * We create an additional variable list here, so the same logic * applies. */ - struct variable desc_inlist; struct descriptor *desc; struct descriptor_item *desc_item; @@ -1149,33 +1243,18 @@ ecpg_build_params(struct statement *stmt) desc_counter++; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { - if (desc_item->num == desc_counter) - { - desc_inlist.type = ECPGt_char; - desc_inlist.value = desc_item->data; - desc_inlist.pointer = &(desc_item->data); - desc_inlist.varcharsize = strlen(desc_item->data); - desc_inlist.arrsize = 1; - desc_inlist.offset = 0; - if (!desc_item->indicator) - { - desc_inlist.ind_type = ECPGt_NO_INDICATOR; - desc_inlist.ind_value = desc_inlist.ind_pointer = NULL; - desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0; - } - else - { - desc_inlist.ind_type = ECPGt_int; - desc_inlist.ind_value = &(desc_item->indicator); - desc_inlist.ind_pointer = &(desc_inlist.ind_value); - desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1; - desc_inlist.ind_offset = 0; - } - if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false)) - return false; + if (desc_item->num != desc_counter) + continue; - break; + if (!store_input_from_desc(stmt, desc_item, &tobeinserted)) + return false; + + if (desc_item->is_binary) + { + binary_length = desc_item->data_len; + binary_format = true; } + break; } if (desc->count == desc_counter) desc_counter = 0; @@ -1298,6 +1377,12 @@ ecpg_build_params(struct statement *stmt) { if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false)) return false; + + if (var->type == ECPGt_bytea) + { + binary_length = ((struct ECPGgeneric_varchar *) (var->value))->len; + binary_format = true; + } } /* @@ -1351,16 +1436,32 @@ ecpg_build_params(struct statement *stmt) else { char **paramvalues; + int *paramlengths; + int *paramformats; if (!(paramvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno))) { ecpg_free_params(stmt, false); return false; } + if (!(paramlengths = (int *) ecpg_realloc(stmt->paramlengths, sizeof(int) * (stmt->nparams + 1), stmt->lineno))) + { + ecpg_free_params(stmt, false); + return false; + } + if (!(paramformats = (int *) ecpg_realloc(stmt->paramformats, sizeof(int) * (stmt->nparams + 1), stmt->lineno))) + { + ecpg_free_params(stmt, false); + return false; + } stmt->nparams++; stmt->paramvalues = paramvalues; + stmt->paramlengths = paramlengths; + stmt->paramformats = paramformats; stmt->paramvalues[stmt->nparams - 1] = tobeinserted; + stmt->paramlengths[stmt->nparams - 1] = binary_length; + stmt->paramformats[stmt->nparams - 1] = (binary_format ? 1 : 0); /* let's see if this was an old style placeholder */ if (stmt->command[position] == '?') @@ -1433,7 +1534,13 @@ ecpg_execute(struct statement *stmt) ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name); if (stmt->statement_type == ECPGst_execute) { - stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0); + stmt->results = PQexecPrepared(stmt->connection->connection, + stmt->name, + stmt->nparams, + (const char *const *) stmt->paramvalues, + (const int *) stmt->paramlengths, + (const int *) stmt->paramformats, + 0); ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command); } else @@ -1445,7 +1552,12 @@ ecpg_execute(struct statement *stmt) } else { - stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0); + stmt->results = PQexecParams(stmt->connection->connection, + stmt->command, stmt->nparams, NULL, + (const char *const *) stmt->paramvalues, + (const int *) stmt->paramlengths, + (const int *) stmt->paramformats, + 0); ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno); } } |