1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

MCOL-4874 Crossengine JOIN involving a ColumnStore table and a

wide decimal column in a non-ColumnStore table throws an exception.

ROW::getSignedNullValue() method does not support wide decimal fields
yet. To fix this exception, we remove the call to this method from
CrossEngineStep::setField().
This commit is contained in:
Gagan Goel
2021-12-07 16:09:34 -05:00
parent 25237b4ba8
commit 340a90fc8d
4 changed files with 118 additions and 29 deletions

View File

@ -195,10 +195,17 @@ void CrossEngineStep::setField(int i, const char* value, unsigned long length, M
ct.colDataType = colType;
ct.colWidth = row.getColumnWidth(i);
if (colType == CalpontSystemCatalog::DECIMAL)
if (colType == CalpontSystemCatalog::DECIMAL ||
colType == CalpontSystemCatalog::UDECIMAL)
{
ct.scale = field->decimals;
ct.precision = field->length;
if (ct.colWidth == datatypes::MAXDECIMALWIDTH)
{
row.setInt128Field(convertValueNum<int128_t>(value, ct), i);
return;
}
}
else
{
@ -206,7 +213,7 @@ void CrossEngineStep::setField(int i, const char* value, unsigned long length, M
ct.precision = row.getPrecision(i);
}
row.setIntField(convertValueNum(value, ct, row.getSignedNullValue(i)), i);
row.setIntField(convertValueNum<int64_t>(value, ct), i);
}
}
@ -229,29 +236,21 @@ inline void CrossEngineStep::addRow(RGData& data)
// simplified version of convertValueNum() in jlf_execplantojoblist.cpp.
int64_t CrossEngineStep::convertValueNum(
const char* str, const CalpontSystemCatalog::ColType& ct, int64_t nullValue)
template <typename T>
T CrossEngineStep::convertValueNum(
const char* str, const CalpontSystemCatalog::ColType& ct)
{
// return value
int64_t rv = nullValue;
// null value
if (str == NULL)
return rv;
// convertColumnData(execplan::CalpontSystemCatalog::ColType colType,
// const std::string& dataOrig,
// bool& pushWarning,
// bool nulFlag,
// bool noRoundup )
T rv = 0;
bool pushWarning = false;
boost::any anyVal = ct.convertColumnData(str, pushWarning, fTimeZone, false, true, false);
bool nullFlag = (str == NULL);
boost::any anyVal = ct.convertColumnData((nullFlag ? "" : str), pushWarning, fTimeZone, nullFlag, true, false);
// Out of range values are treated as NULL as discussed during design review.
if (pushWarning)
return rv;
{
anyVal = ct.getNullValueForType();
}
// non-null value
switch (ct.colDataType)
{
case CalpontSystemCatalog::BIT:
@ -259,7 +258,11 @@ int64_t CrossEngineStep::convertValueNum(
break;
case CalpontSystemCatalog::TINYINT:
#if BOOST_VERSION >= 105200
rv = boost::any_cast<char>(anyVal);
#else
rv = boost::any_cast<int8_t>(anyVal);
#endif
break;
case CalpontSystemCatalog::UTINYINT:
@ -285,7 +288,11 @@ int64_t CrossEngineStep::convertValueNum(
case CalpontSystemCatalog::UMEDINT:
case CalpontSystemCatalog::UINT:
#ifdef _MSC_VER
rv = boost::any_cast<unsigned int>(anyVal);
#else
rv = boost::any_cast<uint32_t>(anyVal);
#endif
break;
case CalpontSystemCatalog::BIGINT:
@ -359,20 +366,21 @@ int64_t CrossEngineStep::convertValueNum(
case CalpontSystemCatalog::DECIMAL:
case CalpontSystemCatalog::UDECIMAL:
if (ct.colWidth == CalpontSystemCatalog::ONE_BYTE)
rv = boost::any_cast<char>(anyVal);
else if (ct.colWidth == CalpontSystemCatalog::TWO_BYTE)
rv = boost::any_cast<int16_t>(anyVal);
else if (ct.colWidth == CalpontSystemCatalog::FOUR_BYTE)
if (LIKELY(ct.colWidth == datatypes::MAXDECIMALWIDTH))
rv = boost::any_cast<int128_t>(anyVal);
else if (ct.colWidth == execplan::CalpontSystemCatalog::EIGHT_BYTE)
rv = boost::any_cast<long long>(anyVal);
else if (ct.colWidth == execplan::CalpontSystemCatalog::FOUR_BYTE)
#ifdef _MSC_VER
rv = boost::any_cast<int>(anyVal);
#else
rv = boost::any_cast<int32_t>(anyVal);
#endif
else
rv = boost::any_cast<long long>(anyVal);
else if (ct.colWidth == execplan::CalpontSystemCatalog::TWO_BYTE)
rv = boost::any_cast<int16_t>(anyVal);
else if (ct.colWidth == execplan::CalpontSystemCatalog::ONE_BYTE)
rv = boost::any_cast<char>(anyVal);
break;
default:

View File

@ -165,8 +165,9 @@ protected:
virtual void setField(int, const char*, unsigned long, MYSQL_FIELD*, rowgroup::Row&);
inline void addRow(rowgroup::RGData&);
//inline void addRow(boost::shared_array<uint8_t>&);
virtual int64_t convertValueNum(
const char*, const execplan::CalpontSystemCatalog::ColType&, int64_t);
template <typename T>
T convertValueNum(
const char*, const execplan::CalpontSystemCatalog::ColType&);
virtual void formatMiniStats();
virtual void printCalTrace();

View File

@ -0,0 +1,23 @@
DROP DATABASE IF EXISTS `mcol_4874`;
CREATE DATABASE `mcol_4874`;
USE `mcol_4874`;
CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001';
GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost';
FLUSH PRIVILEGES;
CREATE TABLE cs1 (a1 INT, b1 BIGINT, c1 INT)ENGINE=COLUMNSTORE;
CREATE TABLE i1 (a2 INT, b2 DECIMAL(37,0), c2 INT);
INSERT INTO cs1 VALUES (1, 11, 10), (1, 0, 11);
INSERT INTO i1 VALUES (1, 11, 100), (1, 0, 11), (1, 12, 101);
SELECT * FROM
(
SELECT a1 AS col1, COUNT(DISTINCT(IF((b1 <> 0), c1, NULL))) FROM cs1 group by col1
) as t1
JOIN
(
SELECT a2 AS col1, COUNT(DISTINCT(IF((b2 <> 0), c2, NULL))) FROM i1 GROUP BY col1
) as t2
USING (col1);
col1 COUNT(DISTINCT(IF((b1 <> 0), c1, NULL))) COUNT(DISTINCT(IF((b2 <> 0), c2, NULL)))
1 1 2
DROP USER 'cejuser'@'localhost';
DROP DATABASE `mcol_4874`;

View File

@ -0,0 +1,57 @@
#
# MCOL-4874 Crossengine JOIN involving a ColumnStore table and a
# wide decimal column in a non-ColumnStore table throws an exception.
#
-- source include/have_innodb.inc
-- source ../include/have_columnstore.inc
if (!$MASTER_MYPORT)
{
# Running with --extern
let $MASTER_MYPORT=`SELECT @@port`;
}
--disable_warnings
DROP DATABASE IF EXISTS `mcol_4874`;
--enable_warnings
CREATE DATABASE `mcol_4874`;
USE `mcol_4874`;
#
# Enable cross engine join
# Configure user and password in Columnstore.xml file
#
--exec $MCS_MCSSETCONFIG CrossEngineSupport User 'cejuser'
--exec $MCS_MCSSETCONFIG CrossEngineSupport Password 'Vagrant1|0000001'
--exec $MCS_MCSSETCONFIG CrossEngineSupport Port $MASTER_MYPORT
#
# Create corresponding in the server
#
--disable_warnings
CREATE USER IF NOT EXISTS'cejuser'@'localhost' IDENTIFIED BY 'Vagrant1|0000001';
--enable_warnings
GRANT ALL PRIVILEGES ON *.* TO 'cejuser'@'localhost';
FLUSH PRIVILEGES;
CREATE TABLE cs1 (a1 INT, b1 BIGINT, c1 INT)ENGINE=COLUMNSTORE;
CREATE TABLE i1 (a2 INT, b2 DECIMAL(37,0), c2 INT);
INSERT INTO cs1 VALUES (1, 11, 10), (1, 0, 11);
INSERT INTO i1 VALUES (1, 11, 100), (1, 0, 11), (1, 12, 101);
SELECT * FROM
(
SELECT a1 AS col1, COUNT(DISTINCT(IF((b1 <> 0), c1, NULL))) FROM cs1 group by col1
) as t1
JOIN
(
SELECT a2 AS col1, COUNT(DISTINCT(IF((b2 <> 0), c2, NULL))) FROM i1 GROUP BY col1
) as t2
USING (col1);
# Cleanup
DROP USER 'cejuser'@'localhost';
DROP DATABASE `mcol_4874`;