[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' );
---------

REVENUE

---------

NULL

---------
1 row in set (5.63 sec)

MariaDB [tpch1]>

The proper answer is:
-------------

REVENUE

-------------

607989.6988

-------------
1 row in set (14.99 sec)

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' );
ERROR 138 (HY000): IDB-1000: 'lineitem' and 'part' are not joined.
mysql>



 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):

SELECT COUNT(*) FROM PART WHERE P_CONTAINER IN ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG');

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:

SELECT COUNT(*) FROM PART WHERE P_CONTAINER IN ('SM CASE');

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)
Version : 1.0 Vendor: MariaDB Corporation Ab
Release : 0 Build Date: Fri 27 May 2016 04:07:53 PM EDT
Install Date: Mon 30 May 2016 11:32:15 AM EDT Build Host: srvbuilder

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' );
ERROR 1815 (HY000): Internal error: IDB-1000: 'lineitem' and 'part' are not joined.
MariaDB [mytest]> show variables like "%vtable%";
---------------------------+

Variable_name Value

---------------------------+

infinidb_vtable_mode 1

---------------------------+
1 row in set (0.00 sec)

MariaDB [mytest]> set infinidb_vtable_mode=0;
Query OK, 0 rows affected (0.00 sec)

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' );
-------------

REVENUE

-------------

607989.6988

-------------
1 row in set (15.02 sec)

Comment by Daniel Lee (Inactive) [ 2016-05-31 ]

The syntax error issue has been moved to ticket MCOL-91 so I am closing this ticket.

Generated at Thu Feb 08 02:18:07 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.