Changeset: a1201f467b96 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a1201f467b96 Modified Files: sql/backends/monet5/sql.c sql/test/miscellaneous/Tests/simple_selects.sql sql/test/miscellaneous/Tests/simple_selects.stable.err Branch: Jun2020 Log Message:
Backported overflow check fix into Jun2020 diffs (156 lines): diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -3835,7 +3835,7 @@ str month_interval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { int *ret = getArgReference_int(stk, pci, 0); - int k = digits2ek(*getArgReference_int(stk, pci, 2)), r = 0; + int k = digits2ek(*getArgReference_int(stk, pci, 2)), r = 0, c; (void) cntxt; *ret = int_nil; @@ -3855,38 +3855,49 @@ month_interval(Client cntxt, MalBlkPtr m return MAL_SUCCEED; r = stk->stk[getArg(pci, 1)].val.ival; break; - case TYPE_lng: + case TYPE_lng: { + lng l; if (is_lng_nil(stk->stk[getArg(pci, 1)].val.lval)) return MAL_SUCCEED; - r = (int) stk->stk[getArg(pci, 1)].val.lval; - break; + l = stk->stk[getArg(pci, 1)].val.lval; + if (l > GDK_int_max) + throw(ILLARG, "calc.month_interval", SQLSTATE(22003) "Value " LLFMT " too large to fit at a month_interval", l); + r = (int) l; + } break; #ifdef HAVE_HGE - case TYPE_hge: + case TYPE_hge: { + hge h; if (is_hge_nil(stk->stk[getArg(pci, 1)].val.hval)) return MAL_SUCCEED; - r = (int) stk->stk[getArg(pci, 1)].val.hval; - break; + h = stk->stk[getArg(pci, 1)].val.hval; + if (h > GDK_int_max) + throw(ILLARG, "calc.month_interval", SQLSTATE(22003) "Value too large to fit at a month_interval"); + r = (int) h; + } break; #endif default: throw(ILLARG, "calc.month_interval", SQLSTATE(42000) "Illegal argument"); } + c = r; switch (k) { case iyear: - r *= 12; + c *= 12; break; case imonth: break; default: throw(ILLARG, "calc.month_interval", SQLSTATE(42000) "Illegal argument"); } - *ret = r; + if (c < r) + throw(ILLARG, "calc.month_interval", SQLSTATE(22003) "Overflow in convertion of %d to month_interval", r); + *ret = c; return MAL_SUCCEED; } str second_interval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { - lng *ret = getArgReference_lng(stk, pci, 0), r; + lng *ret = getArgReference_lng(stk, pci, 0), r, c; int k = digits2ek(*getArgReference_int(stk, pci, 2)), scale = 0; (void) cntxt; @@ -3915,38 +3926,45 @@ second_interval(Client cntxt, MalBlkPtr r = stk->stk[getArg(pci, 1)].val.lval; break; #ifdef HAVE_HGE - case TYPE_hge: + case TYPE_hge: { + hge h; if (is_hge_nil(stk->stk[getArg(pci, 1)].val.hval)) return MAL_SUCCEED; - r = (lng) stk->stk[getArg(pci, 1)].val.hval; - break; + h = stk->stk[getArg(pci, 1)].val.hval; + if (h > GDK_lng_max) + throw(ILLARG, "calc.sec_interval", SQLSTATE(22003) "Value too large to fit at a sec_interval"); + r = (lng) h; + } break; #endif default: throw(ILLARG, "calc.sec_interval", SQLSTATE(42000) "Illegal argument in second interval"); } + c = r; switch (k) { case iday: - r *= 24; + c *= 24; /* fall through */ case ihour: - r *= 60; + c *= 60; /* fall through */ case imin: - r *= 60; + c *= 60; /* fall through */ case isec: - r *= 1000; + c *= 1000; break; default: throw(ILLARG, "calc.sec_interval", SQLSTATE(42000) "Illegal argument in second interval"); } if (scale) { #ifndef TRUNCATE_NUMBERS - r += 5*scales[scale-1]; + c += 5*scales[scale-1]; #endif - r /= scales[scale]; - } - *ret = r; + c /= scales[scale]; + } + if (c < r) + throw(ILLARG, "calc.sec_interval", SQLSTATE(22003) "Overflow in convertion of " LLFMT " to sec_interval", r); + *ret = c; return MAL_SUCCEED; } diff --git a/sql/test/miscellaneous/Tests/simple_selects.sql b/sql/test/miscellaneous/Tests/simple_selects.sql --- a/sql/test/miscellaneous/Tests/simple_selects.sql +++ b/sql/test/miscellaneous/Tests/simple_selects.sql @@ -163,3 +163,6 @@ select 'a' like 'a' escape 'a'; --error, select cast(x as interval second) from (values ('1'), (NULL), ('100'), (NULL)) as x(x); select cast(x as interval month) from (values ('1'), (NULL), ('100'), (NULL)) as x(x); + +select cast(9223372036854775808 as interval month); --error value to large for a month interval +select cast(92233720368547750 as interval second); --error, overflow in conversion for interval second diff --git a/sql/test/miscellaneous/Tests/simple_selects.stable.err b/sql/test/miscellaneous/Tests/simple_selects.stable.err --- a/sql/test/miscellaneous/Tests/simple_selects.stable.err +++ b/sql/test/miscellaneous/Tests/simple_selects.stable.err @@ -193,6 +193,14 @@ MAPI = (monetdb) /var/tmp/mtest-400226/ QUERY = select 'a' like 'a' escape 'a'; --error, like sequence ending with escape character ERROR = !Illegal argument: (I)LIKE pattern must not end with escape character CODE = 22019 +MAPI = (monetdb) /var/tmp/mtest-107867/.s.monetdb.37815 +QUERY = select cast(9223372036854775808 as interval month); --error value to large for a month interval +ERROR = !Value too large to fit at a month_interval +CODE = 22003 +MAPI = (monetdb) /var/tmp/mtest-107867/.s.monetdb.37815 +QUERY = select cast(92233720368547750 as interval second); --error, overflow in conversion for interval second +ERROR = !Overflow in convertion of 92233720368547750 to sec_interval +CODE = 22003 # 17:31:38 > # 17:31:38 > "Done." _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list