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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list