/* 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
va_list args;
struct descriptor *desc;
struct descriptor_item *desc_item;
+ struct variable *var;
for (desc = all_descriptors; desc; desc = desc->next)
{
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:
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;
}
}
}*/
}
while (true);
+ ECPGfree(var);
return true;
}
-/* $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.
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
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)
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)
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;
#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
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";
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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, "]");
}
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;
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;
{
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);
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;
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)
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);
{
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)
}
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 ");
{
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)
}
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 ");
{
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)
}
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 ");
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;
}
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;
}
else
{
- if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
+ if (!ECPGstore_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, &malloced))
return false;
}
if (tobeinserted)
-/* $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 */
%{
%type <str> AlterUserSetStmt privilege_list privilege privilege_target
%type <str> opt_grant_grant_option opt_revoke_grant_option cursor_options
%type <str> transaction_mode_list_or_empty transaction_mode_list
-%type <str> function_with_argtypes_list function_with_argtypes
+%type <str> function_with_argtypes_list function_with_argtypes IntConstVar
%type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
%type <str> GrantStmt privileges PosAllConst constraints_set_list
%type <str> ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait
| '-' 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; }
;
/*
* dynamic SQL: descriptor based access
- * written by Christof Petig <christof.petig@wtal.de>
- * and Peter Eisentraut <peter.eisentraut@credativ.de>
+ * originall written by Christof Petig <christof.petig@wtal.de>
+ * and Peter Eisentraut <peter.eisentraut@credativ.de>
*/
/*
| ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
;
-ECPGGetDescHeaderItem: CVARIABLE '=' desc_header_item
+ECPGGetDescHeaderItem: cvariable '=' desc_header_item
{ push_assignment($1, $3); }
;
| ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
;
-ECPGSetDescHeaderItem: desc_header_item '=' CVARIABLE
- { push_assignment($3, $1); }
+ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
+ {
+ push_assignment($3, $1);
+ }
;
* 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; }
;
| 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; }
;
| ECPGSetDescItems ',' ECPGSetDescItem
;
-ECPGSetDescItem: descriptor_item '=' CVARIABLE { push_assignment($3, $1); };
+ECPGSetDescItem: descriptor_item '=' IntConstVar
+ {
+ push_assignment($3, $1);
+ }
+ ;
descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }