Changeset: d54e331f8b06 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d54e331f8b06 Modified Files: sql/server/rel_select.c sql/test/SQLancer/Tests/sqlancer08.test Branch: Aug2024 Log Message:
Optimize precision and scale when casting to decimal. diffs (71 lines): diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c --- a/sql/server/rel_select.c +++ b/sql/server/rel_select.c @@ -4043,6 +4043,8 @@ rel_case_exp(sql_query *query, sql_rel * } } +#define E_ATOM_STRING(e) ((atom*)(e)->l)->data.val.sval + static sql_exp * rel_cast(sql_query *query, sql_rel **rel, symbol *se, int f) { @@ -4055,6 +4057,7 @@ rel_cast(sql_query *query, sql_rel **rel if (!e) return NULL; + /* strings may need to be truncated */ if (EC_VARCHAR(tpe->type->eclass) && tpe->digits > 0) { sql_subtype *et = exp_subtype(e); @@ -4065,10 +4068,34 @@ rel_cast(sql_query *query, sql_rel **rel e = exp_binop(sql->sa, e, exp_atom_int(sql->sa, tpe->digits), c); } } + + if (e->type == e_atom && tpe->type->eclass == EC_DEC) { + sql_subtype *et = exp_subtype(e); + if (et->type->eclass == EC_CHAR || et->type->eclass == EC_DEC) + tpe = sql_bind_subtype(sql->sa, "decimal", et->digits, et->scale); + else if (et->type->eclass == EC_STRING) { + char *s = E_ATOM_STRING(e); + unsigned int min_precision = 0, min_scale = 0; + bool dot_seen = false; + for (size_t i = 0; i < strlen(s); i++) { + if (isdigit(s[i])) { + min_precision++; + if (dot_seen) + min_scale++; + } else if (s[i] == '.') { + dot_seen = true; + } + } + tpe = sql_bind_subtype(sql->sa, "decimal", min_precision, min_scale); + } + } + if (e) e = exp_check_type(sql, tpe, rel ? *rel : NULL, e, type_cast); + if (e && e->type == e_convert) exp_label(sql->sa, e, ++sql->label); + return e; } diff --git a/sql/test/SQLancer/Tests/sqlancer08.test b/sql/test/SQLancer/Tests/sqlancer08.test --- a/sql/test/SQLancer/Tests/sqlancer08.test +++ b/sql/test/SQLancer/Tests/sqlancer08.test @@ -170,10 +170,10 @@ 0 statement ok ROLLBACK -statement error 42000!Decimal (0.2.3) doesn't have format (10.2) +statement error 42000!Decimal (0.2.3) doesn't have format (3.2) select cast('0.2.3' as decimal(10,2)) -statement error 42000!Decimal (+0..2) doesn't have format (10.2) +statement error 42000!Decimal (+0..2) doesn't have format (2.1) select cast('+0..2' as decimal(10,2)) statement ok _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org