aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/ecpg/ecpglib/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/ecpg/ecpglib/execute.c')
-rw-r--r--src/interfaces/ecpg/ecpglib/execute.c170
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);
}
}