You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-07 03:22:57 +03:00
MCOL-1246 Fix string matching for whitespace
For equality string matches other engines ignore trailing whitespace (this does not apply to LIKE matches). So we should do the same. This patch trims whitespace for MIN/MAX extent elimination checks, fixed width columns and dictionary columns during equality matches against constants (SELECT * FROM t1 WHERE b = 'ABC').
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
#include "calpontsystemcatalog.h"
|
#include "calpontsystemcatalog.h"
|
||||||
#include "brm.h"
|
#include "brm.h"
|
||||||
#include "brmtypes.h"
|
#include "brmtypes.h"
|
||||||
|
#include "dataconvert.h"
|
||||||
|
|
||||||
#define IS_VERBOSE (fDebug >= 4)
|
#define IS_VERBOSE (fDebug >= 4)
|
||||||
#define IS_DETAIL (fDebug >= 3)
|
#define IS_DETAIL (fDebug >= 3)
|
||||||
@@ -653,7 +654,14 @@ bool LBIDList::CasualPartitionPredicate(const int64_t Min,
|
|||||||
|
|
||||||
if (bIsChar && 1 < ct.colWidth)
|
if (bIsChar && 1 < ct.colWidth)
|
||||||
{
|
{
|
||||||
scan = compareVal(order_swap(Min), order_swap(Max), order_swap(value),
|
// MCOL-1246 Trim trailing whitespace for matching so that we have
|
||||||
|
// the same as InnoDB behaviour
|
||||||
|
int64_t tMin = Min;
|
||||||
|
int64_t tMax = Max;
|
||||||
|
dataconvert::DataConvert::trimWhitespace(tMin);
|
||||||
|
dataconvert::DataConvert::trimWhitespace(tMax);
|
||||||
|
|
||||||
|
scan = compareVal(order_swap(tMin), order_swap(tMax), order_swap(value),
|
||||||
op, lcf);
|
op, lcf);
|
||||||
// cout << "scan=" << (uint32_t) scan << endl;
|
// cout << "scan=" << (uint32_t) scan << endl;
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,7 @@ using namespace boost;
|
|||||||
#include "we_type.h"
|
#include "we_type.h"
|
||||||
#include "stats.h"
|
#include "stats.h"
|
||||||
#include "primproc.h"
|
#include "primproc.h"
|
||||||
|
#include "dataconvert.h"
|
||||||
using namespace logging;
|
using namespace logging;
|
||||||
using namespace dbbc;
|
using namespace dbbc;
|
||||||
using namespace primitives;
|
using namespace primitives;
|
||||||
@@ -527,7 +528,13 @@ inline bool colCompare(int64_t val1, int64_t val2, uint8_t COP, uint8_t rf, int
|
|||||||
type == CalpontSystemCatalog::TEXT) && !isNull )
|
type == CalpontSystemCatalog::TEXT) && !isNull )
|
||||||
{
|
{
|
||||||
if (!regex.used && !rf)
|
if (!regex.used && !rf)
|
||||||
|
{
|
||||||
|
// MCOL-1246 Trim trailing whitespace for matching, but not for
|
||||||
|
// regex
|
||||||
|
dataconvert::DataConvert::trimWhitespace(val1);
|
||||||
|
dataconvert::DataConvert::trimWhitespace(val2);
|
||||||
return colCompare_(order_swap(val1), order_swap(val2), COP);
|
return colCompare_(order_swap(val1), order_swap(val2), COP);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return colStrCompare_(order_swap(val1), order_swap(val2), COP, rf, ®ex);
|
return colStrCompare_(order_swap(val1), order_swap(val2), COP, rf, ®ex);
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/scoped_array.hpp>
|
#include <boost/scoped_array.hpp>
|
||||||
|
#include <boost/algorithm/string/trim.hpp>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -164,7 +165,10 @@ void PrimitiveProcessor::p_TokenByScan(const TokenByScanRequestHeader *h,
|
|||||||
string arg_utf8;
|
string arg_utf8;
|
||||||
|
|
||||||
if (eqFilter) {
|
if (eqFilter) {
|
||||||
bool gotIt = eqFilter->find(string(sig, siglen)) != eqFilter->end();
|
// MCOL-1246 Trim whitespace before match
|
||||||
|
string strData(sig, siglen);
|
||||||
|
boost::trim_right(strData);
|
||||||
|
bool gotIt = eqFilter->find(strData) != eqFilter->end();
|
||||||
if ((h->COP1 == COMPARE_EQ && gotIt) || (h->COP1 == COMPARE_NE &&
|
if ((h->COP1 == COMPARE_EQ && gotIt) || (h->COP1 == COMPARE_NE &&
|
||||||
!gotIt))
|
!gotIt))
|
||||||
goto store;
|
goto store;
|
||||||
|
@@ -408,6 +408,7 @@ public:
|
|||||||
static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
static inline std::string decimalToString(int64_t value, uint8_t scale, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
||||||
static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
static inline void decimalToString(int64_t value, uint8_t scale, char* buf, unsigned int buflen, execplan::CalpontSystemCatalog::ColDataType colDataType);
|
||||||
static inline std::string constructRegexp(const std::string& str);
|
static inline std::string constructRegexp(const std::string& str);
|
||||||
|
static inline void trimWhitespace(int64_t &charData);
|
||||||
static inline bool isEscapedChar(char c) { return ('%' == c || '_' == c); }
|
static inline bool isEscapedChar(char c) { return ('%' == c || '_' == c); }
|
||||||
|
|
||||||
// convert string to date
|
// convert string to date
|
||||||
@@ -552,6 +553,18 @@ inline void DataConvert::decimalToString(int64_t int_val, uint8_t scale, char* b
|
|||||||
*(ptr + l1) = '.';
|
*(ptr + l1) = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void DataConvert::trimWhitespace(int64_t &charData)
|
||||||
|
{
|
||||||
|
// Trims whitespace characters off non-dict character data
|
||||||
|
char *ch_data = (char*) &charData;
|
||||||
|
for (int8_t i = 7; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (isspace(ch_data[i]) || ch_data[i] == '\0')
|
||||||
|
ch_data[i] = '\0';
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME: copy/pasted from dictionary.cpp: refactor
|
//FIXME: copy/pasted from dictionary.cpp: refactor
|
||||||
inline std::string DataConvert::constructRegexp(const std::string& str)
|
inline std::string DataConvert::constructRegexp(const std::string& str)
|
||||||
|
Reference in New Issue
Block a user