Changeset: 412cc3428d91 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=412cc3428d91
Added Files:
sql/backends/monet5/sql_cast_impl_int.h
sql/test/BugTracker-2017/Tests/round-or-truncate.Bug-6193.sql
sql/test/BugTracker-2017/Tests/round-or-truncate.Bug-6193.stable.err
sql/test/BugTracker-2017/Tests/round-or-truncate.Bug-6193.stable.out
Removed Files:
sql/backends/monet5/sql_cast_impl_down_from_int.h
sql/backends/monet5/sql_cast_impl_up_to_int.h
Modified Files:
gdk/gdk_calc.c
sql/backends/monet5/Makefile.ag
sql/backends/monet5/sql_cast.c
sql/backends/monet5/sql_cast_impl_down_from_flt.h
sql/backends/monet5/sql_cast_impl_up_to_flt.h
sql/server/sql_atom.c
sql/test/ADT2006/Tests/bram.stable.out
sql/test/BugTracker-2015/Tests/cast_to_num.Bug-3744.stable.out
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out
sql/test/BugTracker-2016/Tests/convert-function-test.Bug-3460.stable.out.int128
sql/test/BugTracker-2017/Tests/All
sql/test/VOC/Tests/VOC.stable.out
sql/test/mergetables/Tests/forex.stable.out
sql/test/mergetables/Tests/forex.stable.out.int128
sql/test/pg_regress/Tests/numeric.sql
sql/test/pg_regress/Tests/numeric.stable.err
sql/test/pg_regress/Tests/numeric.stable.out
sql/test/pg_regress/Tests/numerology.stable.out
Branch: Dec2016
Log Message:
Be consistent about rounding or truncating values.
There is now a symbol TRUNCATE_NUMBERS that, if defined, which it
currently is not, will cause the code to always truncate towards zero
when values need to be converted from higher precision (number of
decimals after the decimal point) to lower precision, including from
floating point to integer. Without the symbol, we always round.
This checkin also fixes some rounding bugs (don't add 0.5 to a
negative number and then truncate toward zero).
This fixes bug 6193.
Also added test.
diffs (truncated from 15197 to 300 lines):
diff --git a/gdk/gdk_calc.c b/gdk/gdk_calc.c
--- a/gdk/gdk_calc.c
+++ b/gdk/gdk_calc.c
@@ -13447,6 +13447,13 @@ convert_##TYPE1##_##TYPE2(const TYPE1 *s
/* Special version of the above for converting from floating point.
* The final assignment rounds the value which can still come out to
* the NIL representation, so we need to check for that. */
+#ifdef TRUNCATE_NUMBERS
+#define roundflt(x) (x)
+#define rounddbl(x) (x)
+#else
+#define roundflt(x) roundf(x)
+#define rounddbl(x) round(x)
+#endif
#define convertimpl_reduce_float(TYPE1, TYPE2) \
static BUN \
convert_##TYPE1##_##TYPE2(const TYPE1 *src, TYPE2 *restrict dst, BUN cnt, \
@@ -13468,7 +13475,7 @@ convert_##TYPE1##_##TYPE2(const TYPE1 *s
CONV_OVERFLOW(TYPE1, #TYPE2, src[i]); \
dst[i] = TYPE2##_nil; \
nils++; \
- } else if ((dst[i] = (TYPE2) src[i]) == TYPE2##_nil && \
+ } else if ((dst[i] = (TYPE2) round##TYPE1(src[i])) ==
TYPE2##_nil && \
abort_on_error) \
CONV_OVERFLOW(TYPE1, #TYPE2, src[i]); \
} \
@@ -13575,6 +13582,9 @@ convertimpl_reduce_float(dbl, lng)
#ifdef HAVE_HGE
convertimpl_reduce_float(dbl, hge)
#endif
+#undef rounddbl
+/* no rounding here */
+#define rounddbl(x) (x)
convertimpl_reduce_float(dbl, flt)
convertimpl_copy(dbl)
diff --git a/sql/backends/monet5/Makefile.ag b/sql/backends/monet5/Makefile.ag
--- a/sql/backends/monet5/Makefile.ag
+++ b/sql/backends/monet5/Makefile.ag
@@ -38,9 +38,8 @@ lib__sql = {
sql_result.c sql_result.h \
sql_cast.c sql_cast.h \
sql_cast_impl_down_from_flt.h \
- sql_cast_impl_down_from_int.h \
+ sql_cast_impl_int.h \
sql_cast_impl_up_to_flt.h \
- sql_cast_impl_up_to_int.h \
sql_round.c sql_round_impl.h sql_bat2time.c \
sql_fround.c sql_fround_impl.h \
sql_orderidx.c sql_orderidx.h \
diff --git a/sql/backends/monet5/sql_cast.c b/sql/backends/monet5/sql_cast.c
--- a/sql/backends/monet5/sql_cast.c
+++ b/sql/backends/monet5/sql_cast.c
@@ -466,96 +466,96 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
return msg;
}
-/* sql_cast_impl_up_to_int */
+/* up casting */
#define TP1 bte
#define TP2 bte
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 bte
#define TP2 sht
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 sht
#define TP2 sht
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 bte
#define TP2 int
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 sht
#define TP2 int
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 int
#define TP2 int
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 bte
#define TP2 lng
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 sht
#define TP2 lng
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 int
#define TP2 lng
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 lng
#define TP2 lng
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#ifdef HAVE_HGE
#define TP1 bte
#define TP2 hge
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 sht
#define TP2 hge
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 int
#define TP2 hge
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 lng
#define TP2 hge
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 hge
#define TP2 hge
-#include "sql_cast_impl_up_to_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#endif
@@ -692,64 +692,66 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
#undef TP1
#endif
-/* sql_cast_impl_down_from_int */
+/* down casting */
+
+#define DOWNCAST
#define TP1 sht
#define TP2 bte
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 int
#define TP2 bte
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 lng
#define TP2 bte
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#ifdef HAVE_HGE
#define TP1 hge
#define TP2 bte
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#endif
#define TP1 int
#define TP2 sht
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#define TP1 lng
#define TP2 sht
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#ifdef HAVE_HGE
#define TP1 hge
#define TP2 sht
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#endif
#define TP1 lng
#define TP2 int
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#ifdef HAVE_HGE
#define TP1 hge
#define TP2 int
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#endif
@@ -757,7 +759,7 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
#ifdef HAVE_HGE
#define TP1 hge
#define TP2 lng
-#include "sql_cast_impl_down_from_int.h"
+#include "sql_cast_impl_int.h"
#undef TP2
#undef TP1
#endif
diff --git a/sql/backends/monet5/sql_cast_impl_down_from_flt.h
b/sql/backends/monet5/sql_cast_impl_down_from_flt.h
--- a/sql/backends/monet5/sql_cast_impl_down_from_flt.h
+++ b/sql/backends/monet5/sql_cast_impl_down_from_flt.h
@@ -28,37 +28,45 @@
#define FUN(a,b,c,d) CONCAT_4(a,b,c,d)
-/* when casting a floating point to an decimal we like to preserve the
+/* when casting a floating point to a decimal we like to preserve the
* precision. This means we first scale the float before converting.
*/
str
-FUN(,TP1,_num2dec_,TP2) (TP2 *res, const TP1 *v, const int *d2, const int *s2)
+FUN(,TP1,_num2dec_,TP2)(TP2 *res, const TP1 *v, const int *d2, const int *s2)
{
- int p = *d2, inlen = 1, scale = *s2;
- TP1 r;
- lng cpyval;
+ TP1 val = *v;
+ int scale = *s2;
+ int precision = *d2;
+ int inlen;
- /* shortcut nil */
- if (*v == NIL(TP1)) {
+ if (val == NIL(TP1)) {
*res = NIL(TP2);
- return (MAL_SUCCEED);
+ return MAL_SUCCEED;
}
- /* since the TP2 type is bigger than or equal to the TP1 type, it will
- always fit */
- r = (TP1) *v;
- if (scale)
- r *= scales[scale];
- cpyval = (lng) r;
+ if (val <= -1) {
+ /* (-Inf, -1] */
+ inlen = (int) floor(log10(-val)) + 1;
+ } else if (val < 1) {
+ /* (-1, 1) */
+ inlen = 1;
+ } else {
+ /* [1, Inf) */
+ inlen = (int) floor(log10(val)) + 1;
+ }
+ if (inlen + scale > precision)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list