Commit 90326c01 authored by Michael Meskes's avatar Michael Meskes

Added SET DESCRIPTOR command.

	Note that this still has some bugs. The functionality is there though, it's just a matter of fixing the bugs now.
Cleaned up error handling in preprocessor.
parent c7beffcc
/* dynamic SQL support routines
*
* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.7 2003/11/29 19:52:08 pgsql Exp $
* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.8 2004/06/30 15:01:56 meskes Exp $
*/
#define POSTGRES_ECPG_INTERNAL
......@@ -110,6 +110,51 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
return (true);
}
static bool
set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
{
switch (vartype)
{
case ECPGt_short:
*target = *(short *) var;
break;
case ECPGt_int:
*target = *(int *) var;
break;
case ECPGt_long:
*target = *(long *) var;
break;
case ECPGt_unsigned_short:
*target = *(unsigned short *) var;
break;
case ECPGt_unsigned_int:
*target = *(unsigned int *) var;
break;
case ECPGt_unsigned_long:
*target = *(unsigned long *) var;
break;
#ifdef HAVE_LONG_LONG_INT_64
case ECPGt_long_long:
*target = *(long long int *) var;
break;
case ECPGt_unsigned_long_long:
*target = *(unsigned long long int *) var;
break;
#endif /* HAVE_LONG_LONG_INT_64 */
case ECPGt_float:
*target = *(float *) var;
break;
case ECPGt_double:
*target = *(double *) var;
break;
default:
ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
return (false);
}
return true;
}
static bool
get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
{
......@@ -385,6 +430,124 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
return (true);
}
bool
ECPGset_desc(int lineno, char *desc_name, int index,...)
{
va_list args;
struct descriptor *desc;
struct descriptor_item *desc_item, *last_di;
for (desc = all_descriptors; desc; desc = desc->next)
{
if (strcmp(desc_name, desc->name)==0)
break;
}
if (desc == NULL)
{
ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name);
return false;
}
for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
{
if (desc_item->num == index)
break;
}
if (desc_item == NULL)
{
desc_item = ECPGalloc(sizeof(*desc_item), lineno);
desc_item->num = index;
desc_item->next = desc->items;
desc->items = desc_item;
}
va_start(args, index);
do
{
enum ECPGdtype itemtype;
long varcharsize;
long offset;
long arrsize;
enum ECPGttype vartype;
void *var;
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);
switch (itemtype)
{
case ECPGd_data:
{
// FIXME: how to do this in general?
switch (vartype)
{
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();
}
break;
}
case ECPGd_indicator:
set_int_item(lineno, &desc_item->indicator, var, vartype);
break;
case ECPGd_length:
set_int_item(lineno, &desc_item->length, var, vartype);
break;
case ECPGd_precision:
set_int_item(lineno, &desc_item->precision, var, vartype);
break;
case ECPGd_scale:
set_int_item(lineno, &desc_item->scale, var, vartype);
break;
case ECPGd_type:
set_int_item(lineno, &desc_item->type, var, vartype);
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);
return false;
}
}
/*if (itemtype == ECPGd_data)
{
free(desc_item->data);
desc_item->data = NULL;
}*/
}
while (true);
return true;
}
bool
ECPGdeallocate_desc(int line, const char *name)
{
......@@ -425,6 +588,7 @@ ECPGallocate_desc(int line, const char *name)
ECPGfree(new);
return false;
}
new->items = NULL;
new->result = PQmakeEmptyPGresult(NULL, 0);
if (!new->result)
{
......
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.34 2004/06/27 12:28:40 meskes Exp $ */
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.35 2004/06/30 15:01:56 meskes Exp $ */
/*
* The aim is to get a simpler inteface to the database routines.
......@@ -1026,6 +1026,9 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
free(str);
}
break;
case ECPGt_descriptor:
break;
default:
/* Not implemented yet */
......@@ -1046,6 +1049,7 @@ ECPGexecute(struct statement * stmt)
PGresult *results;
PGnotify *notify;
struct variable *var;
int desc_counter = 0;
copiedquery = ECPGstrdup(stmt->command, stmt->lineno);
......@@ -1056,64 +1060,116 @@ ECPGexecute(struct statement * stmt)
* so on.
*/
var = stmt->inlist;
while (var)
{
char *newcopy = NULL;
const char *tobeinserted = NULL;
const char *tobeinserted;
char *p;
bool malloced = FALSE;
int hostvarl = 0;
if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
return false;
bool malloced = FALSE;
int hostvarl = 0;
/*
* Now tobeinserted points to an area that is to be inserted at
* the first %s
*/
if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
return false;
strcpy(newcopy, copiedquery);
if ((p = next_insert(newcopy + hostvarl)) == NULL)
tobeinserted = NULL;
/* A descriptor is a special case since it contains many variables but is listed only once. */
if (var->type == ECPGt_descriptor)
{
/*
* We have an argument but we dont have the matched up string
* in the string
*/
ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
return false;
/* We create an additional variable list here, so the same logic applies. */
struct variable desc_inlist;
struct descriptor *desc;
struct descriptor_item *desc_item;
for (desc = all_descriptors; desc; desc = desc->next)
{
if (strcmp(var->pointer, desc->name) == 0)
break;
}
if (desc == NULL)
{
ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer);
return false;
}
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;
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;
if (!ECPGstore_input(stmt, &desc_inlist, &tobeinserted, &malloced))
return false;
break;
}
}
if (!desc_item) /* no more entries found in descriptor */
desc_counter = 0;
}
else
{
strcpy(p, tobeinserted);
hostvarl = strlen(newcopy);
if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
return false;
}
if (tobeinserted)
{
/*
* The strange thing in the second argument is the rest of the
* string from the old string
* Now tobeinserted points to an area that is to be inserted at
* the first %s
*/
strcat(newcopy,
copiedquery
+ (p - newcopy)
+ sizeof("?") - 1 /* don't count the '\0' */ );
}
if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
return false;
/*
* Now everything is safely copied to the newcopy. Lets free the
* oldcopy and let the copiedquery get the var->value from the
* newcopy.
*/
if (malloced)
{
ECPGfree((char *) tobeinserted);
tobeinserted = NULL;
}
strcpy(newcopy, copiedquery);
if ((p = next_insert(newcopy + hostvarl)) == NULL)
{
/*
* We have an argument but we dont have the matched up string
* in the string
*/
ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
return false;
}
else
{
strcpy(p, tobeinserted);
hostvarl = strlen(newcopy);
/*
* The strange thing in the second argument is the rest of the
* string from the old string
*/
strcat(newcopy,
copiedquery
+ (p - newcopy)
+ sizeof("?") - 1 /* don't count the '\0' */ );
}
ECPGfree(copiedquery);
copiedquery = newcopy;
/*
* Now everything is safely copied to the newcopy. Lets free the
* oldcopy and let the copiedquery get the var->value from the
* newcopy.
*/
if (malloced)
{
ECPGfree((char *) tobeinserted);
tobeinserted = NULL;
}
var = var->next;
ECPGfree(copiedquery);
copiedquery = newcopy;
}
if (desc_counter == 0)
var = var->next;
}
/* Check if there are unmatched things left. */
......
......@@ -7,39 +7,42 @@
enum COMPAT_MODE
{
ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE
ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE
};
#define INFORMIX_MODE(X) ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE)
enum ARRAY_TYPE
{
ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR, ECPG_ARRAY_NONE
ECPG_ARRAY_NOT_SET, ECPG_ARRAY_ARRAY, ECPG_ARRAY_VECTOR, ECPG_ARRAY_NONE
};
/* Here are some methods used by the lib. */
/* Returns a pointer to a string containing a simple type name. */
void ECPGadd_mem(void *ptr, int lineno);
bool ECPGget_data(const PGresult *, int, int, int, enum ECPGttype type,
enum ECPGttype, char *, char *, long, long, long, enum ARRAY_TYPE, enum COMPAT_MODE, bool);
struct connection *ECPGget_connection(const char *);
char *ECPGalloc(long, int);
char *ECPGrealloc(void *, long, int);
void ECPGfree(void *);
bool ECPGinit(const struct connection *, const char *, const int);
char *ECPGstrdup(const char *, int);
const char *ECPGtype_name(enum ECPGttype);
unsigned int ECPGDynamicType(Oid);
void ECPGfree_auto_mem(void);
void ECPGclear_auto_mem(void);
void ECPGadd_mem (void *ptr, int lineno);
bool ECPGget_data (const PGresult *, int, int, int, enum ECPGttype type,
enum ECPGttype, char *, char *, long, long, long,
enum ARRAY_TYPE, enum COMPAT_MODE, bool);
struct connection *ECPGget_connection (const char *);
char *ECPGalloc (long, int);
char *ECPGrealloc (void *, long, int);
void ECPGfree (void *);
bool ECPGinit (const struct connection *, const char *, const int);
char *ECPGstrdup (const char *, int);
const char *ECPGtype_name (enum ECPGttype);
unsigned int ECPGDynamicType (Oid);
void ECPGfree_auto_mem (void);
void ECPGclear_auto_mem (void);
struct descriptor *ecpggetdescp (int, char *);
/* A generic varchar type. */
struct ECPGgeneric_varchar
{
int len;
char arr[1];
int len;
char arr[1];
};
/*
......@@ -48,64 +51,79 @@ struct ECPGgeneric_varchar
struct ECPGtype_information_cache
{
struct ECPGtype_information_cache *next;
int oid;
bool isarray;
struct ECPGtype_information_cache *next;
int oid;
bool isarray;
};
/* structure to store one statement */
struct statement
{
int lineno;
char *command;
struct connection *connection;
enum COMPAT_MODE compat;
bool force_indicator;
struct variable *inlist;
struct variable *outlist;
int lineno;
char *command;
struct connection *connection;
enum COMPAT_MODE compat;
bool force_indicator;
struct variable *inlist;
struct variable *outlist;
};
/* structure to store connections */
struct connection
{
char *name;
PGconn *connection;
bool committed;
int autocommit;
struct ECPGtype_information_cache *cache_head;
struct connection *next;
char *name;
PGconn *connection;
bool committed;
int autocommit;
struct ECPGtype_information_cache *cache_head;
struct connection *next;
};
/* structure to store descriptors */
struct descriptor
{
char *name;
PGresult *result;
struct descriptor *next;
char *name;
PGresult *result;
struct descriptor *next;
int count;
struct descriptor_item *items;
};
extern struct descriptor *all_descriptors;
struct descriptor_item
{
int num;
char *data;
int indicator;
int length;
int precision;
int scale;
int type;
struct descriptor_item *next;
};
struct variable
{
enum ECPGttype type;
void *value;
void *pointer;
long varcharsize;
long arrsize;
long offset;
enum ECPGttype ind_type;
void *ind_value;
void *ind_pointer;
long ind_varcharsize;
long ind_arrsize;
long ind_offset;
struct variable *next;
enum ECPGttype type;
void *value;
void *pointer;
long varcharsize;
long arrsize;
long offset;
enum ECPGttype ind_type;
void *ind_value;
void *ind_pointer;
long ind_varcharsize;
long ind_arrsize;
long ind_offset;
struct variable *next;
};
PGresult **
ECPGdescriptor_lvalue(int line, const char *descriptor);
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_result (const PGresult * results, int act_field,
const struct statement *stmt, struct variable *var);
/* SQLSTATE values generated or processed by ecpglib (intentionally
* not exported -- users should refer to the codes directly) */
......@@ -133,4 +151,4 @@ bool ECPGstore_result(const PGresult *results, int act_field,
#define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR "YE000"
#define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY "YE001"
#endif /* _ECPG_LIB_EXTERN_H */
#endif /* _ECPG_LIB_EXTERN_H */
......@@ -76,6 +76,8 @@ void ECPGraise(int line, int code, const char *sqlstate, const char *str);
void ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat);
bool ECPGget_desc_header(int, char *, int *);
bool ECPGget_desc(int, char *, int,...);
bool ECPGset_desc_header(int, char *, int *);
bool ECPGset_desc(int, char *, int,...);
void ECPGset_noind_null(enum ECPGttype, void *);
bool ECPGis_noind_null(enum ECPGttype, void *);
......
......@@ -58,9 +58,7 @@ ECPGnumeric_lvalue(FILE *f, char *name)
fputs(name, yyout);
break;
default:
snprintf(errortext, sizeof errortext, "variable %s: numeric type needed"
,name);
mmerror(PARSE_ERROR, ET_ERROR, errortext);
mmerror(PARSE_ERROR, ET_ERROR, "variable %s: numeric type needed", name);
break;
}
}
......@@ -120,8 +118,7 @@ drop_descriptor(char *name, char *connection)
}
}
}
snprintf(errortext, sizeof errortext, "unknown descriptor %s", name);
mmerror(PARSE_ERROR, ET_WARNING, errortext);
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor %s", name);
}
struct descriptor
......@@ -143,8 +140,7 @@ lookup_descriptor(char *name, char *connection)
return i;
}
}
snprintf(errortext, sizeof errortext, "unknown descriptor %s", name);
mmerror(PARSE_ERROR, ET_WARNING, errortext);
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor %s", name);
return NULL;
}
......@@ -153,16 +149,13 @@ output_get_descr_header(char *desc_name)
{
struct assignment *results;
fprintf(yyout, "{ ECPGget_desc_header(%d, %s, &(", yylineno, desc_name);
fprintf(yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
for (results = assignments; results != NULL; results = results->next)
{
if (results->value == ECPGd_count)
ECPGnumeric_lvalue(yyout, results->variable);
else
{
snprintf(errortext, sizeof errortext, "unknown descriptor header item '%d'", results->value);
mmerror(PARSE_ERROR, ET_WARNING, errortext);
}
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor header item '%d'", results->value);
}
drop_assignments();
......@@ -175,7 +168,7 @@ output_get_descr(char *desc_name, char *index)
{
struct assignment *results;
fprintf(yyout, "{ ECPGget_desc(%d, %s, %s,", yylineno, desc_name, index);
fprintf(yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
for (results = assignments; results != NULL; results = results->next)
{
const struct variable *v = find_variable(results->variable);
......@@ -200,6 +193,116 @@ output_get_descr(char *desc_name, char *index)
whenever_action(2 | 1);
}
void
output_set_descr_header(char *desc_name)
{
struct assignment *results;
fprintf(yyout, "{ ECPGset_desc_header(__LINE__, %s, &(", desc_name);
for (results = assignments; results != NULL; results = results->next)
{
if (results->value == ECPGd_count)
ECPGnumeric_lvalue(yyout, results->variable);
else
mmerror(PARSE_ERROR, ET_WARNING, "unknown descriptor header item '%d'", results->value);
}
drop_assignments();
fprintf(yyout, "));\n");
whenever_action(3);
}
static const char *
descriptor_item_name(enum ECPGdtype itemcode)
{
switch (itemcode)
{
case ECPGd_cardinality:
return "CARDINALITY";
case ECPGd_count:
return "COUNT";
case ECPGd_data:
return "DATA";
case ECPGd_di_code:
return "DATETIME_INTERVAL_CODE";
case ECPGd_di_precision:
return "DATETIME_INTERVAL_PRECISION";
case ECPGd_indicator:
return "INDICATOR";
case ECPGd_key_member:
return "KEY_MEMBER";
case ECPGd_length:
return "LENGTH";
case ECPGd_name:
return "NAME";
case ECPGd_nullable:
return "NULLABLE";
case ECPGd_octet:
return "OCTET_LENGTH";
case ECPGd_precision:
return "PRECISION";
case ECPGd_ret_length:
return "RETURNED_LENGTH";
case ECPGd_ret_octet:
return "RETURNED_OCTET_LENGTH";
case ECPGd_scale:
return "SCALE";
case ECPGd_type:
return "TYPE";
default:
return NULL;
}
}
void
output_set_descr(char *desc_name, char *index)
{
struct assignment *results;
fprintf(yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
for (results = assignments; results != NULL; results = results->next)
{
const struct variable *v = find_variable(results->variable);
switch (results->value)
{
case ECPGd_cardinality:
case ECPGd_di_code:
case ECPGd_di_precision:
case ECPGd_precision:
case ECPGd_scale:
mmerror(PARSE_ERROR, ET_FATAL, "descriptor item %s is not implemented",
descriptor_item_name(results->value));
break;
case ECPGd_key_member:
case ECPGd_name:
case ECPGd_nullable:
case ECPGd_octet:
case ECPGd_ret_length:
case ECPGd_ret_octet:
mmerror(PARSE_ERROR, ET_FATAL, "descriptor item %s cannot be set",
descriptor_item_name(results->value));
break;
case ECPGd_data:
case ECPGd_indicator:
case ECPGd_length:
case ECPGd_type:
fprintf(yyout, "%s,", get_dtype(results->value));
ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
break;
default:
;
}
}
drop_assignments();
fputs("ECPGd_EODT);\n", yyout);
whenever_action(2 | 1);
}
/* I consider dynamic allocation overkill since at most two descriptor
variables are possible per statement. (input and output descriptor)
And descriptors are no normal variables, so they don't belong into
......@@ -211,11 +314,10 @@ struct variable *
descriptor_variable(const char *name, int input)
{
static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
static const struct ECPGtype descriptor_type =
{ECPGt_descriptor, 0};
static const struct variable varspace[2] =
{{descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL},
{descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL}
static const struct ECPGtype descriptor_type = { ECPGt_descriptor, 0 };
static const struct variable varspace[2] = {
{ descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL },
{ descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL }
};
strncpy(descriptor_names[input], name, MAX_DESCRIPTOR_NAMELEN);
......
......@@ -25,8 +25,7 @@ extern char *descriptor_name;
extern char *connection;
extern char *input_filename;
extern char *yytext,
*token_start,
errortext[128];
*token_start;
#ifdef YYDEBUG
extern int yydebug;
......@@ -63,11 +62,13 @@ extern int yylex(void);
extern void yyerror(char *);
extern void *mm_alloc(size_t), *mm_realloc(void *, size_t);
extern char *mm_strdup(const char *);
extern void mmerror(int, enum errortype, char *);
extern void mmerror(int, enum errortype, char *, ...);
extern ScanKeyword *ScanECPGKeywordLookup(char *);
extern ScanKeyword *ScanCKeywordLookup(char *);
extern void output_get_descr_header(char *);
extern void output_get_descr(char *, char *);
extern void output_set_descr_header(char *);
extern void output_set_descr(char *, char *);
extern void push_assignment(char *, enum ECPGdtype);
extern struct variable *find_variable(char *);
extern void whenever_action(int);
......
......@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.128 2004/05/05 15:03:04 meskes Exp $
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.129 2004/06/30 15:01:57 meskes Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1164,10 +1164,7 @@ parse_include(void)
}
}
if (!yyin)
{
snprintf(errortext, sizeof(errortext), "Cannot open include file %s in line %d\n", yytext, yylineno);
mmerror(NO_INCLUDE_FILE, ET_FATAL, errortext);
}
mmerror(NO_INCLUDE_FILE, ET_FATAL, "Cannot open include file %s in line %d\n", yytext, yylineno);
input_filename = mm_strdup(inc_file);
yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ));
......
This diff is collapsed.
......@@ -195,8 +195,7 @@ get_type(enum ECPGttype type)
return ("ECPGt_timestamp");
break;
default:
sprintf(errortext, "illegal variable type %d\n", type);
yyerror(errortext);
mmerror(PARSE_ERROR, ET_ERROR, "illegal variable type %d\n", type);
}
return NULL;
......@@ -538,8 +537,7 @@ ECPGfree_type(struct ECPGtype * type)
ECPGfree_struct_member(type->u.members);
break;
default:
sprintf(errortext, "illegal variable type %d\n", type->type);
yyerror(errortext);
mmerror(PARSE_ERROR, ET_ERROR, "illegal variable type %d\n", type->type);
break;
}
}
......@@ -598,8 +596,7 @@ get_dtype(enum ECPGdtype type)
case ECPGd_cardinality:
return ("ECPGd_cardinality");
default:
sprintf(errortext, "illegal descriptor item %d\n", type);
yyerror(errortext);
mmerror(PARSE_ERROR, ET_ERROR, "illegal descriptor item %d\n", type);
}
return NULL;
......
......@@ -84,10 +84,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
case '\0': /* found the end, but this time it has to
* be an array element */
if (members->type->type != ECPGt_array)
{
snprintf(errortext, sizeof(errortext), "incorrectly formed variable %s", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable %s", name);
switch (members->type->u.element->type)
{
......@@ -110,8 +107,7 @@ find_struct_member(char *name, char *str, struct ECPGstruct_member * members, in
return (find_struct_member(name, end, members->type->u.members, brace_level));
break;
default:
snprintf(errortext, sizeof(errortext), "incorrectly formed variable %s", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
mmerror(PARSE_ERROR, ET_FATAL, "incorrectly formed variable %s", name);
break;
}
}
......@@ -134,16 +130,10 @@ find_struct(char *name, char *next, char *end)
if (c == '-')
{
if (p->type->type != ECPGt_array)
{
snprintf(errortext, sizeof(errortext), "variable %s is not a pointer", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "variable %s is not a pointer", name);
if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
{
snprintf(errortext, sizeof(errortext), "variable %s is not a pointer to a structure or a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "variable %s is not a pointer to a structure or a union", name);
/* restore the name, we will need it later */
*next = c;
......@@ -155,10 +145,7 @@ find_struct(char *name, char *next, char *end)
if (next == end)
{
if (p->type->type != ECPGt_struct && p->type->type != ECPGt_union)
{
snprintf(errortext, sizeof(errortext), "variable %s is neither a structure nor a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "variable %s is neither a structure nor a union", name);
/* restore the name, we will need it later */
*next = c;
......@@ -168,16 +155,10 @@ find_struct(char *name, char *next, char *end)
else
{
if (p->type->type != ECPGt_array)
{
snprintf(errortext, sizeof(errortext), "variable %s is not an array", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "variable %s is not an array", name);
if (p->type->u.element->type != ECPGt_struct && p->type->u.element->type != ECPGt_union)
{
snprintf(errortext, sizeof(errortext), "variable %s is not a pointer to a structure or a union", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "variable %s is not a pointer to a structure or a union", name);
/* restore the name, we will need it later */
*next = c;
......@@ -243,10 +224,8 @@ find_variable(char *name)
*next = '\0';
p = find_simple(name);
if (p == NULL)
{
snprintf(errortext, sizeof(errortext), "The variable %s is not declared", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "The variable %s is not declared", name);
*next = c;
switch (p->type->u.element->type)
{
......@@ -267,10 +246,7 @@ find_variable(char *name)
p = find_simple(name);
if (p == NULL)
{
snprintf(errortext, sizeof(errortext), "The variable %s is not declared", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "The variable %s is not declared", name);
return (p);
}
......@@ -490,10 +466,7 @@ get_typedef(char *name)
for (this = types; this && strcmp(this->name, name); this = this->next);
if (!this)
{
snprintf(errortext, sizeof(errortext), "invalid datatype '%s'", name);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "invalid datatype '%s'", name);
return (this);
}
......@@ -521,10 +494,7 @@ adjust_array(enum ECPGttype type_enum, char **dimension, char **length, char *ty
}
if (pointer_len > 2)
{
snprintf(errortext, sizeof(errortext), "No multilevel (more than 2) pointer supported %d", pointer_len);
mmerror(PARSE_ERROR, ET_FATAL, errortext);
}
mmerror(PARSE_ERROR, ET_FATAL, "No multilevel (more than 2) pointer supported %d", pointer_len);
if (pointer_len > 1 && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char)
mmerror(PARSE_ERROR, ET_FATAL, "No pointer to pointer supported for this type");
......
EXEC SQL WHENEVER SQLERROR SQLPRINT;
int
main()
{
EXEC SQL BEGIN DECLARE SECTION;
char *stmt1 = "INSERT INTO test1 VALUES (?, ?)";
char *stmt2 = "SELECT * from test1 where a = ? and b = ?";
int val1 = 1;
char val2[] = "one", val2output[] = "AAA";
int val1output = 2, val2i = 0;
int val2null = 1;
EXEC SQL END DECLARE SECTION;
FILE *dbgs;
if ((dbgs = fopen("log", "w")) != NULL)
ECPGdebug(1, dbgs);
EXEC SQL ALLOCATE DESCRIPTOR indesc;
EXEC SQL ALLOCATE DESCRIPTOR outdesc;
EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2i, DATA = :val2;
EXEC SQL CONNECT TO mm;
EXEC SQL CREATE TABLE test1 (a int, b text);
EXEC SQL PREPARE foo1 FROM :stmt1;
EXEC SQL PREPARE foo2 FROM :stmt2;
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 2 INDICATOR = :val2null, DATA = :val2;
EXEC SQL EXECUTE foo1 USING DESCRIPTOR indesc;
EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2i, DATA = :val2;
EXEC SQL EXECUTE foo2 USING DESCRIPTOR indesc INTO DESCRIPTOR outdesc;
EXEC SQL GET DESCRIPTOR outdesc VALUE 1 :val2output = DATA;
printf("output = %s\n", val2output);
EXEC SQL DECLARE c CURSOR FOR foo2;
EXEC SQL OPEN c USING DESCRIPTOR indesc;
EXEC SQL FETCH next FROM c INTO :val1output, :val2output;
printf("val1=%d val2=%s\n", val1output, val2output);
EXEC SQL CLOSE c;
EXEC SQL SELECT * INTO :val1output, :val2output FROM test1 where a = 2;
printf("val1=%d val2=%s\n", val1output, val2output);
EXEC SQL DROP TABLE test1;
EXEC SQL DISCONNECT;
EXEC SQL DEALLOCATE DESCRIPTOR indesc;
EXEC SQL DEALLOCATE DESCRIPTOR outdesc;
if (dbgs != NULL)
fclose(dbgs);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment