Fix ifnull/nvl expr result wrong precision

This commit is contained in:
hezuojiao
2023-04-27 02:14:22 +00:00
committed by ob-robot
parent f59bb29409
commit bc1c4b7599
6 changed files with 70 additions and 32 deletions

View File

@ -16,9 +16,9 @@
#include "share/ob_virtual_table_scanner_iterator.h" #include "share/ob_virtual_table_scanner_iterator.h"
namespace oceanbase namespace oceanbase
{ {
namespace common namespace common
{ {
class ObObj; class ObObj;
} }
@ -36,9 +36,9 @@ public:
inline void set_addr(common::ObAddr &addr) {addr_ = &addr;} inline void set_addr(common::ObAddr &addr) {addr_ = &addr;}
virtual int set_ip(common::ObAddr *addr); virtual int set_ip(common::ObAddr *addr);
private: private:
enum DISK_COLUMN enum DISK_COLUMN
{ {
SVR_IP = common::OB_APP_MIN_COLUMN_ID, SVR_IP = common::OB_APP_MIN_COLUMN_ID,
SVR_PORT, SVR_PORT,
TOTAL_SIZE, TOTAL_SIZE,
@ -53,9 +53,9 @@ private:
int32_t port_; int32_t port_;
bool is_end_; bool is_end_;
DISALLOW_COPY_AND_ASSIGN(ObInfoSchemaDiskStatTable); DISALLOW_COPY_AND_ASSIGN(ObInfoSchemaDiskStatTable);
}; };
} }
} }
#endif /* OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE */ #endif /* OCEANBASE_OBSERVER_VIRTUAL_TABLE_OB_DISK_STAT_TABLE */

View File

@ -80,9 +80,15 @@ int ObExprIfNull::calc_result_type2(ObExprResType &type,
} else { } else {
type.set_scale(-1); type.set_scale(-1);
} }
if (lib::is_mysql_mode() && ob_is_real_type(type.get_type()) && if (lib::is_mysql_mode() && SCALE_UNKNOWN_YET != type.get_scale()) {
SCALE_UNKNOWN_YET != type.get_scale()) { if (ob_is_real_type(type.get_type())) {
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type.get_scale()))); type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type.get_scale())));
} else if (ob_is_number_tc(type.get_type())) { // TODO:@zuojiao.hzj add decimal_int here
const int16_t intd1 = type1.get_precision() - type1.get_scale();
const int16_t intd2 = type2.get_precision() - type2.get_scale();
const int16_t prec = MAX(type.get_precision(), MAX(intd1, intd2) + type.get_scale());
type.set_precision(static_cast<ObPrecision>(prec));
}
} }
type.set_length(MAX(type1.get_length(), type2.get_length())); type.set_length(MAX(type1.get_length(), type2.get_length()));
type1.set_calc_meta(type.get_obj_meta()); type1.set_calc_meta(type.get_obj_meta());

View File

