From: Michael Meskes Date: Mon, 18 Feb 2019 09:20:31 +0000 (+0100) Subject: Add bytea datatype to ECPG. X-Git-Tag: REL_12_BETA1~712 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=050710b36964dee7e1b2bf6b5ef00041fd5d2787;p=postgresql Add bytea datatype to ECPG. So far ECPG programs had to treat binary data for bytea column as 'char' type. But this meant converting from/to escaped format with PQunescapeBytea/ PQescapeBytea() and therefore forcing users to add unnecessary code and cost for the conversion in runtime. By adding a dedicated datatype for bytea most of this special handling is no longer needed. Author: Matsumura-san ("Matsumura, Ryo" ) Discussion: https://postgr.es/m/flat/03040DFF97E6E54E88D3BFEE5F5480F737A141F9@G01JPEXMBYT04 --- diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index d2319c8b32..b7f785069f 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -917,7 +917,7 @@ do character(n), varchar(n), text - char[n+1], VARCHAR[n+1]declared in ecpglib.h + char[n+1], VARCHAR[n+1] @@ -947,7 +947,7 @@ do bytea - char * + char *, bytea[n] @@ -1204,6 +1204,36 @@ EXEC SQL END DECLARE SECTION; + + + bytea + + + The handling of the bytea type is also similar to + the VARCHAR. The definition on an array of type + bytea is converted into a named struct for every + variable. A declaration like: + +bytea var[180]; + + is converted into: + +struct bytea_var { int len; char arr[180]; } var; + + The member arr hosts binary format + data. It also can handle even '\0' as part of + data unlike VARCHAR. + The data is converted from/to hex format and sent/received by + ecpglib. + + + + + bytea variable can be used only when + is set to hex. + + + diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index 424b5ae5d5..81f94cc12b 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -122,6 +122,86 @@ check_special_value(char *ptr, double *retval, char **endptr) return false; } +/* imported from src/backend/utils/adt/encode.c */ + +unsigned +ecpg_hex_enc_len(unsigned srclen) +{ + return srclen << 1; +} + +unsigned +ecpg_hex_dec_len(unsigned srclen) +{ + return srclen >> 1; +} + +static inline char +get_hex(char c) +{ + static const int8 hexlookup[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + int res = -1; + + if (c > 0 && c < 127) + res = hexlookup[(unsigned char) c]; + + return (char) res; +} + +static unsigned +hex_decode(const char *src, unsigned len, char *dst) +{ + const char *s, + *srcend; + char v1, + v2, + *p; + + srcend = src + len; + s = src; + p = dst; + while (s < srcend) + { + if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') + { + s++; + continue; + } + v1 = get_hex(*s++) << 4; + if (s >= srcend) + return -1; + + v2 = get_hex(*s++); + *p++ = v1 | v2; + } + + return p - dst; +} + +unsigned +ecpg_hex_encode(const char *src, unsigned len, char *dst) +{ + static const char hextbl[] = "0123456789abcdef"; + const char *end = src + len; + + while (src < end) + { + *dst++ = hextbl[(*src >> 4) & 0xF]; + *dst++ = hextbl[*src & 0xF]; + src++; + } + return len * 2; +} + bool ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, @@ -447,6 +527,55 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, return false; break; + case ECPGt_bytea: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var + offset * act_tuple); + long dst_size, + src_size, + dec_size; + + dst_size = ecpg_hex_enc_len(varcharsize); + src_size = size - 2; /* exclude backslash + 'x' */ + dec_size = src_size < dst_size ? src_size : dst_size; + variable->len = hex_decode(pval + 2, dec_size, variable->arr); + + if (dst_size < src_size) + { + long rcv_size = ecpg_hex_dec_len(size - 2); + + /* truncation */ + switch (ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + *((short *) (ind + ind_offset * act_tuple)) = rcv_size; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *((int *) (ind + ind_offset * act_tuple)) = rcv_size; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *((long *) (ind + ind_offset * act_tuple)) = rcv_size; + break; +#ifdef HAVE_LONG_LONG_INT + case ECPGt_long_long: + case ECPGt_unsigned_long_long: + *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size; + break; +#endif /* HAVE_LONG_LONG_INT */ + default: + break; + } + sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W'; + } + + pval += size; + + } + break; + case ECPGt_char: case ECPGt_unsigned_char: case ECPGt_string: diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index d19dce2110..97849d0793 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -587,6 +587,28 @@ ECPGset_desc_header(int lineno, const char *desc_name, int count) return true; } +static void +set_desc_attr(struct descriptor_item *desc_item, struct variable *var, + char *tobeinserted) +{ + if (var->type != ECPGt_bytea) + desc_item->is_binary = false; + + else + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); + + desc_item->is_binary = true; + desc_item->data_len = variable->len; + } + + ecpg_free(desc_item->data); /* free() takes care of a + * potential NULL value */ + desc_item->data = (char *) tobeinserted; +} + + bool ECPGset_desc(int lineno, const char *desc_name, int index,...) { @@ -666,9 +688,7 @@ ECPGset_desc(int lineno, const char *desc_name, int index,...) return false; } - ecpg_free(desc_item->data); /* free() takes care of a - * potential NULL value */ - desc_item->data = (char *) tobeinserted; + set_desc_attr(desc_item, var, tobeinserted); tobeinserted = NULL; break; } diff --git a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h index f3e41d3eec..1ec2bf49f0 100644 --- a/src/interfaces/ecpg/ecpglib/ecpglib_extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -40,6 +40,13 @@ struct ECPGgeneric_varchar char arr[FLEXIBLE_ARRAY_MEMBER]; }; +/* A generic bytea type. */ +struct ECPGgeneric_bytea +{ + int len; + char arr[FLEXIBLE_ARRAY_MEMBER]; +}; + /* * type information cache */ @@ -75,6 +82,8 @@ struct statement #endif int nparams; char **paramvalues; + int *paramlengths; + int *paramformats; PGresult *results; }; @@ -133,6 +142,8 @@ struct descriptor_item int precision; int scale; int type; + bool is_binary; + int data_len; struct descriptor_item *next; }; @@ -226,6 +237,9 @@ struct sqlda_compat *ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_M void ecpg_set_compat_sqlda(int, struct sqlda_compat **, const PGresult *, int, enum COMPAT_MODE); struct sqlda_struct *ecpg_build_native_sqlda(int, PGresult *, int, enum COMPAT_MODE); void ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE); +unsigned ecpg_hex_dec_len(unsigned srclen); +unsigned ecpg_hex_enc_len(unsigned srclen); +unsigned ecpg_hex_encode(const char *src, unsigned len, char *dst); /* SQLSTATE values generated or processed by ecpglib (intentionally * not exported -- users should refer to the codes directly) */ diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 2bdb558fab..67681956b0 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); } } diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c index ee0d3e98fb..02338a41ea 100644 --- a/src/interfaces/ecpg/ecpglib/misc.c +++ b/src/interfaces/ecpg/ecpglib/misc.c @@ -355,6 +355,9 @@ ECPGset_noind_null(enum ECPGttype type, void *ptr) *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00; ((struct ECPGgeneric_varchar *) ptr)->len = 0; break; + case ECPGt_bytea: + ((struct ECPGgeneric_bytea *) ptr)->len = 0; + break; case ECPGt_decimal: memset((char *) ptr, 0, sizeof(decimal)); ((decimal *) ptr)->sign = NUMERIC_NULL; @@ -428,6 +431,10 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr) if (*(((const struct ECPGgeneric_varchar *) ptr)->arr) == 0x00) return true; break; + case ECPGt_bytea: + if (((struct ECPGgeneric_bytea *) ptr)->len == 0) + return true; + break; case ECPGt_decimal: if (((const decimal *) ptr)->sign == NUMERIC_NULL) return true; diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c index a3f281752b..9251450f9e 100644 --- a/src/interfaces/ecpg/ecpglib/typename.c +++ b/src/interfaces/ecpg/ecpglib/typename.c @@ -48,6 +48,8 @@ ecpg_type_name(enum ECPGttype typ) return "bool"; case ECPGt_varchar: return "varchar"; + case ECPGt_bytea: + return "bytea"; case ECPGt_char_variable: return "char"; case ECPGt_decimal: diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 9b1f3a8066..4a7e8e781f 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -63,7 +63,8 @@ enum ECPGttype ECPGt_EORT, /* End of result types. */ ECPGt_NO_INDICATOR, /* no indicator */ ECPGt_string, /* trimmed (char *) type */ - ECPGt_sqlda /* C struct descriptor */ + ECPGt_sqlda, /* C struct descriptor */ + ECPGt_bytea }; /* descriptor items */ @@ -88,7 +89,7 @@ enum ECPGdtype ECPGd_cardinality }; -#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string)) +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string) || ((type) == ECPGt_bytea)) /* we also have to handle different statement types */ enum ECPG_statement_type diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index a6f870dcda..366dc231ca 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -47,6 +47,7 @@ static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess static struct this_type actual_type[STRUCT_DEPTH]; static char *actual_startline[STRUCT_DEPTH]; static int varchar_counter = 1; +static int bytea_counter = 1; /* temporarily store struct members while creating the data structure */ struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL }; @@ -563,6 +564,7 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum, ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL; if (type_enum != ECPGt_varchar && + type_enum != ECPGt_bytea && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string && diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 6755d4a0d2..88b27a297a 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -580,6 +580,14 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } + else if (strcmp($1, "bytea") == 0) + { + $$.type_enum = ECPGt_bytea; + $$.type_str = EMPTY; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } else if (strcmp($1, "float") == 0) { $$.type_enum = ECPGt_float; @@ -657,7 +665,7 @@ var_type: simple_type /* this is for typedef'ed types */ struct typedefs *this = get_typedef($1); - $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name); + $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); $$.type_enum = this->type->type_enum; $$.type_dimension = this->type->type_dimension; $$.type_index = this->type->type_index; @@ -868,7 +876,7 @@ variable_list: variable { $$ = $1; } | variable_list ',' variable { - if (actual_type[struct_level].type_enum == ECPGt_varchar) + if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea) $$ = cat_str(3, $1, mm_strdup(";"), $3); else $$ = cat_str(3, $1, mm_strdup(","), $3); @@ -882,9 +890,10 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize char *length = $3.index2; /* length of string */ char *dim_str; char *vcn; + int *varlen_type_counter; + char *struct_name; adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false); - switch (actual_type[struct_level].type_enum) { case ECPGt_struct: @@ -898,10 +907,21 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize break; case ECPGt_varchar: + case ECPGt_bytea: + if (actual_type[struct_level].type_enum == ECPGt_varchar) + { + varlen_type_counter = &varchar_counter; + struct_name = " struct varchar_"; + } + else + { + varlen_type_counter = &bytea_counter; + struct_name = " struct bytea_"; + } if (atoi(dimension) < 0) - type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter); + type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter); else - type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter), dimension); + type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter), dimension); if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1) dim_str=mm_strdup(""); @@ -913,12 +933,12 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize /* make sure varchar struct name is unique by adding a unique counter to its definition */ vcn = (char *) mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(vcn, "%d", varchar_counter); + sprintf(vcn, "%d", *varlen_type_counter); if (strcmp(dimension, "0") == 0) - $$ = cat_str(7, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); + $$ = cat_str(7, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); else - $$ = cat_str(8, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); - varchar_counter++; + $$ = cat_str(8, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); + (*varlen_type_counter)++; break; case ECPGt_char: @@ -1384,6 +1404,7 @@ ECPGVar: SQL_VAR break; case ECPGt_varchar: + case ECPGt_bytea: if (atoi(dimension) == -1) type = ECPGmake_simple_type($5.type_enum, length, 0); else diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index afe90498b7..a9b4acfddf 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -102,7 +102,7 @@ ECPGmake_simple_type(enum ECPGttype type, char *size, int counter) ne->size = size; ne->u.element = NULL; ne->struct_sizeof = NULL; - ne->counter = counter; /* only needed for varchar */ + ne->counter = counter; /* only needed for varchar and bytea */ return ne; } @@ -175,6 +175,8 @@ get_type(enum ECPGttype type) break; case ECPGt_varchar: return "ECPGt_varchar"; + case ECPGt_bytea: + return "ECPGt_bytea"; case ECPGt_NO_INDICATOR: /* no indicator */ return "ECPGt_NO_INDICATOR"; break; @@ -424,6 +426,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, { char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4); char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1 + strlen(varcharsize) + sizeof(int) * CHAR_BIT * 10 / 3); + char *struct_name; switch (type) { @@ -433,6 +436,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, */ case ECPGt_varchar: + case ECPGt_bytea: /* * we have to use the pointer except for arrays with given @@ -449,10 +453,15 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, * If we created a varchar structure automatically, counter is * greater than 0. */ + if (type == ECPGt_varchar) + struct_name = "struct varchar"; + else + struct_name = "struct bytea"; + if (counter) - sprintf(offset, "sizeof(struct varchar_%d)", counter); + sprintf(offset, "sizeof(%s_%d)", struct_name, counter); else - sprintf(offset, "sizeof(struct varchar)"); + sprintf(offset, "sizeof(%s)", struct_name); break; case ECPGt_char: case ECPGt_unsigned_char: diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index a953498c1c..887d479e73 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -560,6 +560,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty break; case ECPGt_varchar: + case ECPGt_bytea: /* pointer has to get dimension 0 */ if (pointer_len) *dimension = mm_strdup("0"); diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule index 81afc5d974..89b21533be 100644 --- a/src/interfaces/ecpg/test/ecpg_schedule +++ b/src/interfaces/ecpg/test/ecpg_schedule @@ -32,6 +32,7 @@ test: preproc/whenever test: preproc/whenever_do_continue test: sql/array test: sql/binary +test: sql/bytea test: sql/code100 test: sql/copystdout test: sql/define diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.c b/src/interfaces/ecpg/test/expected/sql-bytea.c new file mode 100644 index 0000000000..f230d73209 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-bytea.c @@ -0,0 +1,316 @@ +/* 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 "bytea.pgc" +#include +#include +#include +#include + + +#line 1 "regression.h" + + + + + + +#line 6 "bytea.pgc" + +/* exec sql whenever sqlerror sqlprint ; */ +#line 7 "bytea.pgc" + + +static void +dump_binary(char *buf, int len, int ind) +{ + int i; + + printf("len=%d, ind=%d, data=0x", len, ind); + for (i = 0; i < len; ++i) + printf("%02x", 0xff & buf[i]); + printf("\n"); +} + +#define DATA_SIZE 0x200 +#define LACK_SIZE 13 +# +int +main(void) +{ +/* exec sql begin declare section */ + + + + + + +#line 27 "bytea.pgc" + struct bytea_1 { int len; char arr[ DATA_SIZE ]; } send_buf [ 2 ] ; + +#line 28 "bytea.pgc" + struct bytea_2 { int len; char arr[ DATA_SIZE ]; } recv_buf [ 2 ] ; + +#line 29 "bytea.pgc" + struct bytea_3 { int len; char arr[ DATA_SIZE ]; } * recv_vlen_buf ; + +#line 30 "bytea.pgc" + struct bytea_4 { int len; char arr[ DATA_SIZE - LACK_SIZE ]; } recv_short_buf ; + +#line 31 "bytea.pgc" + int ind [ 2 ] ; +/* exec sql end declare section */ +#line 32 "bytea.pgc" + + int i, j, c; + +#define init() { \ + for (i = 0; i < 2; ++i) \ + { \ + memset(recv_buf[i].arr, 0x0, sizeof(recv_buf[i].arr)); \ + recv_buf[i].len = 0; \ + ind[i] = 0; \ + } \ + recv_vlen_buf = NULL, \ + memset(recv_short_buf.arr, 0x0, sizeof(recv_short_buf.arr)); \ +} \ +while (0) + + + ECPGdebug(1, stderr); + + for (i = 0; i < 2; ++i) + { + for (j = 0, c = 0xff; (c == -1 ? c = 0xff : 1), j < DATA_SIZE; ++j, --c) + send_buf[i].arr[j] = c; + + send_buf[i].len = DATA_SIZE; + } + + { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); +#line 58 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 58 "bytea.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table if not exists test ( data1 bytea , data2 bytea )", ECPGt_EOIT, ECPGt_EORT); +#line 60 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 60 "bytea.pgc" + + + { ECPGprepare(__LINE__, NULL, 0, "ins_stmt", "insert into test values(?,?)"); +#line 62 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 62 "bytea.pgc" + + { ECPGprepare(__LINE__, NULL, 0, "sel_stmt", "select data1,data2 from test"); +#line 63 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 63 "bytea.pgc" + + ECPGallocate_desc(__LINE__, "idesc"); +#line 64 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint(); +#line 64 "bytea.pgc" + + ECPGallocate_desc(__LINE__, "odesc"); +#line 65 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint(); +#line 65 "bytea.pgc" + + + /* Test for static sql statement with normal host variable, indicator */ + init(); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT); +#line 69 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 69 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test values ( $1 , $2 )", + ECPGt_bytea,&(send_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(send_buf[1]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 70 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 70 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select data1 , data2 from test", ECPGt_EOIT, + ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_2), + ECPGt_int,&(ind[0]),(long)1,(long)1,sizeof(int), + ECPGt_bytea,&(recv_short_buf),(long)DATA_SIZE - LACK_SIZE,(long)1,sizeof(struct bytea_4), + ECPGt_int,&(ind[1]),(long)1,(long)1,sizeof(int), ECPGt_EORT); +#line 71 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 71 "bytea.pgc" + + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + /* Test for variable length array */ + init(); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT); +#line 77 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 77 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test values ( $1 , $2 )", + ECPGt_bytea,&(send_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(send_buf[1]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 78 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 78 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into test values ( $1 , $2 )", + ECPGt_bytea,&(send_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(send_buf[1]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 79 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 79 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select data1 from test", ECPGt_EOIT, + ECPGt_bytea,&(recv_vlen_buf),(long)DATA_SIZE,(long)0,sizeof(struct bytea_3), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 80 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 80 "bytea.pgc" + + dump_binary(recv_vlen_buf[0].arr, recv_vlen_buf[0].len, 0); + dump_binary(recv_vlen_buf[1].arr, recv_vlen_buf[1].len, 0); + + /* Test for dynamic sql statement with normal host variable, indicator */ + init(); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT); +#line 86 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 86 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "ins_stmt", + ECPGt_bytea,&(send_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(send_buf[1]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 87 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 87 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "sel_stmt", ECPGt_EOIT, + ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_2), + ECPGt_int,&(ind[0]),(long)1,(long)1,sizeof(int), + ECPGt_bytea,&(recv_short_buf),(long)DATA_SIZE - LACK_SIZE,(long)1,sizeof(struct bytea_4), + ECPGt_int,&(ind[1]),(long)1,(long)1,sizeof(int), ECPGt_EORT); +#line 88 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 88 "bytea.pgc" + + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + /* Test for dynamic sql statement with sql descriptor */ + init(); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "truncate test", ECPGt_EOIT, ECPGt_EORT); +#line 94 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 94 "bytea.pgc" + + { ECPGset_desc(__LINE__, "idesc", 1,ECPGd_data, + ECPGt_bytea,&(send_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), ECPGd_EODT); + +#line 95 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 95 "bytea.pgc" + + { ECPGset_desc(__LINE__, "idesc", 2,ECPGd_data, + ECPGt_bytea,&(send_buf[1]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_1), ECPGd_EODT); + +#line 96 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 96 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "ins_stmt", + ECPGt_descriptor, "idesc", 1L, 1L, 1L, + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 97 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 97 "bytea.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_execute, "sel_stmt", ECPGt_EOIT, + ECPGt_descriptor, "odesc", 1L, 1L, 1L, + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 98 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 98 "bytea.pgc" + + { ECPGget_desc(__LINE__, "odesc", 1,ECPGd_indicator, + ECPGt_int,&(ind[0]),(long)1,(long)1,sizeof(int), ECPGd_data, + ECPGt_bytea,&(recv_buf[0]),(long)DATA_SIZE,(long)1,sizeof(struct bytea_2), ECPGd_EODT); + +#line 99 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 99 "bytea.pgc" + + { ECPGget_desc(__LINE__, "odesc", 2,ECPGd_indicator, + ECPGt_int,&(ind[1]),(long)1,(long)1,sizeof(int), ECPGd_data, + ECPGt_bytea,&(recv_short_buf),(long)DATA_SIZE - LACK_SIZE,(long)1,sizeof(struct bytea_4), ECPGd_EODT); + +#line 100 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 100 "bytea.pgc" + + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table test", ECPGt_EOIT, ECPGt_EORT); +#line 104 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 104 "bytea.pgc" + + { ECPGtrans(__LINE__, NULL, "commit"); +#line 105 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 105 "bytea.pgc" + + { ECPGdisconnect(__LINE__, "CURRENT"); +#line 106 "bytea.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 106 "bytea.pgc" + + + return 0; +} diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.stderr b/src/interfaces/ecpg/test/expected/sql-bytea.stderr new file mode 100644 index 0000000000..c9f071e2ea --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-bytea.stderr @@ -0,0 +1,150 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database ecpg1_regression on port +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 60: query: create table if not exists test ( data1 bytea , data2 bytea ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 60: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 60: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 62: name ins_stmt; query: "insert into test values($1,$2)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: prepare_common on line 63: name sel_stmt; query: "select data1,data2 from test" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 69: query: truncate test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 69: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 69: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 70: query: insert into test values ( $1 , $2 ); with 2 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 70: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 70: parameter 1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 70: parameter 2 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 70: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 71: query: select data1 , data2 from test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 71: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 71: correctly got 1 tuples with 2 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 71: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 71: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 77: query: truncate test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 77: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 77: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 78: query: insert into test values ( $1 , $2 ); with 2 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 78: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 78: parameter 1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 78: parameter 2 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 78: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 79: query: insert into test values ( $1 , $2 ); with 2 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 79: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 79: parameter 1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 79: parameter 2 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 79: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 80: query: select data1 from test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 80: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 80: correctly got 2 tuples with 1 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_store_result on line 80: allocating memory for 2 tuples +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 80: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 80: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 86: query: truncate test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 86: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 86: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 87: query: insert into test values($1,$2); with 2 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 87: using PQexecPrepared for "insert into test values($1,$2)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 87: parameter 1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 87: parameter 2 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 87: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 88: query: select data1,data2 from test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 88: using PQexecPrepared for "select data1,data2 from test" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 88: correctly got 1 tuples with 2 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 88: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 88: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 94: query: truncate test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 94: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 94: OK: TRUNCATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 97: query: insert into test values($1,$2); with 2 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 97: using PQexecPrepared for "insert into test values($1,$2)" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 97: parameter 1 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 97: parameter 2 = fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 97: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 98: query: select data1,data2 from test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 98: using PQexecPrepared for "select data1,data2 from test" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 98: correctly got 1 tuples with 2 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 98: putting result (1 tuples) into descriptor odesc +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGget_desc: reading items for tuple 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGget_desc: reading items for tuple 2 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 100: RESULT: \xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 104: query: drop table test; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 104: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 104: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 105: action "commit"; connection "ecpg1_regression" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 0: name sel_stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: deallocate_one on line 0: name ins_stmt +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection ecpg1_regression closed +[NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/sql-bytea.stdout b/src/interfaces/ecpg/test/expected/sql-bytea.stdout new file mode 100644 index 0000000000..4c9ad4c599 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/sql-bytea.stdout @@ -0,0 +1,8 @@ +len=512, ind=0, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +len=499, ind=512, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d +len=512, ind=0, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +len=512, ind=0, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +len=512, ind=0, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +len=499, ind=512, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d +len=512, ind=0, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100 +len=499, ind=512, data=0xfffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d diff --git a/src/interfaces/ecpg/test/sql/Makefile b/src/interfaces/ecpg/test/sql/Makefile index c3d86ae4f3..d7182c900f 100644 --- a/src/interfaces/ecpg/test/sql/Makefile +++ b/src/interfaces/ecpg/test/sql/Makefile @@ -24,7 +24,9 @@ TESTS = array array.c \ show show.c \ insupd insupd.c \ twophase twophase.c \ - declare declare.c + insupd insupd.c \ + declare declare.c \ + bytea bytea.c all: $(TESTS) diff --git a/src/interfaces/ecpg/test/sql/bytea.pgc b/src/interfaces/ecpg/test/sql/bytea.pgc new file mode 100644 index 0000000000..b2c5c03713 --- /dev/null +++ b/src/interfaces/ecpg/test/sql/bytea.pgc @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +exec sql include ../regression; +exec sql whenever sqlerror sqlprint; + +static void +dump_binary(char *buf, int len, int ind) +{ + int i; + + printf("len=%d, ind=%d, data=0x", len, ind); + for (i = 0; i < len; ++i) + printf("%02x", 0xff & buf[i]); + printf("\n"); +} + +#define DATA_SIZE 0x200 +#define LACK_SIZE 13 +# +int +main(void) +{ +exec sql begin declare section; + bytea send_buf[2][DATA_SIZE]; + bytea recv_buf[2][DATA_SIZE]; + bytea recv_vlen_buf[][DATA_SIZE]; + bytea recv_short_buf[DATA_SIZE - LACK_SIZE]; + int ind[2]; +exec sql end declare section; + int i, j, c; + +#define init() { \ + for (i = 0; i < 2; ++i) \ + { \ + memset(recv_buf[i].arr, 0x0, sizeof(recv_buf[i].arr)); \ + recv_buf[i].len = 0; \ + ind[i] = 0; \ + } \ + recv_vlen_buf = NULL, \ + memset(recv_short_buf.arr, 0x0, sizeof(recv_short_buf.arr)); \ +} \ +while (0) + + + ECPGdebug(1, stderr); + + for (i = 0; i < 2; ++i) + { + for (j = 0, c = 0xff; (c == -1 ? c = 0xff : 1), j < DATA_SIZE; ++j, --c) + send_buf[i].arr[j] = c; + + send_buf[i].len = DATA_SIZE; + } + + exec sql connect to REGRESSDB1; + + exec sql create table if not exists test (data1 bytea, data2 bytea); + + exec sql prepare ins_stmt from "insert into test values(?,?)"; + exec sql prepare sel_stmt from "select data1,data2 from test"; + exec sql allocate descriptor idesc; + exec sql allocate descriptor odesc; + + /* Test for static sql statement with normal host variable, indicator */ + init(); + exec sql truncate test; + exec sql insert into test values(:send_buf[0], :send_buf[1]); + exec sql select data1,data2 into :recv_buf[0]:ind[0], :recv_short_buf:ind[1] from test; + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + /* Test for variable length array */ + init(); + exec sql truncate test; + exec sql insert into test values(:send_buf[0], :send_buf[1]); + exec sql insert into test values(:send_buf[0], :send_buf[1]); + exec sql select data1 into :recv_vlen_buf from test; + dump_binary(recv_vlen_buf[0].arr, recv_vlen_buf[0].len, 0); + dump_binary(recv_vlen_buf[1].arr, recv_vlen_buf[1].len, 0); + + /* Test for dynamic sql statement with normal host variable, indicator */ + init(); + exec sql truncate test; + exec sql execute ins_stmt using :send_buf[0], :send_buf[1]; + exec sql execute sel_stmt into :recv_buf[0]:ind[0], :recv_short_buf:ind[1]; + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + /* Test for dynamic sql statement with sql descriptor */ + init(); + exec sql truncate test; + exec sql set descriptor idesc value 1 data = :send_buf[0]; + exec sql set descriptor idesc value 2 data = :send_buf[1]; + exec sql execute ins_stmt using sql descriptor idesc; + exec sql execute sel_stmt into sql descriptor odesc; + exec sql get descriptor odesc value 1 :recv_buf[0] = data, :ind[0] = indicator; + exec sql get descriptor odesc value 2 :recv_short_buf = data, :ind[1] = indicator; + dump_binary(recv_buf[0].arr, recv_buf[0].len, ind[0]); + dump_binary(recv_short_buf.arr, recv_short_buf.len, ind[1]); + + exec sql drop table test; + exec sql commit; + exec sql disconnect; + + return 0; +}