InterBase/Firebird Decimal/Numeric type

admin

Administrator
Staff member
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.%0*ld", -scale, dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%ld.%0*ld", 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.%0*hd", -scale, (int)dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%hd.%0*hd", (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.%0*Ld", -scale, dtl);
+ } else {
+ val->value.str.len = sprintf(string_data, "%Ld.%0*Ld", 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
 
Back
Top