From 8715789928dfea256334e849799bf57064a5b227 Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Sun, 4 Jul 2004 15:02:24 +0000 Subject: [PATCH] Made sure SET DESCRIPTOR accepts all data types including constants. --- src/interfaces/ecpg/ChangeLog | 9 ++ src/interfaces/ecpg/ecpglib/data.c | 5 +- src/interfaces/ecpg/ecpglib/descriptor.c | 53 +++---- src/interfaces/ecpg/ecpglib/execute.c | 180 ++++++++++++----------- src/interfaces/ecpg/ecpglib/extern.h | 2 + src/interfaces/ecpg/include/ecpglib.h | 1 + src/interfaces/ecpg/preproc/preproc.y | 43 ++++-- src/interfaces/ecpg/preproc/variable.c | 2 +- src/interfaces/ecpg/test/test_desc.pgc | 3 +- 9 files changed, 161 insertions(+), 137 deletions(-) diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index ab69eb0fed..888dd73bc8 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -1825,6 +1825,15 @@ Sun Jun 27 13:50:58 CEST 2004 Mon Jun 28 11:08:42 CEST 2004 - Arrays can be read as arrays or as character strings now. + +Wed Jun 30 16:56:32 CEST 2004 + + - Added SET DESCRIPTOR command. + - Cleaned up error handling in preprocessor. + +Sun Jul 4 16:53:53 CEST 2004 + + - Made sure SET DESCRIPTOR accepts all data types including constants. - Set pgtypes library version to 1.2. - Set ecpg version to 3.2.0. - Set compat library version to 1.2. diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index eb1360efc6..04e944ce89 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.25 2004/06/28 11:47:41 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.26 2004/07/04 15:02:22 meskes Exp $ */ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" @@ -76,10 +76,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, * and 0 if not */ if (PQgetisnull(results, act_tuple, act_field)) - { - printf("MM NULL\n"); value_for_indicator = -1; - } switch (ind_type) { diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index f9da2cc4b1..e653203f89 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -1,6 +1,6 @@ /* dynamic SQL support routines * - * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.9 2004/07/01 18:32:58 meskes Exp $ + * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.10 2004/07/04 15:02:22 meskes Exp $ */ #define POSTGRES_ECPG_INTERNAL @@ -436,6 +436,7 @@ ECPGset_desc(int lineno, char *desc_name, int index,...) va_list args; struct descriptor *desc; struct descriptor_item *desc_item; + struct variable *var; for (desc = all_descriptors; desc; desc = desc->next) { @@ -463,69 +464,59 @@ ECPGset_desc(int lineno, char *desc_name, int index,...) desc->items = desc_item; } + if (!(var = (struct variable *) ECPGalloc(sizeof(struct variable), lineno))) + return false; + va_start(args, index); do { enum ECPGdtype itemtype; - long varcharsize; - long offset; - long arrsize; - enum ECPGttype vartype; - void *var; + enum ECPGttype type; + const char *tobeinserted = NULL; + bool malloced; itemtype = va_arg(args, enum ECPGdtype); if (itemtype == ECPGd_EODT) break; - vartype = va_arg(args, enum ECPGttype); - var = va_arg(args, void *); - varcharsize = va_arg(args, long); - arrsize = va_arg(args, long); - offset = va_arg(args, long); + type = va_arg(args, enum ECPGttype); + ECPGget_variable(&args, type, var, false); switch (itemtype) { case ECPGd_data: { - // FIXME: how to do this in general? - switch (vartype) + if (!ECPGstore_input(lineno, true, var, &tobeinserted, &malloced)) { - case ECPGt_char: - desc_item->data = strdup((char *)var); - break; - case ECPGt_int: - { - char buf[20]; - snprintf(buf, 20, "%d", *(int *)var); - desc_item->data = strdup(buf); - break; - } - default: - abort(); + ECPGfree(var); + return false; } + + desc_item->data = (char *) tobeinserted; + tobeinserted = NULL; break; } case ECPGd_indicator: - set_int_item(lineno, &desc_item->indicator, var, vartype); + set_int_item(lineno, &desc_item->indicator, var->pointer, var->type); break; case ECPGd_length: - set_int_item(lineno, &desc_item->length, var, vartype); + set_int_item(lineno, &desc_item->length, var->pointer, var->type); break; case ECPGd_precision: - set_int_item(lineno, &desc_item->precision, var, vartype); + set_int_item(lineno, &desc_item->precision, var->pointer, var->type); break; case ECPGd_scale: - set_int_item(lineno, &desc_item->scale, var, vartype); + set_int_item(lineno, &desc_item->scale, var->pointer, var->type); break; case ECPGd_type: - set_int_item(lineno, &desc_item->type, var, vartype); + set_int_item(lineno, &desc_item->type, var->pointer, var->type); break; default: @@ -533,6 +524,7 @@ ECPGset_desc(int lineno, char *desc_name, int index,...) char type_str[20]; snprintf(type_str, sizeof(type_str), "%d", itemtype); ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str); + ECPGfree(var); return false; } } @@ -544,6 +536,7 @@ ECPGset_desc(int lineno, char *desc_name, int index,...) }*/ } while (true); + ECPGfree(var); return true; } diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index d99f958445..6464ecb4b3 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.35 2004/06/30 15:01:56 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.36 2004/07/04 15:02:22 meskes Exp $ */ /* * The aim is to get a simpler inteface to the database routines. @@ -69,6 +69,59 @@ quote_postgres(char *arg, int lineno) return res; } +void +ECPGget_variable(va_list *ap, enum ECPGttype type, struct variable *var, bool indicator) +{ + var->type = type; + var->pointer = va_arg(*ap, char *); + + var->varcharsize = va_arg(*ap, long); + var->arrsize = va_arg(*ap, long); + var->offset = va_arg(*ap, long); + + if (var->arrsize == 0 || var->varcharsize == 0) + var->value = *((char **) (var->pointer)); + else + var->value = var->pointer; + + /* + * negative values are used to indicate an array without given + * bounds + */ + /* reset to zero for us */ + if (var->arrsize < 0) + var->arrsize = 0; + if (var->varcharsize < 0) + var->varcharsize = 0; + + var->next = NULL; + + if (indicator) + { + var->ind_type = va_arg(*ap, enum ECPGttype); + var->ind_pointer = va_arg(*ap, char *); + var->ind_varcharsize = va_arg(*ap, long); + var->ind_arrsize = va_arg(*ap, long); + var->ind_offset = va_arg(*ap, long); + + if (var->ind_type != ECPGt_NO_INDICATOR + && (var->ind_arrsize == 0 || var->ind_varcharsize == 0)) + var->ind_value = *((char **) (var->ind_pointer)); + else + var->ind_value = var->ind_pointer; + + /* + * negative values are used to indicate an array without given + * bounds + */ + /* reset to zero for us */ + if (var->ind_arrsize < 0) + var->ind_arrsize = 0; + if (var->ind_varcharsize < 0) + var->ind_varcharsize = 0; + } +} + /* * create a list of variables * The variables are listed with input variables preceding outputvariables @@ -118,8 +171,7 @@ create_statement(int lineno, int compat, int force_indicator, struct connection if (!(var = (struct variable *) ECPGalloc(sizeof(struct variable), lineno))) return false; - var->type = type; - var->pointer = va_arg(ap, char *); + ECPGget_variable(&ap, type, var, true); /* if variable is NULL, the statement hasn't been prepared */ if (var->pointer == NULL) @@ -129,48 +181,6 @@ create_statement(int lineno, int compat, int force_indicator, struct connection return false; } - var->varcharsize = va_arg(ap, long); - var->arrsize = va_arg(ap, long); - var->offset = va_arg(ap, long); - - if (var->arrsize == 0 || var->varcharsize == 0) - var->value = *((char **) (var->pointer)); - else - var->value = var->pointer; - - /* - * negative values are used to indicate an array without given - * bounds - */ - /* reset to zero for us */ - if (var->arrsize < 0) - var->arrsize = 0; - if (var->varcharsize < 0) - var->varcharsize = 0; - - var->ind_type = va_arg(ap, enum ECPGttype); - var->ind_pointer = va_arg(ap, char *); - var->ind_varcharsize = va_arg(ap, long); - var->ind_arrsize = va_arg(ap, long); - var->ind_offset = va_arg(ap, long); - var->next = NULL; - - if (var->ind_type != ECPGt_NO_INDICATOR - && (var->ind_arrsize == 0 || var->ind_varcharsize == 0)) - var->ind_value = *((char **) (var->ind_pointer)); - else - var->ind_value = var->ind_pointer; - - /* - * negative values are used to indicate an array without given - * bounds - */ - /* reset to zero for us */ - if (var->ind_arrsize < 0) - var->ind_arrsize = 0; - if (var->ind_varcharsize < 0) - var->ind_varcharsize = 0; - for (ptr = *list; ptr && ptr->next; ptr = ptr->next); if (ptr == NULL) @@ -477,8 +487,8 @@ ECPGstore_result(const PGresult *results, int act_field, return status; } -static bool -ECPGstore_input(const struct statement * stmt, const struct variable * var, +bool +ECPGstore_input(const int lineno, const bool force_indicator, const struct variable * var, const char **tobeinserted_p, bool *malloced_p) { char *mallocedval = NULL; @@ -491,7 +501,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, #if 0 if (var->arrsize > 1 &&...) { - ECPGraise(stmt->lineno, ECPG_ARRAY_INSERT, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL); + ECPGraise(lineno, ECPG_ARRAY_INSERT, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL); return false; } #endif @@ -530,7 +540,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; #endif /* HAVE_LONG_LONG_INT_64 */ case ECPGt_NO_INDICATOR: - if (stmt->force_indicator == false) + if (force_indicator == false) { if (ECPGis_noind_null(var->type, var->value)) *tobeinserted_p = "null"; @@ -546,7 +556,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, int element; case ECPGt_short: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -566,7 +576,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_int: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -586,7 +596,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_unsigned_short: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -606,7 +616,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_unsigned_int: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -626,7 +636,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_long: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -646,7 +656,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_unsigned_long: - if (!(mallocedval = ECPGalloc(var->arrsize * 20, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 20, lineno))) return false; if (var->arrsize > 1) @@ -666,7 +676,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; #ifdef HAVE_LONG_LONG_INT_64 case ECPGt_long_long: - if (!(mallocedval = ECPGalloc(var->arrsize * 30, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 30, lineno))) return false; if (var->arrsize > 1) @@ -686,7 +696,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_unsigned_long_long: - if (!(mallocedval = ECPGalloc(var->arrsize * 30, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 30, lineno))) return false; if (var->arrsize > 1) @@ -706,7 +716,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; #endif /* HAVE_LONG_LONG_INT_64 */ case ECPGt_float: - if (!(mallocedval = ECPGalloc(var->arrsize * 25, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 25, lineno))) return false; if (var->arrsize > 1) @@ -726,7 +736,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_double: - if (!(mallocedval = ECPGalloc(var->arrsize * 25, stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize * 25, lineno))) return false; if (var->arrsize > 1) @@ -746,7 +756,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, break; case ECPGt_bool: - if (!(mallocedval = ECPGalloc(var->arrsize + sizeof("array []"), stmt->lineno))) + if (!(mallocedval = ECPGalloc(var->arrsize + sizeof("array []"), lineno))) return false; if (var->arrsize > 1) @@ -765,7 +775,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, for (element = 0; element < var->arrsize; element++) sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f'); else - ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size"); + ECPGraise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size"); strcpy(mallocedval + strlen(mallocedval) - 1, "]"); } @@ -776,7 +786,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, else if (var->offset == sizeof(int)) sprintf(mallocedval, "'%c'", (*((int *) var->value)) ? 't' : 'f'); else - ECPGraise(stmt->lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size"); + ECPGraise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, "different size"); } *tobeinserted_p = mallocedval; @@ -787,15 +797,15 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, case ECPGt_unsigned_char: { /* set slen to string length if type is char * */ - int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; + int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; - if (!(newcopy = ECPGalloc(slen + 1, stmt->lineno))) + if (!(newcopy = ECPGalloc(slen + 1, lineno))) return false; strncpy(newcopy, (char *) var->value, slen); newcopy[slen] = '\0'; - mallocedval = quote_postgres(newcopy, stmt->lineno); + mallocedval = quote_postgres(newcopy, lineno); if (!mallocedval) return false; @@ -810,7 +820,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, { int slen = strlen((char *) var->value); - if (!(mallocedval = ECPGalloc(slen + 1, stmt->lineno))) + if (!(mallocedval = ECPGalloc(slen + 1, lineno))) return false; strncpy(mallocedval, (char *) var->value, slen); @@ -825,13 +835,13 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, struct ECPGgeneric_varchar *variable = (struct ECPGgeneric_varchar *) (var->value); - if (!(newcopy = (char *) ECPGalloc(variable->len + 1, stmt->lineno))) + if (!(newcopy = (char *) ECPGalloc(variable->len + 1, lineno))) return false; strncpy(newcopy, variable->arr, variable->len); newcopy[variable->len] = '\0'; - mallocedval = quote_postgres(newcopy, stmt->lineno); + mallocedval = quote_postgres(newcopy, lineno); if (!mallocedval) return false; @@ -862,7 +872,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, PGTYPESnumeric_free(nval); slen = strlen(str); - if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [] "), stmt->lineno))) + if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [] "), lineno))) return false; if (!element) @@ -885,7 +895,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, PGTYPESnumeric_free(nval); slen = strlen(str); - if (!(mallocedval = ECPGalloc(slen + 1, stmt->lineno))) + if (!(mallocedval = ECPGalloc(slen + 1, lineno))) return false; strncpy(mallocedval, str, slen); @@ -907,10 +917,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, { for (element = 0; element < var->arrsize; element++) { - str = quote_postgres(PGTYPESinterval_to_asc((interval *) ((var + var->offset * element)->value)), stmt->lineno); + str = quote_postgres(PGTYPESinterval_to_asc((interval *) ((var + var->offset * element)->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],interval "), stmt->lineno))) + if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],interval "), lineno))) return false; if (!element) @@ -924,10 +934,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, } else { - str = quote_postgres(PGTYPESinterval_to_asc((interval *) (var->value)), stmt->lineno); + str = quote_postgres(PGTYPESinterval_to_asc((interval *) (var->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGalloc(slen + sizeof("interval ") + 1, stmt->lineno))) + if (!(mallocedval = ECPGalloc(slen + sizeof("interval ") + 1, lineno))) return false; strcpy(mallocedval, "interval "); @@ -950,10 +960,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, { for (element = 0; element < var->arrsize; element++) { - str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), stmt->lineno); + str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],date "), stmt->lineno))) + if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [],date "), lineno))) return false; if (!element) @@ -967,10 +977,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, } else { - str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), stmt->lineno); + str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGalloc(slen + sizeof("date ") + 1, stmt->lineno))) + if (!(mallocedval = ECPGalloc(slen + sizeof("date ") + 1, lineno))) return false; strcpy(mallocedval, "date "); @@ -993,10 +1003,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, { for (element = 0; element < var->arrsize; element++) { - str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), stmt->lineno); + str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [], timestamp "), stmt->lineno))) + if (!(mallocedval = ECPGrealloc(mallocedval, strlen(mallocedval) + slen + sizeof("array [], timestamp "), lineno))) return false; if (!element) @@ -1010,10 +1020,10 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, } else { - str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), stmt->lineno); + str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), lineno); slen = strlen(str); - if (!(mallocedval = ECPGalloc(slen + sizeof("timestamp") + 1, stmt->lineno))) + if (!(mallocedval = ECPGalloc(slen + sizeof("timestamp") + 1, lineno))) return false; strcpy(mallocedval, "timestamp "); @@ -1032,7 +1042,7 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var, default: /* Not implemented yet */ - ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (char *) ECPGtype_name(var->type)); + ECPGraise(lineno, ECPG_UNSUPPORTED, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (char *) ECPGtype_name(var->type)); return false; break; } @@ -1104,7 +1114,7 @@ ECPGexecute(struct statement * stmt) desc_inlist.ind_value = desc_inlist.ind_pointer = NULL; desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0; - if (!ECPGstore_input(stmt, &desc_inlist, &tobeinserted, &malloced)) + if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, &malloced)) return false; break; @@ -1116,7 +1126,7 @@ ECPGexecute(struct statement * stmt) } else { - if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced)) + if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, &malloced)) return false; } if (tobeinserted) diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h index c644ff292d..74a8b046c9 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/extern.h @@ -124,6 +124,8 @@ PGresult **ECPGdescriptor_lvalue (int line, const char *descriptor); bool ECPGstore_result (const PGresult * results, int act_field, const struct statement *stmt, struct variable *var); +bool ECPGstore_input(const int, const bool, const struct variable *, const char **, bool *); +void ECPGget_variable(va_list *, enum ECPGttype, struct variable *, bool); /* SQLSTATE values generated or processed by ecpglib (intentionally * not exported -- users should refer to the codes directly) */ diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index 9f3e3aa150..778104a27b 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -8,6 +8,7 @@ #include "libpq-fe.h" #include "ecpgtype.h" +#include #ifndef __BEOS__ #ifndef __cplusplus diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index ee9f25bad1..e1dab2b72e 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -1,4 +1,4 @@ -/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.290 2004/06/30 15:01:57 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.291 2004/07/04 15:02:23 meskes Exp $ */ /* Copyright comment */ %{ @@ -504,7 +504,7 @@ add_additional_variables(char *name, bool insert) %type AlterUserSetStmt privilege_list privilege privilege_target %type opt_grant_grant_option opt_revoke_grant_option cursor_options %type transaction_mode_list_or_empty transaction_mode_list -%type function_with_argtypes_list function_with_argtypes +%type function_with_argtypes_list function_with_argtypes IntConstVar %type DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt %type GrantStmt privileges PosAllConst constraints_set_list %type ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait @@ -4204,6 +4204,17 @@ IntConst: PosIntConst { $$ = $1; } | '-' PosIntConst { $$ = cat2_str(make_str("-"), $2); } ; +IntConstVar: Iconst + { + char *length = mm_alloc(32); + + sprintf(length, "%d", (int) strlen($1)); + new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0); + $$ = $1; + } + | cvariable { $$ = $1; } + ; + StringConst: Sconst { $$ = $1; } | civar { $$ = $1; } ; @@ -5283,8 +5294,8 @@ opt_output: SQL_OUTPUT { $$ = make_str("output"); } /* * dynamic SQL: descriptor based access - * written by Christof Petig - * and Peter Eisentraut + * originall written by Christof Petig + * and Peter Eisentraut */ /* @@ -5319,7 +5330,7 @@ ECPGGetDescHeaderItems: ECPGGetDescHeaderItem | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem ; -ECPGGetDescHeaderItem: CVARIABLE '=' desc_header_item +ECPGGetDescHeaderItem: cvariable '=' desc_header_item { push_assignment($1, $3); } ; @@ -5331,8 +5342,10 @@ ECPGSetDescHeaderItems: ECPGSetDescHeaderItem | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem ; -ECPGSetDescHeaderItem: desc_header_item '=' CVARIABLE - { push_assignment($3, $1); } +ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar + { + push_assignment($3, $1); + } ; @@ -5343,9 +5356,7 @@ desc_header_item: SQL_COUNT { $$ = ECPGd_count; } * manipulate a descriptor */ -ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE CVARIABLE ECPGGetDescItems - { $$.str = $5; $$.name = $3; } - | GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems +ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE IntConstVar ECPGGetDescItems { $$.str = $5; $$.name = $3; } ; @@ -5353,12 +5364,10 @@ ECPGGetDescItems: ECPGGetDescItem | ECPGGetDescItems ',' ECPGGetDescItem ; -ECPGGetDescItem: CVARIABLE '=' descriptor_item { push_assignment($1, $3); }; +ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); }; -ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE CVARIABLE ECPGSetDescItems - { $$.str = $5; $$.name = $3; } - | SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGSetDescItems +ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE IntConstVar ECPGSetDescItems { $$.str = $5; $$.name = $3; } ; @@ -5366,7 +5375,11 @@ ECPGSetDescItems: ECPGSetDescItem | ECPGSetDescItems ',' ECPGSetDescItem ; -ECPGSetDescItem: descriptor_item '=' CVARIABLE { push_assignment($3, $1); }; +ECPGSetDescItem: descriptor_item '=' IntConstVar + { + push_assignment($3, $1); + } + ; descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; } diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index 081ed27ca3..207d264771 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -419,7 +419,7 @@ dump_variables(struct arguments * list, int mode) /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, list->indicator->name, list->indicator->type, - NULL, NULL, 0, NULL, NULL); + NULL, NULL, make_str("0"), NULL, NULL); /* Then release the list element. */ if (mode != 0) diff --git a/src/interfaces/ecpg/test/test_desc.pgc b/src/interfaces/ecpg/test/test_desc.pgc index edfa699cdc..aee30bc59f 100644 --- a/src/interfaces/ecpg/test/test_desc.pgc +++ b/src/interfaces/ecpg/test/test_desc.pgc @@ -31,8 +31,7 @@ main() EXEC SQL EXECUTE foo1 USING DESCRIPTOR indesc; - //EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2; - EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1output; + EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2; EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2null, DATA = :val2; EXEC SQL EXECUTE foo1 USING DESCRIPTOR indesc;