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

bug: insert bigint data close to the boundary range, the result set is wrong #1332

Closed
2 of 3 tasks
davidshiz opened this issue Feb 27, 2023 · 9 comments · Fixed by #1393
Closed
2 of 3 tasks

bug: insert bigint data close to the boundary range, the result set is wrong #1332

davidshiz opened this issue Feb 27, 2023 · 9 comments · Fixed by #1393
Assignees
Labels
A-bug Something isn't working prio: high High priority

Comments

@davidshiz
Copy link
Collaborator

davidshiz commented Feb 27, 2023

Have you read the Contributing Guidelines on issues?

Please confirm if bug report does NOT exists already ?

  • I confirm there is no existing issue for this

Describe the problem

mysql> CREATE TABLE int8_tbl(q1 int8, q2 int8);
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO int8_tbl VALUES('4567890123456789','123');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO int8_tbl VALUES ('9223372036854775807','9223372036854775806');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO int8_tbl VALUES ('-9223372036854775805','-9223372036854775806');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM int8_tbl;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
|     4567890123456789 |                  123 |
|  9223372036854775807 |  9223372036854775806 |
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM int8_tbl WHERE q2 < 4567890123456789;
Empty set (0.00 sec)

Expected behavior

mysql> SELECT * FROM int8_tbl WHERE q2 < 4567890123456789;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
|     4567890123456789 |                  123 |
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
2 rows in set (0.00 sec)

How To Reproduce

CREATE TABLE int8_tbl(q1 int8, q2 int8);
INSERT INTO int8_tbl VALUES('4567890123456789','123');
INSERT INTO int8_tbl VALUES ('9223372036854775807','9223372036854775806');
INSERT INTO int8_tbl VALUES ('-9223372036854775805','-9223372036854775806');
SELECT * FROM int8_tbl WHERE q2 < 4567890123456789;

Environment

root@ub01:~# /stonedb57/install/bin/mysqld --version
/stonedb57/install/bin/mysqld  Ver 5.7.36-StoneDB-v1.0.2 for Linux on x86_64 (build-)
build information as follow:
        Repository address: https://github.com/stoneatom/stonedb.git:stonedb-5.7-dev
        Branch name: stonedb-5.7-dev
        Last commit ID: 0f4250589
        Last commit time: Date:   Tue Feb 21 06:09:37 2023 +0000
        Build time: Date: Wed Feb 22 17:50:51 CST 2023

Are you interested in submitting a PR to solve the problem?

  • Yes, I will!
@davidshiz davidshiz added the A-bug Something isn't working label Feb 27, 2023
@RingsC
Copy link
Contributor

RingsC commented Feb 27, 2023

@davidshiz, pls, give out the resul of select * from int8_tbl . Thanks.

@davidshiz
Copy link
Collaborator Author

@davidshiz, pls, give out the resul of select * from int8_tbl . Thanks.

ok, It has been updated, view the above content

@wisehead wisehead added this to the stonedb_5.7_v1.0.3 milestone Mar 1, 2023
@hustjieke
Copy link
Collaborator

It seems like the similar problem with #1344

@hustjieke hustjieke moved this to In Progress in StoneDB for MySQL 5.7 Mar 2, 2023
@hustjieke
Copy link
Collaborator

Simplify the sql:

