diff options
Diffstat (limited to 'src/interfaces/ecpg/lib/ecpglib.c')
-rw-r--r-- | src/interfaces/ecpg/lib/ecpglib.c | 143 |
1 files changed, 117 insertions, 26 deletions
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 87b2350bdb0..815f4bff0bc 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -96,10 +96,11 @@ ECPGdo(int lineno, char *query,...) */ while (type != ECPGt_EOIT) { - void *value = NULL; - long varcharsize; - long size; - long arrsize; + void *value = NULL, *ind_value; + long varcharsize, ind_varcharsize; + long size, ind_size; + long arrsize, ind_arrsize; + enum ECPGttype ind_type; char *newcopy; char *mallocedval = NULL; @@ -117,10 +118,41 @@ ECPGdo(int lineno, char *query,...) varcharsize = va_arg(ap, long); size = va_arg(ap, long); arrsize = va_arg(ap, long); - - switch (type) + ind_type = va_arg(ap, enum ECPGttype); + ind_value = va_arg(ap, void *); + ind_varcharsize = va_arg(ap, long); + ind_size = va_arg(ap, long); + ind_arrsize = va_arg(ap, long); + + buff[0] = '\0'; + + /* check for null value and set input buffer accordingly */ + switch (ind_type) { case ECPGt_short: + case ECPGt_unsigned_short: + if (*(short *) ind_value < 0) + strcpy(buff, "null"); + break; + case ECPGt_int: + case ECPGt_unsigned_int: + if (*(int *) ind_value < 0) + strcpy(buff, "null"); + break; + case ECPGt_long: + case ECPGt_unsigned_long: + if (*(long *) ind_value < 0L) + strcpy(buff, "null"); + break; + default: + break; + } + + if (*buff == '\0') + { + switch (type) + { + case ECPGt_short: case ECPGt_int: sprintf(buff, "%d", *(int *) value); tobeinserted = buff; @@ -205,7 +237,10 @@ ECPGdo(int lineno, char *query,...) ECPGtype_name(type), lineno); return false; break; + } } + else + tobeinserted = buff; /* * Now tobeinserted points to an area that is to be inserted at @@ -266,7 +301,7 @@ ECPGdo(int lineno, char *query,...) if (committed) { - if ((results = PQexec(simple_connection, "begin")) == NULL) + if ((results = PQexec(simple_connection, "begin transaction")) == NULL) { register_error(-1, "Error starting transaction line %d.", lineno); return false; @@ -324,10 +359,11 @@ ECPGdo(int lineno, char *query,...) for (x = 0; x < m && status; x++) { - void *value = NULL; - long varcharsize; - long size; - long arrsize; + void *value = NULL, *ind_value; + long varcharsize, ind_varcharsize; + long size, ind_size; + long arrsize, ind_arrsize; + enum ECPGttype ind_type; char *pval = PQgetvalue(results, 0, x); @@ -339,14 +375,38 @@ ECPGdo(int lineno, char *query,...) ECPGlog("ECPGdo line %d: RESULT: %s\n", lineno, pval ? pval : ""); - /* No the pval is a pointer to the value. */ + /* Now the pval is a pointer to the value. */ /* We will have to decode the value */ type = va_arg(ap, enum ECPGttype); value = va_arg(ap, void *); varcharsize = va_arg(ap, long); size = va_arg(ap, long); arrsize = va_arg(ap, long); - + ind_type = va_arg(ap, enum ECPGttype); + ind_value = va_arg(ap, void *); + ind_varcharsize = va_arg(ap, long); + ind_size = va_arg(ap, long); + ind_arrsize = va_arg(ap, long); + + /* check for null value and set indicator accordingly */ + switch (ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + *(short *) ind_value = -PQgetisnull(results, 0, x); + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *(int *) ind_value = -PQgetisnull(results, 0, x); + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *(long *) ind_value = -PQgetisnull(results, 0, x); + break; + default: + break; + } + switch (type) { long res; @@ -486,7 +546,30 @@ ECPGdo(int lineno, char *query,...) ((char *) value)[strlen(pval)] = '\0'; } else + { strncpy((char *) value, pval, varcharsize); + if (varcharsize < strlen(pval)) + { + /* truncation */ + switch (ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + *(short *) ind_value = varcharsize; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *(int *) ind_value = varcharsize; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *(long *) ind_value = varcharsize; + break; + default: + break; + } + } + } } break; @@ -498,7 +581,28 @@ ECPGdo(int lineno, char *query,...) strncpy(var->arr, pval, varcharsize); var->len = strlen(pval); if (var->len > varcharsize) + { + /* truncation */ + switch (ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + *(short *) ind_value = varcharsize; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *(int *) ind_value = varcharsize; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *(long *) ind_value = varcharsize; + break; + default: + break; + } + var->len = varcharsize; + } } break; @@ -587,19 +691,6 @@ ECPGtrans(int lineno, const char * transaction) return (TRUE); } -/* include these for compatibility */ -bool -ECPGcommit(int lineno) -{ - return(ECPGtrans(lineno, "end")); -} - -bool -ECPGrollback(int lineno) -{ - return(ECPGtrans(lineno, "abort")); -} - bool ECPGsetdb(PGconn *newcon) { |