@ -112,6 +112,16 @@ int ObExprNvl::calc_result_type2(ObExprResType &type,
} else { } else {
type.set_scale(-1); type.set_scale(-1);
} }
if (lib::is_mysql_mode() && SCALE_UNKNOWN_YET != type.get_scale()) {
if (ob_is_real_type(type.get_type())) {
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type.get_scale())));
} else if (ob_is_number_tc(type.get_type())) { // TODO:@zuojiao.hzj add decimal_int here
const int16_t intd1 = type1.get_precision() - type1.get_scale();
const int16_t intd2 = type2.get_precision() - type2.get_scale();
const int16_t prec = MAX(type.get_precision(), MAX(intd1, intd2) + type.get_scale());
type.set_precision(static_cast<ObPrecision>(prec));
}
}
type.set_length(MAX(type1.get_length(), type2.get_length())); type.set_length(MAX(type1.get_length(), type2.get_length()));
//对于 int 和uint64的混合类型,需要提升类型至decimal //对于 int 和uint64的混合类型,需要提升类型至decimal
if (lib::is_mysql_mode() if (lib::is_mysql_mode()

View File

@ -87,7 +87,7 @@ INSERT INTO t2 VALUES (0.0), (9.0);
SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM; FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def CEMPNUM 246 6 4 Y 32768 2 63 def CEMPNUM 246 15 4 Y 32768 2 63
CEMPNUM CEMPNUM
0.00 0.00
2.00 2.00
@ -100,7 +100,7 @@ ifnull(0, 0.0)
insert into t3 values(0, 2.4, "123"); insert into t3 values(0, 2.4, "123");
select ifnull(a, b), ifnull(a, c) from t3; select ifnull(a, b), ifnull(a, c) from t3;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ifnull(a, b) 246 11 1 Y 32768 0 63 def ifnull(a, b) 246 12 1 Y 32768 0 63
def ifnull(a, c) 253 44 1 Y 0 0 45 def ifnull(a, c) 253 44 1 Y 0 0 45
ifnull(a, b) ifnull(a, c) ifnull(a, b) ifnull(a, c)
0 0 0 0

View File

@ -731,7 +731,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c1, DECIMAL(10, 0)), t1.c17)]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c1, DECIMAL(11, 0)), t1.c17)]), filter(nil), rowset=256
access([t1.c1], [t1.c17]), partitions(p0) access([t1.c1], [t1.c17]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -772,7 +772,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c1, DECIMAL(10, 0)), cast(t1.c18, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c1, DECIMAL(11, 0)), cast(t1.c18, DECIMAL(11, 0)))]), filter(nil), rowset=256
access([t1.c1], [t1.c18]), partitions(p0) access([t1.c1], [t1.c18]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -7947,7 +7947,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c9, DECIMAL(10, 0)), t1.c17)]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c9, DECIMAL(11, 0)), t1.c17)]), filter(nil), rowset=256
access([t1.c9], [t1.c17]), partitions(p0) access([t1.c9], [t1.c17]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -7988,7 +7988,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c9, DECIMAL(10, 0)), cast(t1.c18, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c9, DECIMAL(11, 0)), cast(t1.c18, DECIMAL(11, 0)))]), filter(nil), rowset=256
access([t1.c9], [t1.c18]), partitions(p0) access([t1.c9], [t1.c18]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -9751,7 +9751,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c11, DECIMAL(10, 0)), t1.c17)]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c11, DECIMAL(20, 0)), t1.c17)]), filter(nil), rowset=256
access([t1.c11], [t1.c17]), partitions(p0) access([t1.c11], [t1.c17]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -9792,7 +9792,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c11, DECIMAL(10, 0)), cast(t1.c18, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c11, DECIMAL(20, 0)), cast(t1.c18, DECIMAL(20, 0)))]), filter(nil), rowset=256
access([t1.c11], [t1.c18]), partitions(p0) access([t1.c11], [t1.c18]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -10653,7 +10653,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c12, DECIMAL(10, 0)), t1.c17)]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c12, DECIMAL(20, 0)), t1.c17)]), filter(nil), rowset=256
access([t1.c12], [t1.c17]), partitions(p0) access([t1.c12], [t1.c17]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -10694,7 +10694,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c12, DECIMAL(10, 0)), cast(t1.c18, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c12, DECIMAL(20, 0)), cast(t1.c18, DECIMAL(20, 0)))]), filter(nil), rowset=256
access([t1.c12], [t1.c18]), partitions(p0) access([t1.c12], [t1.c18]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -14507,7 +14507,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(t1.c17, cast(t1.c1, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(t1.c17, cast(t1.c1, DECIMAL(11, 0)))]), filter(nil), rowset=256
access([t1.c17], [t1.c1]), partitions(p0) access([t1.c17], [t1.c1]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -14835,7 +14835,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(t1.c17, cast(t1.c9, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(t1.c17, cast(t1.c9, DECIMAL(11, 0)))]), filter(nil), rowset=256
access([t1.c17], [t1.c9]), partitions(p0) access([t1.c17], [t1.c9]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -14917,7 +14917,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(t1.c17, cast(t1.c11, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(t1.c17, cast(t1.c11, DECIMAL(20, 0)))]), filter(nil), rowset=256
access([t1.c17], [t1.c11]), partitions(p0) access([t1.c17], [t1.c11]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -14958,7 +14958,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(t1.c17, cast(t1.c12, DECIMAL(10, 0)))]), filter(nil), rowset=256 0 - output([nvl(t1.c17, cast(t1.c12, DECIMAL(20, 0)))]), filter(nil), rowset=256
access([t1.c17], [t1.c12]), partitions(p0) access([t1.c17], [t1.c12]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15491,7 +15491,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(4, 0)), cast(t1.c3, DECIMAL(4, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c3, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c3]), partitions(p0) access([t1.c18], [t1.c3]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15532,7 +15532,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(3, 0)), cast(t1.c4, DECIMAL(3, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c4, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c4]), partitions(p0) access([t1.c18], [t1.c4]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15573,7 +15573,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(6, 0)), cast(t1.c5, DECIMAL(6, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c5, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c5]), partitions(p0) access([t1.c18], [t1.c5]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15614,7 +15614,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(5, 0)), cast(t1.c6, DECIMAL(5, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c6, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c6]), partitions(p0) access([t1.c18], [t1.c6]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15655,7 +15655,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(9, 0)), cast(t1.c7, DECIMAL(9, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c7, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c7]), partitions(p0) access([t1.c18], [t1.c7]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -15696,7 +15696,7 @@ Query Plan
=============================================== ===============================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([nvl(cast(t1.c18, DECIMAL(8, 0)), cast(t1.c8, DECIMAL(8, 0)))]), filter(nil), rowset=256 0 - output([nvl(cast(t1.c18, DECIMAL(10, 0)), cast(t1.c8, DECIMAL(10, 0)))]), filter(nil), rowset=256
access([t1.c18], [t1.c8]), partitions(p0) access([t1.c18], [t1.c8]), partitions(p0)
is_index_back=false, is_global_index=false, is_index_back=false, is_global_index=false,
range_key([t1.__pk_increment]), range(MIN ; MAX)always true range_key([t1.__pk_increment]), range(MIN ; MAX)always true
@ -19933,3 +19933,19 @@ select nvl(null,b) from t1;
| 2020-09-13 20:26:40.000 | | 2020-09-13 20:26:40.000 |
+-------------------------+ +-------------------------+
drop table t1; drop table t1;
#bug:
create table t1 as select nvl(cast(1 as decimal(10, 7)), cast(2 as decimal(12, 5))) as c from dual;
desc t1;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| c | decimal(14,7) | NO | | NULL | |
+-------+---------------+------+-----+---------+-------+
select * from t1;
+-----------+
| c |
+-----------+
| 1.0000000 |
+-----------+
drop table t1;

View File

@ -84,3 +84,9 @@ insert into t1 values(1, now());
insert into t1 values(2, now(6)); insert into t1 values(2, now(6));
select nvl(null,b) from t1; select nvl(null,b) from t1;
drop table t1; drop table t1;
--echo #bug:
create table t1 as select nvl(cast(1 as decimal(10, 7)), cast(2 as decimal(12, 5))) as c from dual;
desc t1;
select * from t1;
drop table t1;