mysql> create table t(a int8);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t values(1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t where a < 3;
+------+
| a    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

mysql> insert into t values(-9223372036854775806);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t where a < 3;
+----------------------+
| a                    |
+----------------------+
|                    1 |
| -9223372036854775806 |
+----------------------+
2 rows in set (0.00 sec)

mysql> insert into t values(9223372036854775806);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t where a < 3;
Empty set (0.00 sec)

@hustjieke hustjieke added the prio: high High priority label Mar 8, 2023
@hustjieke
Copy link
Collaborator

error msg should be [-9223372036854775806, 9223372036854775807]:
image

@davidshiz
Copy link
Collaborator Author

same question

mysql> select * from int8_tbl;
+---------------------+---------------------+
| q1                  | q2                  |
+---------------------+---------------------+
| 9223372036854775807 | 9223372036854775806 |
|                NULL |                NULL |
|                 123 |                 456 |
|                 123 |    4567890123456789 |
|    4567890123456789 |                 123 |
|    4567890123456789 |    4567890123456789 |
|    4567890123456789 |   -4567890123456789 |
+---------------------+---------------------+
7 rows in set (0.00 sec)

mysql> SELECT * FROM int8_tbl WHERE q2 >= 4567890123456789;
Empty set (0.00 sec)

@El-even-11
Copy link
Contributor

El-even-11 commented Mar 9, 2023

another similar problem

mysql> select * from int8_tbl;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
1 row in set (0.00 sec)

mysql> select * from int8_tbl where q2 = -9223372036854775807;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
1 row in set (0.00 sec)

@hustjieke
Copy link
Collaborator

another similar question

mysql> select * from int8_tbl;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
1 row in set (0.00 sec)

mysql> select * from int8_tbl where q2 = -9223372036854775807;
+----------------------+----------------------+
| q1                   | q2                   |
+----------------------+----------------------+
| -9223372036854775805 | -9223372036854775806 |
+----------------------+----------------------+
1 row in set (0.00 sec)

Yes, I'm working on this bug now. It seems like sth. wrong happened when do optimizer.

@hustjieke
Copy link
Collaborator

root cause:
In function TianmuAttr::EvaluatePack_BetweenInt():

  int64_t pv1 = d.val1.vc->GetValueInt64(mit); // left value
  int64_t pv2 = d.val2.vc->GetValueInt64(mit); // right value
  int64_t local_min = dpn.min_i;
  int64_t local_max = dpn.max_i;
  if (pv1 != common::MINUS_INF_64) 
    pv1 = pv1 - local_min;-----> error happened here, if local_min = -9223372036854775806, the result of  pv1 may be out of boundary and get wrong value, we should use uint64 to store pv1
  else  local_min-local_min = 0
    pv1 = 0;

  if (pv2 != common::PLUS_INF_64)  // encode from 0-level to 2-level
    pv2 = pv2 - local_min; -----> The same reason as pv1
  else
    pv2 = local_max - local_min; 

and then when do row filter, int64_t v = p->GetValInt(mit.GetCurInpack(dim)); should be changed to uint64_t, as we use format uint64_t to store data into pack:

      if (d.op == common::Operator::O_BETWEEN && !mit.NullsPossibleInPack(dim) && dpn.numOfNulls == 0) {
        // easy and fast case - no "if"s
        do {
          int64_t v = p->GetValInt(mit.GetCurInpack(dim));
          if (pv1 > v || v > pv2) 
            mit.ResetCurrent(); 
          ++mit; 
        } while (mit.IsValid() && !mit.PackrowStarted());

hustjieke added a commit to hustjieke/stonedb-8.0.30-upgrade that referenced this issue Mar 15, 2023
…in or not in stoneatom#1332

[summary]
In tianmu, pack_int uses uint64_t to store level 2 encode, ranges from [0, uint64_max], so
when filter data, the conditions(in code named "pv1, pv2") should be also changed to level 2 encode.
e.g.: stored value = actually value - min
uint64 upv1 = pv1 - local_min;
uint64 upv2 = local_max - local_min;
the fixes mainly in funciont "EvaluatePack_BetweenInt".

For not int (value): when value < local_min, it should be a special case.
Only used when rough check = RS_ALL(no numeric data matchs), but table has null, rough check will be reset RS_SOME.
hustjieke added a commit to hustjieke/stonedb-8.0.30-upgrade that referenced this issue Mar 17, 2023
@mergify mergify bot closed this as completed in #1393 Mar 17, 2023
mergify bot pushed a commit that referenced this issue Mar 17, 2023
…in or not in #1332

[summary]
In tianmu, pack_int uses uint64_t to store level 2 encode, ranges from [0, uint64_max], so
when filter data, the conditions(in code named "pv1, pv2") should be also changed to level 2 encode.
e.g.: stored value = actually value - min
uint64 upv1 = pv1 - local_min;
uint64 upv2 = local_max - local_min;
the fixes mainly in funciont "EvaluatePack_BetweenInt".

For not int (value): when value < local_min, it should be a special case.
Only used when rough check = RS_ALL(no numeric data matchs), but table has null, rough check will be reset RS_SOME.
mergify bot pushed a commit that referenced this issue Mar 17, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in StoneDB for MySQL 5.7 Mar 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-bug Something isn't working prio: high High priority
Projects
5 participants