diff options
Diffstat (limited to 'src/interfaces/ecpg/lib/ecpglib.c')
-rw-r--r-- | src/interfaces/ecpg/lib/ecpglib.c | 970 |
1 files changed, 489 insertions, 481 deletions
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index b2bb9f1415..3804544514 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -25,58 +25,58 @@ #include <sqlca.h> /* variables visible to the programs */ -int no_auto_trans; +int no_auto_trans; -static struct sqlca sqlca_init = +static struct sqlca sqlca_init = { - {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, - sizeof(struct sqlca), - 0, - { 0, {0}}, - {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0} + {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, + sizeof(struct sqlca), + 0, + {0, {0}}, + {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} }; struct sqlca sqlca = { - {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, - sizeof(struct sqlca), - 0, - { 0, {0}}, - {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0} + {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '}, + sizeof(struct sqlca), + 0, + {0, {0}}, + {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '}, + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0} }; static struct connection { - char *name; - PGconn *connection; + char *name; + PGconn *connection; struct connection *next; -} *all_connections = NULL, *actual_connection = NULL; +} *all_connections = NULL, *actual_connection = NULL; struct variable { enum ECPGttype type; - void *value; - long varcharsize; - long arrsize; - long offset; + void *value; + long varcharsize; + long arrsize; + long offset; enum ECPGttype ind_type; - void *ind_value; - long ind_varcharsize; - long ind_arrsize; - long ind_offset; + void *ind_value; + long ind_varcharsize; + long ind_arrsize; + long ind_offset; struct variable *next; }; struct statement { - int lineno; - char *command; + int lineno; + char *command; struct variable *inlist; struct variable *outlist; }; @@ -98,7 +98,7 @@ register_error(long code, char *fmt,...) } static void -ECPGfinish(struct connection *act) +ECPGfinish(struct connection * act) { if (act != NULL) { @@ -114,8 +114,8 @@ ECPGfinish(struct connection *act) else { struct connection *con; - - for (con = all_connections; con->next && con->next != act; con = con->next); + + for (con = all_connections; con->next && con->next != act; con = con->next); if (con->next) { con->next = act->next; @@ -123,7 +123,7 @@ ECPGfinish(struct connection *act) free(act); } } - + if (actual_connection == act) actual_connection = all_connections; } @@ -131,20 +131,21 @@ ECPGfinish(struct connection *act) ECPGlog("ECPGfinish: called an extra time.\n"); } -static char *ecpg_alloc(long size, int lineno) +static char * +ecpg_alloc(long size, int lineno) { - char *new = (char *) malloc(size); + char *new = (char *) malloc(size); if (!new) { ECPGfinish(actual_connection); ECPGlog("out of memory\n"); - register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); + register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno); return NULL; } - + memset(new, '\0', size); - return(new); + return (new); } /* This function returns a newly malloced string that has the ' and \ @@ -159,8 +160,8 @@ quote_postgres(char *arg, int lineno) ri; if (!res) - return(res); - + return (res); + for (i = 0, ri = 0; arg[i]; i++, ri++) { switch (arg[i]) @@ -181,62 +182,61 @@ quote_postgres(char *arg, int lineno) /* create a list of variables */ static bool -create_statement(int lineno, struct statement **stmt, char *query, va_list ap) +create_statement(int lineno, struct statement ** stmt, char *query, va_list ap) { struct variable **list = &((*stmt)->inlist); - enum ECPGttype type; - + enum ECPGttype type; + if (!(*stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno))) return false; - + (*stmt)->command = query; (*stmt)->lineno = lineno; - + list = &((*stmt)->inlist); type = va_arg(ap, enum ECPGttype); - + while (type != ECPGt_EORT) - { - if (type == ECPGt_EOIT) - { - list = &((*stmt)->outlist); - } - else - { - struct variable *var, *ptr; - - if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno))) - return false; - - var->type = type; - var->value = va_arg(ap, void *); - var->varcharsize = va_arg(ap, long); - var->arrsize = va_arg(ap, long); - var->offset = va_arg(ap, long); - var->ind_type = va_arg(ap, enum ECPGttype); - var->ind_value = va_arg(ap, void *); - var->ind_varcharsize = va_arg(ap, long); - var->ind_arrsize = va_arg(ap, long); - var->ind_offset = va_arg(ap, long); - var->next = NULL; - - for (ptr = *list; ptr && ptr->next; ptr=ptr->next); - - if (ptr == NULL) - *list = var; + { + if (type == ECPGt_EOIT) + list = &((*stmt)->outlist); else - ptr->next = var; - } - - type = va_arg(ap, enum ECPGttype); + { + struct variable *var, + *ptr; + + if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno))) + return false; + + var->type = type; + var->value = va_arg(ap, void *); + var->varcharsize = va_arg(ap, long); + var->arrsize = va_arg(ap, long); + var->offset = va_arg(ap, long); + var->ind_type = va_arg(ap, enum ECPGttype); + var->ind_value = va_arg(ap, void *); + var->ind_varcharsize = va_arg(ap, long); + var->ind_arrsize = va_arg(ap, long); + var->ind_offset = va_arg(ap, long); + var->next = NULL; + + for (ptr = *list; ptr && ptr->next; ptr = ptr->next); + + if (ptr == NULL) + *list = var; + else + ptr->next = var; + } + + type = va_arg(ap, enum ECPGttype); } - - return(true); + + return (true); } static bool -ECPGexecute(struct statement *stmt) +ECPGexecute(struct statement * stmt) { bool status = false; char *copiedquery; @@ -244,8 +244,8 @@ ECPGexecute(struct statement *stmt) PGnotify *notify; struct variable *var; - memcpy((char *)&sqlca, (char *)&sqlca_init, sizeof(sqlca)); - + memcpy((char *) &sqlca, (char *) &sqlca_init, sizeof(sqlca)); + copiedquery = strdup(stmt->command); /* @@ -270,7 +270,7 @@ ECPGexecute(struct statement *stmt) */ buff[0] = '\0'; - + /* check for null value and set input buffer accordingly */ switch (var->ind_type) { @@ -292,117 +292,117 @@ ECPGexecute(struct statement *stmt) default: break; } - + if (*buff == '\0') { - switch (var->type) - { - case ECPGt_short: - case ECPGt_int: - sprintf(buff, "%d", *(int *) var->value); - tobeinserted = buff; - break; + switch (var->type) + { + case ECPGt_short: + case ECPGt_int: + sprintf(buff, "%d", *(int *) var->value); + tobeinserted = buff; + break; - case ECPGt_unsigned_short: - case ECPGt_unsigned_int: - sprintf(buff, "%d", *(unsigned int *) var->value); - tobeinserted = buff; - break; + case ECPGt_unsigned_short: + case ECPGt_unsigned_int: + sprintf(buff, "%d", *(unsigned int *) var->value); + tobeinserted = buff; + break; - case ECPGt_long: - sprintf(buff, "%ld", *(long *) var->value); - tobeinserted = buff; - break; + case ECPGt_long: + sprintf(buff, "%ld", *(long *) var->value); + tobeinserted = buff; + break; - case ECPGt_unsigned_long: - sprintf(buff, "%ld", *(unsigned long *) var->value); - tobeinserted = buff; - break; + case ECPGt_unsigned_long: + sprintf(buff, "%ld", *(unsigned long *) var->value); + tobeinserted = buff; + break; - case ECPGt_float: - sprintf(buff, "%.14g", *(float *) var->value); - tobeinserted = buff; - break; + case ECPGt_float: + sprintf(buff, "%.14g", *(float *) var->value); + tobeinserted = buff; + break; - case ECPGt_double: - sprintf(buff, "%.14g", *(double *) var->value); - tobeinserted = buff; - break; + case ECPGt_double: + sprintf(buff, "%.14g", *(double *) var->value); + tobeinserted = buff; + break; - case ECPGt_bool: - sprintf(buff, "'%c'", (*(char *) var->value ? 't' : 'f')); - tobeinserted = buff; - break; + case ECPGt_bool: + sprintf(buff, "'%c'", (*(char *) var->value ? 't' : 'f')); + tobeinserted = buff; + break; - case ECPGt_char: - case ECPGt_unsigned_char: - { - /* set slen to string length if type is char * */ - int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; - char * tmp; - - if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno))) - return false; - - strncpy(newcopy, (char *) var->value, slen); - newcopy[slen] = '\0'; - - if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) - return false; - - strcpy(mallocedval, "'"); - tmp = quote_postgres(newcopy, stmt->lineno); - if (!tmp) - return false; - - strcat(mallocedval, tmp); - strcat(mallocedval, "'"); - - free(newcopy); - - tobeinserted = mallocedval; - } - break; + case ECPGt_char: + case ECPGt_unsigned_char: + { + /* set slen to string length if type is char * */ + int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize; + char *tmp; - case ECPGt_varchar: - { - struct ECPGgeneric_varchar *variable = - (struct ECPGgeneric_varchar *) (var->value); - char *tmp; - - if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno))) - return false; - - strncpy(newcopy, variable->arr, variable->len); - newcopy[variable->len] = '\0'; - - if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) - return false; - - strcpy(mallocedval, "'"); - tmp = quote_postgres(newcopy, stmt->lineno); - if (!tmp) - return false; - - strcat(mallocedval, tmp); - strcat(mallocedval, "'"); - - free(newcopy); - - tobeinserted = mallocedval; - } - break; + if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno))) + return false; - default: - /* Not implemented yet */ - register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", - ECPGtype_name(var->type), stmt->lineno); - return false; - break; - } + strncpy(newcopy, (char *) var->value, slen); + newcopy[slen] = '\0'; + + if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) + return false; + + strcpy(mallocedval, "'"); + tmp = quote_postgres(newcopy, stmt->lineno); + if (!tmp) + return false; + + strcat(mallocedval, tmp); + strcat(mallocedval, "'"); + + free(newcopy); + + tobeinserted = mallocedval; + } + break; + + case ECPGt_varchar: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); + char *tmp; + + if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno))) + return false; + + strncpy(newcopy, variable->arr, variable->len); + newcopy[variable->len] = '\0'; + + if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno))) + return false; + + strcpy(mallocedval, "'"); + tmp = quote_postgres(newcopy, stmt->lineno); + if (!tmp) + return false; + + strcat(mallocedval, tmp); + strcat(mallocedval, "'"); + + free(newcopy); + + tobeinserted = mallocedval; + } + break; + + default: + /* Not implemented yet */ + register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", + ECPGtype_name(var->type), stmt->lineno); + return false; + break; + } } else - tobeinserted = buff; + tobeinserted = buff; /* * Now tobeinserted points to an area that is to be inserted at @@ -410,7 +410,7 @@ ECPGexecute(struct statement *stmt) */ if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno))) return false; - + strcpy(newcopy, copiedquery); if ((p = strstr(newcopy, ";;")) == NULL) { @@ -438,7 +438,8 @@ ECPGexecute(struct statement *stmt) /* * Now everything is safely copied to the newcopy. Lets free the - * oldcopy and let the copiedquery get the var->value from the newcopy. + * oldcopy and let the copiedquery get the var->value from the + * newcopy. */ if (mallocedval != NULL) { @@ -481,7 +482,7 @@ ECPGexecute(struct statement *stmt) ECPGlog("ECPGexecute line %d: error: %s", stmt->lineno, PQerrorMessage(actual_connection->connection)); register_error(ECPG_PGSQL, "Postgres error: %s line %d.", - PQerrorMessage(actual_connection->connection), stmt->lineno); + PQerrorMessage(actual_connection->connection), stmt->lineno); } else { @@ -489,7 +490,10 @@ ECPGexecute(struct statement *stmt) var = stmt->outlist; switch (PQresultStatus(results)) { - int nfields, ntuples, act_tuple, act_field; + int nfields, + ntuples, + act_tuple, + act_field; case PGRES_TUPLES_OK: @@ -502,7 +506,7 @@ ECPGexecute(struct statement *stmt) nfields = PQnfields(results); sqlca.sqlerrd[2] = ntuples = PQntuples(results); status = true; - + if (ntuples < 1) { ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n", @@ -512,268 +516,274 @@ ECPGexecute(struct statement *stmt) break; } - for (act_field = 0; act_field < nfields && status; act_field++) - { - char *pval; - char *scan_length; - - if (var == NULL) - { - ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno); - register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); - return(false); - } - - /* if we don't have enough space, we cannot read all tuples */ - if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) - { - ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", - stmt->lineno, ntuples, var->arrsize); - register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", stmt->lineno); - status = false; - break; - } - for (act_tuple = 0; act_tuple < ntuples; act_tuple++) - { - pval = PQgetvalue(results, act_tuple, act_field); - - ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : ""); - - /* Now the pval is a pointer to the var->value. */ - /* We will have to decode the var->value */ - - /* check for null var->value and set indicator accordingly */ - switch (var->ind_type) - { - case ECPGt_short: - case ECPGt_unsigned_short: - ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); - break; - case ECPGt_int: - case ECPGt_unsigned_int: - ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); - break; - case ECPGt_long: - case ECPGt_unsigned_long: - ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); - break; - default: - break; - } - - switch (var->type) - { - long res; - unsigned long ures; - double dres; - - case ECPGt_short: - case ECPGt_int: - case ECPGt_long: - if (pval) - { - res = strtol(pval, &scan_length, 10); - if (*scan_length != '\0') /* Garbage left */ - { - register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.", - pval, stmt->lineno); - status = false; - res = 0L; - } - } - else - res = 0L; - - /* Again?! Yes */ - switch (var->type) - { - case ECPGt_short: - ((short *) var->value)[act_tuple] = (short) res; - break; - case ECPGt_int: - ((int *) var->value)[act_tuple] = (int) res; - break; - case ECPGt_long: - ((long *) var->value)[act_tuple] = res; - break; - default: - /* Cannot happen */ - break; - } - break; - - case ECPGt_unsigned_short: - case ECPGt_unsigned_int: - case ECPGt_unsigned_long: - if (pval) - { - ures = strtoul(pval, &scan_length, 10); - if (*scan_length != '\0') /* Garbage left */ - { - register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.", - pval, stmt->lineno); - status = false; - ures = 0L; - } - } - else - ures = 0L; - - /* Again?! Yes */ - switch (var->type) - { - case ECPGt_unsigned_short: - ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures; - break; - case ECPGt_unsigned_int: - ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures; - break; - case ECPGt_unsigned_long: - ((unsigned long *) var->value)[act_tuple] = ures; - break; - default: - /* Cannot happen */ - break; - } - break; - - - case ECPGt_float: - case ECPGt_double: - if (pval) - { - dres = strtod(pval, &scan_length); - if (*scan_length != '\0') /* Garbage left */ - { - register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.", - pval, stmt->lineno); - status = false; - dres = 0.0; - } - } - else - dres = 0.0; - - /* Again?! Yes */ - switch (var->type) - { - case ECPGt_float: - ((float *) var->value)[act_tuple] = dres; - break; - case ECPGt_double: - ((double *) var->value)[act_tuple] = dres; - break; - default: - /* Cannot happen */ - break; - } - break; - - case ECPGt_bool: - if (pval) - { - if (pval[0] == 'f' && pval[1] == '\0') - { - ((char *) var->value)[act_tuple] = false; - break; - } - else if (pval[0] == 't' && pval[1] == '\0') - { - ((char *) var->value)[act_tuple] = true; - break; - } - } - - register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.", - (pval ? pval : "NULL"), - stmt->lineno); - status = false; - break; - - case ECPGt_char: - case ECPGt_unsigned_char: - { - if (var->varcharsize == 0) - { - /* char* */ - strncpy(((char **) var->value)[act_tuple], pval, strlen(pval)); - (((char **) var->value)[act_tuple])[strlen(pval)] = '\0'; - } - else - { - strncpy((char *) ((long)var->value + var->offset * act_tuple), pval, var->varcharsize); - if (var->varcharsize < strlen(pval)) - { - /* truncation */ - switch (var->ind_type) - { - case ECPGt_short: - case ECPGt_unsigned_short: - ((short *) var->ind_value)[act_tuple] = var->varcharsize; - break; - case ECPGt_int: - case ECPGt_unsigned_int: - ((int *) var->ind_value)[act_tuple] = var->varcharsize; - break; - case ECPGt_long: - case ECPGt_unsigned_long: - ((long *) var->ind_value)[act_tuple] = var->varcharsize; - break; - default: - break; - } - sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; - } - } - } - break; - - case ECPGt_varchar: - { - struct ECPGgeneric_varchar *variable = - (struct ECPGgeneric_varchar *) ((long)var->value + var->offset * act_tuple); - - if (var->varcharsize == 0) - strncpy(variable->arr, pval, strlen(pval)); - else - strncpy(variable->arr, pval, var->varcharsize); - - variable->len = strlen(pval); - if (var->varcharsize > 0 && variable->len > var->varcharsize) - { - /* truncation */ - switch (var->ind_type) - { - case ECPGt_short: - case ECPGt_unsigned_short: - ((short *) var->ind_value)[act_tuple] = var->varcharsize; - break; - case ECPGt_int: - case ECPGt_unsigned_int: - ((int *) var->ind_value)[act_tuple] = var->varcharsize; - break; - case ECPGt_long: - case ECPGt_unsigned_long: - ((long *) var->ind_value)[act_tuple] = var->varcharsize; - break; - default: - break; - } - sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; - - variable->len = var->varcharsize; - } - } - break; - - default: - register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", - ECPGtype_name(var->type), stmt->lineno); - status = false; - break; - } - } - var = var->next; + for (act_field = 0; act_field < nfields && status; act_field++) + { + char *pval; + char *scan_length; + + if (var == NULL) + { + ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno); + register_error(ECPG_TOO_FEW_ARGUMENTS, "Too few arguments line %d.", stmt->lineno); + return (false); + } + + /* + * if we don't have enough space, we cannot read all + * tuples + */ + if ((var->arrsize > 0 && ntuples > var->arrsize) || (var->ind_arrsize > 0 && ntuples > var->ind_arrsize)) + { + ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", + stmt->lineno, ntuples, var->arrsize); + register_error(ECPG_TOO_MANY_MATCHES, "Too many matches line %d.", stmt->lineno); + status = false; + break; + } + for (act_tuple = 0; act_tuple < ntuples; act_tuple++) + { + pval = PQgetvalue(results, act_tuple, act_field); + + ECPGlog("ECPGexecute line %d: RESULT: %s\n", stmt->lineno, pval ? pval : ""); + + /* Now the pval is a pointer to the var->value. */ + /* We will have to decode the var->value */ + + /* + * check for null var->value and set indicator + * accordingly + */ + switch (var->ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + ((short *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + break; + case ECPGt_int: + case ECPGt_unsigned_int: + ((int *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + break; + case ECPGt_long: + case ECPGt_unsigned_long: + ((long *) var->ind_value)[act_tuple] = -PQgetisnull(results, act_tuple, act_field); + break; + default: + break; + } + + switch (var->type) + { + long res; + unsigned long ures; + double dres; + + case ECPGt_short: + case ECPGt_int: + case ECPGt_long: + if (pval) + { + res = strtol(pval, &scan_length, 10); + if (*scan_length != '\0') /* Garbage left */ + { + register_error(ECPG_INT_FORMAT, "Not correctly formatted int type: %s line %d.", + pval, stmt->lineno); + status = false; + res = 0L; + } + } + else + res = 0L; + + /* Again?! Yes */ + switch (var->type) + { + case ECPGt_short: + ((short *) var->value)[act_tuple] = (short) res; + break; + case ECPGt_int: + ((int *) var->value)[act_tuple] = (int) res; + break; + case ECPGt_long: + ((long *) var->value)[act_tuple] = res; + break; + default: + /* Cannot happen */ + break; + } + break; + + case ECPGt_unsigned_short: + case ECPGt_unsigned_int: + case ECPGt_unsigned_long: + if (pval) + { + ures = strtoul(pval, &scan_length, 10); + if (*scan_length != '\0') /* Garbage left */ + { + register_error(ECPG_UINT_FORMAT, "Not correctly formatted unsigned type: %s line %d.", + pval, stmt->lineno); + status = false; + ures = 0L; + } + } + else + ures = 0L; + + /* Again?! Yes */ + switch (var->type) + { + case ECPGt_unsigned_short: + ((unsigned short *) var->value)[act_tuple] = (unsigned short) ures; + break; + case ECPGt_unsigned_int: + ((unsigned int *) var->value)[act_tuple] = (unsigned int) ures; + break; + case ECPGt_unsigned_long: + ((unsigned long *) var->value)[act_tuple] = ures; + break; + default: + /* Cannot happen */ + break; + } + break; + + + case ECPGt_float: + case ECPGt_double: + if (pval) + { + dres = strtod(pval, &scan_length); + if (*scan_length != '\0') /* Garbage left */ + { + register_error(ECPG_FLOAT_FORMAT, "Not correctly formatted floating point type: %s line %d.", + pval, stmt->lineno); + status = false; + dres = 0.0; + } + } + else + dres = 0.0; + + /* Again?! Yes */ + switch (var->type) + { + case ECPGt_float: + ((float *) var->value)[act_tuple] = dres; + break; + case ECPGt_double: + ((double *) var->value)[act_tuple] = dres; + break; + default: + /* Cannot happen */ + break; + } + break; + + case ECPGt_bool: + if (pval) + { + if (pval[0] == 'f' && pval[1] == '\0') + { + ((char *) var->value)[act_tuple] = false; + break; + } + else if (pval[0] == 't' && pval[1] == '\0') + { + ((char *) var->value)[act_tuple] = true; + break; + } + } + + register_error(ECPG_CONVERT_BOOL, "Unable to convert %s to bool on line %d.", + (pval ? pval : "NULL"), + stmt->lineno); + status = false; + break; + + case ECPGt_char: + case ECPGt_unsigned_char: + { + if (var->varcharsize == 0) + { + /* char* */ + strncpy(((char **) var->value)[act_tuple], pval, strlen(pval)); + (((char **) var->value)[act_tuple])[strlen(pval)] = '\0'; + } + else + { + strncpy((char *) ((long) var->value + var->offset * act_tuple), pval, var->varcharsize); + if (var->varcharsize < strlen(pval)) + { + /* truncation */ + switch (var->ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + ((short *) var->ind_value)[act_tuple] = var->varcharsize; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + ((int *) var->ind_value)[act_tuple] = var->varcharsize; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + ((long *) var->ind_value)[act_tuple] = var->varcharsize; + break; + default: + break; + } + sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; + } + } + } + break; + + case ECPGt_varchar: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple); + + if (var->varcharsize == 0) + strncpy(variable->arr, pval, strlen(pval)); + else + strncpy(variable->arr, pval, var->varcharsize); + + variable->len = strlen(pval); + if (var->varcharsize > 0 && variable->len > var->varcharsize) + { + /* truncation */ + switch (var->ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + ((short *) var->ind_value)[act_tuple] = var->varcharsize; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + ((int *) var->ind_value)[act_tuple] = var->varcharsize; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + ((long *) var->ind_value)[act_tuple] = var->varcharsize; + break; + default: + break; + } + sqlca.sqlwarn[0] = sqlca.sqlwarn[1] = 'W'; + + variable->len = var->varcharsize; + } + } + break; + + default: + register_error(ECPG_UNSUPPORTED, "Unsupported type %s on line %d.", + ECPGtype_name(var->type), stmt->lineno); + status = false; + break; + } + } + var = var->next; } if (status && var != NULL) @@ -832,30 +842,30 @@ ECPGexecute(struct statement *stmt) } bool -ECPGdo(int lineno, char *query, ...) +ECPGdo(int lineno, char *query,...) { - va_list args; - struct statement *stmt; - + va_list args; + struct statement *stmt; + va_start(args, query); if (create_statement(lineno, &stmt, query, args) == false) - return(false); + return (false); va_end(args); /* are we connected? */ if (actual_connection == NULL || actual_connection->connection == NULL) - { + { ECPGlog("ECPGdo: not connected\n"); register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno); return false; - } + } - return(ECPGexecute(stmt)); + return (ECPGexecute(stmt)); } bool -ECPGtrans(int lineno, const char * transaction) +ECPGtrans(int lineno, const char *transaction) { PGresult *res; @@ -876,9 +886,9 @@ ECPGsetconn(int lineno, const char *connection_name) { struct connection *con = all_connections; - ECPGlog("ECPGsetconn: setting actual connection to %s\n", connection_name); - - for (; con && strcmp(connection_name, con->name) != 0; con=con->next); + ECPGlog("ECPGsetconn: setting actual connection to %s\n", connection_name); + + for (; con && strcmp(connection_name, con->name) != 0; con = con->next); if (con) { actual_connection = con; @@ -892,43 +902,43 @@ ECPGsetconn(int lineno, const char *connection_name) } bool -ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char * connection_name) +ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char *connection_name) { struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno); if (!this) return false; - + if (dbname == NULL && connection_name == NULL) connection_name = "DEFAULT"; - + /* add connection to our list */ if (connection_name != NULL) this->name = strdup(connection_name); else this->name = strdup(dbname); - + if (all_connections == NULL) this->next = NULL; else this->next = all_connections; actual_connection = all_connections = this; - - ECPGlog("ECPGconnect: opening database %s %s%s\n", dbname ? dbname : "NULL", user ? "for user ": "", user ? user : ""); + + ECPGlog("ECPGconnect: opening database %s %s%s\n", dbname ? dbname : "NULL", user ? "for user " : "", user ? user : ""); sqlca.sqlcode = 0; this->connection = PQsetdbLogin(NULL, NULL, NULL, NULL, dbname, user, passwd); - + if (PQstatus(this->connection) == CONNECTION_BAD) { ECPGfinish(this); - ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user ": "", user ? user : "", lineno); + ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user " : "", user ? user : "", lineno); register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "NULL"); return false; } - + return true; } @@ -936,7 +946,7 @@ bool ECPGdisconnect(int lineno, const char *connection_name) { struct connection *con; - + if (strcmp(connection_name, "CURRENT") == 0) ECPGfinish(actual_connection); else if (strcmp(connection_name, "ALL") == 0) @@ -944,26 +954,24 @@ ECPGdisconnect(int lineno, const char *connection_name) for (con = all_connections; con;) { struct connection *f = con; - + con = con->next; ECPGfinish(f); } } - else + else { - for (con = all_connections; con && strcmp(con->name, connection_name) != 0;con = con->next); + for (con = all_connections; con && strcmp(con->name, connection_name) != 0; con = con->next); if (con == NULL) - { + { ECPGlog("disconnect: not connected to connection %s\n", connection_name); register_error(ECPG_NO_CONN, "No such connection %s in line %d", connection_name, lineno); return false; } else - { ECPGfinish(con); - } } - + return true; } @@ -986,7 +994,7 @@ ECPGlog(const char *format,...) if (!f) return; - + sprintf(f, "[%d]: %s", getpid(), format); va_start(ap, format); |