[MCOL-47] Statement returns NULL Created: 2016-05-06 Updated: 2016-05-31 Resolved: 2016-05-31 |
|
| Status: | Closed |
| Project: | MariaDB ColumnStore |
| Component/s: | ExeMgr |
| Affects Version/s: | None |
| Fix Version/s: | 1.0.0 |
| Type: | Bug | Priority: | Major |
| Reporter: | David Hall (Inactive) | Assignee: | Daniel Lee (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Sprint: | MCOL Sprint 2 - Priority 2 |
| Description |
|
Ref: working_tpch1_compareLogOnly/tableMode There are to scripts in this directory, the first runs the queries int tableMode = 0 – without vtables and the second runs them with tableMode = 2 – for vtables. When tableMode 2 is used, it detects that ColumnStore doesn't support the syntax and automatically switches to tableMode 0 and issues a warning to that effect. In both cases this query returns NULL, though it should return a number MariaDB [tpch1]> SELECT SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT)) AS REVENUE FROM LINEITEM, PART WHERE ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#41' AND P_CONTAINER IN ( 'SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') AND L_QUANTITY >= 3 AND L_QUANTITY <= 3 + 1 AND P_SIZE BETWEEN 1 AND 5 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#33' AND P_CONTAINER IN ( 'MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') AND L_QUANTITY >= 14 AND L_QUANTITY <= 14 + 1 AND P_SIZE BETWEEN 1 AND 10 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#45' AND P_CONTAINER IN ( 'LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') AND L_QUANTITY >= 25 AND L_QUANTITY <= 25 + 1 AND P_SIZE BETWEEN 1 AND 15 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' );
---------
--------- MariaDB [tpch1]> The proper answer is:
-------------
------------- mysql> It also seems to take less time than mysql 5.1 which may reflect the bad processing. When vtable mode is 1, we get the following error. This is not new behaviour. I think it is incorrect. It should issue an error about incompatibility or syntax error or something, rather than the ubiquitous error given. mysql> SELECT SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT)) AS REVENUE FROM LINEITEM, PART WHERE ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#41' AND P_CONTAINER IN ( 'SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') AND L_QUANTITY >= 3 AND L_QUANTITY <= 3 + 1 AND P_SIZE BETWEEN 1 AND 5 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#33' AND P_CONTAINER IN ( 'MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') AND L_QUANTITY >= 14 AND L_QUANTITY <= 14 + 1 AND P_SIZE BETWEEN 1 AND 10 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#45' AND P_CONTAINER IN ( 'LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') AND L_QUANTITY >= 25 AND L_QUANTITY <= 25 + 1 AND P_SIZE BETWEEN 1 AND 15 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ); |
| Comments |
| Comment by David Hall (Inactive) [ 2016-05-09 ] | ||||||
|
The problem is not in the join, as I first suspected, but rather in the IN. The following query returns 0 when run in table mode (infinidb_vtable_mode=0):
In vtable mode (infinidb_vtable_mode=2), the answer is correct: 19906 So use this query rather than the complicated one to chase the error. When the IN is reduced to one item in the list, it works:
| ||||||
| Comment by David Hall (Inactive) [ 2016-05-12 ] | ||||||
|
The issue is that String::copy() doesn't put the NULL terminator on the copied string. I know this sounds wierd, but bear with me. When the strings of the IN are processed, they're placed into an in_string object, defined in item_cmpfunc. This class maintains it's own buffer, but the objects in the buffer are String objects. The buffers to the string objects are pointers to the original string in the item. That is, it's not a deep copy. in Item_func_in::fix_length_and_dec, a copy of the original string is made. When it is, the null is not terminator is not set. It is this pointer that is placed in the in_string object. In InfiniDB processing, we need to get a copy of these strings to set up our own filter. We use the function c_ptr() to access them. c-ptr() reallocates because Ptr[str_length] is not 0 – there's no terminator. This reallocation messes up the in_string object. Plus, with all the garbage in the strings, InfiniDB's compare fails. There's a double failure. Anyway, to fix in Columnstore, we no longer use c_ptr, but rather ptr. It also trims to str->length() before using. | ||||||
| Comment by David Hall (Inactive) [ 2016-05-12 ] | ||||||
|
For QA | ||||||
| Comment by Dipti Joshi (Inactive) [ 2016-05-31 ] | ||||||
|
dleeyhHas this been verified ? | ||||||
| Comment by Daniel Lee (Inactive) [ 2016-05-31 ] | ||||||
|
Build tested: getsoftwareinfo Tue May 31 10:30:28 2016 Name : mariadb-columnstore-platform Relocations: (not relocatable) For vtable mode 0, it worked. For vtable mode 1, it still returned a syntax error. MariaDB [mytest]> SELECT SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT)) AS REVENUE FROM LINEITEM, PART WHERE ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#41' AND P_CONTAINER IN ( 'SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') AND L_QUANTITY >= 3 AND L_QUANTITY <= 3 + 1 AND P_SIZE BETWEEN 1 AND 5 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#33' AND P_CONTAINER IN ( 'MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') AND L_QUANTITY >= 14 AND L_QUANTITY <= 14 + 1 AND P_SIZE BETWEEN 1 AND 10 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#45' AND P_CONTAINER IN ( 'LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') AND L_QUANTITY >= 25 AND L_QUANTITY <= 25 + 1 AND P_SIZE BETWEEN 1 AND 15 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' );
---------------------
--------------------- MariaDB [mytest]> set infinidb_vtable_mode=0; MariaDB [mytest]> SELECT SUM(L_EXTENDEDPRICE * (1 - L_DISCOUNT)) AS REVENUE FROM LINEITEM, PART WHERE ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#41' AND P_CONTAINER IN ( 'SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') AND L_QUANTITY >= 3 AND L_QUANTITY <= 3 + 1 AND P_SIZE BETWEEN 1 AND 5 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#33' AND P_CONTAINER IN ( 'MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') AND L_QUANTITY >= 14 AND L_QUANTITY <= 14 + 1 AND P_SIZE BETWEEN 1 AND 10 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' ) OR ( P_PARTKEY = L_PARTKEY AND P_BRAND = 'Brand#45' AND P_CONTAINER IN ( 'LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') AND L_QUANTITY >= 25 AND L_QUANTITY <= 25 + 1 AND P_SIZE BETWEEN 1 AND 15 AND L_SHIPMODE IN ('AIR', 'AIR REG') AND L_SHIPINSTRUCT = 'DELIVER IN PERSON' );
-------------
------------- | ||||||
| Comment by Daniel Lee (Inactive) [ 2016-05-31 ] | ||||||
|
The syntax error issue has been moved to ticket |