-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CBRD-24684] divide operation result into numeric type #4150
Conversation
@@ -728,6 +728,8 @@ static const char sysprm_ha_conf_file_name[] = "cubrid_ha.conf"; | |||
|
|||
#define PRM_NAME_STATDUMP_FORCE_ADD_INT_MAX "statdump_force_add_int_max" | |||
|
|||
#define PRM_NAME_ORACLE_STYLE_DIVIDE "oracle_style_divide" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the word "oracle"?
How about replacing it with words like "for math" or "for science", "for engineering"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of this parameter is compatibility with oracle.
src/parser/type_checking.c
Outdated
@@ -6089,6 +6089,8 @@ pt_apply_expressions_definition (PARSER_CONTEXT * parser, PT_NODE ** node) | |||
int matches = 0, best_match = -1, i = 0; | |||
EXPRESSION_SIGNATURE sig; | |||
|
|||
static bool oracle_style_divide = prm_get_bool_value (PRM_ID_ORACLE_STYLE_DIVIDE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of the changes in this PR, how about just changing below and setting 'oracle_style_number_return=y"?
diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c
index d27a1891b..791d76fc4 100644
--- a/src/parser/type_checking.c
+++ b/src/parser/type_checking.c
@@ -10580,7 +10580,11 @@ pt_common_type (PT_TYPE_ENUM arg1_type, PT_TYPE_ENUM arg2_type)
/* The common type between two ENUMs is string */
common_type = PT_TYPE_VARCHAR;
}
- else
+ else if (PT_IS_DISCRETE_NUMBER_TYPE (arg1_type) && PT_IS_DISCRETE_NUMBER_TYPE (arg1_type))
+ {
+ common_type = PT_TYPE_NUMERIC;
+ }
+ else
{
common_type = arg1_type;
}
csql> ;get oracle_style_number_return
/*
oracle_style_number_return=y
*/
create table t1 (s_c1 short, s_c2 short, i_c1 int, i_c2 int, b_c1 bigint, b_c2 bigint);
insert into t1 values (1, 2, 1, 2, 1, 2);
select s_c1/s_c2, i_c1/i_c2, b_c1/b_c2, 1/2, 1.0/2 from t1;
/*
s_c1/s_c2 i_c1/i_c2 b_c1/b_c2 1/2 1.0/2
==============================================================================================================
0.5 0.5 0.5 0.5 0.5
*/
select s_c1+s_c2, i_c1+i_c2, b_c1+b_c2, 1+2, 1.0+2 from t1;
/*
s_c1+s_c2 i_c1+i_c2 b_c1+b_c2 1+2 1.0+2
==============================================================================================================
3 3 3 3 3
*/
select s_c1-s_c2, i_c1-i_c2, b_c1-b_c2, 1-2, 1.0-2 from t1;
/*
s_c1-s_c2 i_c1-i_c2 b_c1-b_c2 1-2 1.0-2
==============================================================================================================
-1 -1 -1 -1 -1
*/
select s_c1*s_c2, i_c1*i_c2, b_c1*b_c2, 1*2, 1.0*2 from t1;
/*
s_c1*s_c2 i_c1*i_c2 b_c1*b_c2 1*2 1.0*2
==============================================================================================================
2 2 2 2 2
*/
select typeof(s_c1/s_c2), typeof(i_c1/i_c2), typeof(b_c1/b_c2), typeof(1/2), typeof(1.0/2), typeof(1) from t1;
/*
typeof(s_c1/s_c2) typeof(i_c1/i_c2) typeof(b_c1/b_c2) typeof(1/2) typeof(1.0/2) typeof(1)
====================================================================================================================================
'numeric (24, 9)' 'numeric (24, 9)' 'numeric (24, 9)' 'numeric (24, 9)' 'numeric (10, 9)' 'integer'
*/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NUMERIC type has precision and scale info which might not be defined at compile time.
SELECT count(*) / 3 FROM t1 query returns integer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not be changed in the pt_common_type function, it should be changed in the pt_common_type_op function so that the operator can be checked and changed.
diff --git a/src/parser/type_checking.c b/src/parser/type_checking.c
index d27a1891b..cf40e6816 100644
--- a/src/parser/type_checking.c
+++ b/src/parser/type_checking.c
@@ -11310,6 +11310,12 @@ pt_common_type_op (PT_TYPE_ENUM t1, PT_OP_TYPE op, PT_TYPE_ENUM t2)
switch (op)
{
+ case PT_DIVIDE:
+ if (PT_IS_DISCRETE_NUMBER_TYPE (t1) && PT_IS_DISCRETE_NUMBER_TYPE (t2))
+ {
+ result_type = PT_TYPE_NUMERIC;
+ }
+ break;
case PT_MINUS:
case PT_TIMES:
if (result_type == PT_TYPE_SEQUENCE)
In Oracle, unnecessary '.0' is not printed. Please check test cases of test_medium.
|
The test case below is not normal. Please check.
|
trailing zeros are suppressed in oracle style printing numeric. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the last comment of RND-1815, technical support team requested that the result type should be numeric rather than double. Was there a further discussion and decision on this point?
Finally, it would be NUMERIC type. |
As a result of this issue, is it okay if the result of DIVIDE is numeric? Or should the precision or the resulting value be exactly the same? |
Floating error could be accumulated a lot like the following because of scale:
Oracle
CUBRID
|
Maybe It could be fixed by #4375 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue was confirmed to be related to the format of that particular type rather than the actual value resulting from the division operation. Approved.
it's fail case of test_medium.
|
http://jira.cubrid.org/browse/CBRD-24684
It can see the difference in decimal point output between CUBRID and other DBMS (Tibero, Oracle).
In CUBRID, only integer values are displayed during calculation, and decimal points are output in other DBMS (Tibero, Oracle).
For this reason, we are experiencing great difficulties in migrating from other DBMS to CUBRID.
We need to modify the logic so that the result data type is numeric in case of numeric style division operation.