ibase_query() returns incorrect value about Decimal/Numeric type on
InterBase6/Firebird.
--- interbase.c.orig Fri Jun 15 11:32:31 2001
+++ interbase.c Tue Jun 12 18:09:07 2001
@@ -1741,7 +1741,22 @@
val->value.str.len = len;
break;
case SQL_LONG:
- if (scale) {
+ if (scale < 0) {
+ int j;
+ long dt, dth, dtl, pow_scale = 1;
+ for (j = 0; j < -scale; j++) pow_scale = 10;
+ dt = (long )data;
+ dth = dt / pow_scale;
+ dtl = dt % pow_scale;
+ if (dtl < 0) dtl = -1;
+ if ((dt < 0) && (dth == 0)) {
+ val->value.str.len = sprintf(string_data, "-0.%0ld", -scale, dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%ld.%0ld", dth, -scale, dtl);
+ }
+ val->type = IS_STRING;
+ val->value.str.val = estrdup(string_data);
+ /
int j, f = 1;
float n = (float) (long *)(data);
@@ -1750,18 +1765,36 @@
val->type = IS_STRING;
val->value.str.len = sprintf(string_data, "%.f", -scale, n / f);
val->value.str.val = estrdup(string_data);
+ /
} else {
val->type = IS_LONG;
val->value.lval = (long )(data);
}
break;
case SQL_SHORT:
- val->type = IS_LONG;
- val->value.lval = (short )(data);
+ if (scale < 0) {
+ int j;
+ short dt, dth, dtl, pow_scale = 1;
+ for (j = 0; j < -scale; j++) pow_scale = 10;
+ dt = (short )data;
+ dth = dt / pow_scale;
+ dtl = dt % pow_scale;
+ if (dtl < 0) dtl = -1;
+ if ((dt < 0) && (dth == 0)) {
+ val->value.str.len = sprintf(string_data, "-0.%0hd", -scale, (int)dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%hd.%0hd", (int)dth, -scale, (int)dtl);
+ }
+ val->type = IS_STRING;
+ val->value.str.val = estrdup(string_data);
+ } else {
+ val->type = IS_LONG;
+ val->value.lval = (short )(data);
+ }
break;
case SQL_FLOAT:
val->type = IS_DOUBLE;
- val->value.dval = (float )(data);
+ val->value.dval = (double) (float )(data);
break;
case SQL_DOUBLE:
if (scale) {
@@ -1778,11 +1811,31 @@
break;
#ifdef SQL_INT64
case SQL_INT64:
- val->type = IS_STRING;
+ if (scale) {
+ int j;
+ ISC_INT64 dt, dth, dtl, pow_scale = 1;
+ for (j = 0; j < -scale; j++) pow_scale = 10;
+ dt = (ISC_INT64 )data;
+ dth = (ISC_INT64) (dt / pow_scale);
+ dtl = (ISC_INT64) (dt % pow_scale);
+ if (dtl < 0) dtl = -1;
+ if ((dt < 0) && (dth == 0)) {
+ val->value.str.len = sprintf(string_data, "-0.%0Ld", -scale, dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%Ld.%0Ld", dth, -scale, dtl);
+ }
+ val->type = IS_STRING;
+ val->value.str.val = estrdup(string_data);
+ /
val->value.str.len = sprintf(string_data, "%Ld.%Ld",
(ISC_INT64) (((ISC_INT64 )data) / (int) pow(10.0, (double) -scale)),
(ISC_INT64) abs((int) (((ISC_INT64 )data) % (int) pow(10.0, (double) -scale))));
- val->value.str.val = estrdup(string_data);
+ /
+ } else {
+ val->type = IS_STRING;
+ val->value.str.len = sprintf(string_data, "%Ld", (ISC_INT64 )data);
+ val->value.str.val = estrdup(string_data);
+ }
break;
#endif
#ifndef SQL_TIMESTAMP