Skip to content
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

Merged
merged 25 commits into from
Jun 1, 2023

Conversation

beyondykk9
Copy link
Contributor

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.

@beyondykk9 beyondykk9 self-assigned this Feb 28, 2023
@beyondykk9 beyondykk9 marked this pull request as draft March 1, 2023 23:53
@beyondykk9 beyondykk9 changed the title [CBRD-24684] divide operation result into numeric type [CBRD-24684] divide operation result into double type May 10, 2023
@hgryoo hgryoo marked this pull request as ready for review May 15, 2023 07:24
@@ -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"
Copy link
Contributor

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"?

Copy link
Contributor Author

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.

@@ -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);
Copy link
Contributor

@youngjinj youngjinj May 16, 2023

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'
*/

Copy link
Contributor Author

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.

Copy link
Contributor

@youngjinj youngjinj May 17, 2023

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)

@shparkcubrid
Copy link
Contributor

shparkcubrid commented May 17, 2023

In Oracle, unnecessary '.0' is not printed. Please check test cases of test_medium.

SQL> select 4/2 from dual;

       4/2
----------
         2

@shparkcubrid
Copy link
Contributor

The test case below is not normal. Please check.
test_medium

evaluate 150000000000 / 6543;
** Difference between Expected(-) and Actual(+) results:
@@ -1,4 +1,4 @@
 ===================================================
     
-22925263     
+2.2925263640531868E7

@beyondykk9
Copy link
Contributor Author

In Oracle, unnecessary '.0' is not printed. Please check test cases of test_medium.

SQL> select 4/2 from dual;

       4/2
----------
         2

trailing zeros are suppressed in oracle style printing numeric.

Copy link
Contributor

@hyunikn hyunikn left a 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?

@beyondykk9
Copy link
Contributor Author

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.

@hgryoo
Copy link
Member

hgryoo commented May 22, 2023

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?

@hgryoo
Copy link
Member

hgryoo commented May 22, 2023

Floating error could be accumulated a lot like the following because of scale:

SELECT (5555 / 7) / (7.5 / 11) FROM dual;

Oracle

1163.904761904761904761904761904761904763

CUBRID

1163.904761904761594 -- SELECT (5555 / 7) / (7.5 / 11) FROM dual;
1163.9047619047619047619047619047619358 -- SELECT (cast(5555 as numeric(38,34)) / 7) / (cast(7.5 as numeric(38,34)) / 11) FROM dual;

@hgryoo
Copy link
Member

hgryoo commented May 22, 2023

Floating error could be accumulated a lot like the following because of scale:

SELECT (5555 / 7) / (7.5 / 11) FROM dual;

Oracle

1163.904761904761904761904761904761904763

CUBRID

1163.904761904761594 -- SELECT (5555 / 7) / (7.5 / 11) FROM dual;
1163.9047619047619047619047619047619358 -- SELECT (cast(5555 as numeric(38,34)) / 7) / (cast(7.5 as numeric(38,34)) / 11) FROM dual;

Maybe It could be fixed by #4375

Copy link
Member

@hgryoo hgryoo left a 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.

@shparkcubrid
Copy link
Contributor

shparkcubrid commented May 23, 2023

In Oracle, unnecessary '.0' is not printed. Please check test cases of test_medium.

SQL> select 4/2 from dual;

       4/2
----------
         2

trailing zeros are suppressed in oracle style printing numeric.

it's fail case of test_medium.

select country, rownum/10 as number
from public.location
where mod(rownum, 10) = 0 order by 1;
** Difference between Expected(-) and Actual(+) results:
@@ -1,6 +1,6 @@
 ===================================================
 country    number    
-Aruba     1     
-Bahamas     3     
-West Indies     2     
+Aruba     1.000000000     
+Bahamas     3.000000000     
+West Indies     2.000000000 

@beyondykk9 beyondykk9 changed the title [CBRD-24684] divide operation result into double type [CBRD-24684] divide operation result into numeric type Jun 1, 2023
@beyondykk9 beyondykk9 merged commit 63133ba into CUBRID:develop Jun 1, 2023
@beyondykk9 beyondykk9 deleted the CBRD-24684 branch June 1, 2023 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants