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

MCOL-271 empty strings should not be NULLs (#2794)

This patch improves handling of NULLs in textual fields in ColumnStore.
Previously empty strings were considered NULLs and it could be a problem
if data scheme allows for empty strings. It was also one of major
reasons of behavior difference between ColumnStore and other engines in
MariaDB family.

Also, this patch fixes some other bugs and incorrect behavior, for
example, incorrect comparison for "column <= ''" which evaluates to
constant True for all purposes before this patch.
This commit is contained in:
Sergey Zefirov
2023-03-30 17:26:45 +01:00
committed by Roman Nozdrin
parent 0ea592da80
commit b53c231ca6
417 changed files with 12459 additions and 3520 deletions

View File

@ -129,14 +129,16 @@ namespace
d /= exp10(in.getScale(i));
os.precision(15);
os << d;
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeIntToStringNoScale(const Row& in, Row* out, uint32_t i)
{
ostringstream os;
os << in.getIntField(i);
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeIntToXFloat(const Row& in, Row* out, uint32_t i)
@ -206,14 +208,16 @@ namespace
d /= exp10(in.getScale(i));
os.precision(15);
os << d;
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeUintToStringNoScale(const Row& in, Row* out, uint32_t i)
{
ostringstream os;
os << in.getUintField(i);
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizUintToXFloat(const Row& in, Row* out, uint32_t i)
@ -301,7 +305,8 @@ namespace
void normalizeDateToString(const Row& in, Row* out, uint32_t i)
{
string d = DataConvert::dateToString(in.getUintField(i));
out->setStringField(d, i);
utils::NullString ns(d);
out->setStringField(ns, i);
}
void normalizeDatetimeToDatetime(const Row& in, Row* out, uint32_t i)
@ -351,7 +356,8 @@ namespace
void normalizeDatetimeToString(const Row& in, Row* out, uint32_t i)
{
string d = DataConvert::datetimeToString(in.getUintField(i));
out->setStringField(d, i);
utils::NullString ns(d);
out->setStringField(ns, i);
}
void normalizeTimestampToTimestamp(const Row& in, Row* out, uint32_t i)
@ -405,7 +411,8 @@ namespace
void normalizeTimestampToString(const Row& in, Row* out, uint32_t i, long fTimeZone)
{
string d = DataConvert::timestampToString(in.getUintField(i), fTimeZone);
out->setStringField(d, i);
utils::NullString ns(d);
out->setStringField(ns, i);
}
void normalizeTimeToTime(const Row& in, Row* out, uint32_t i)
@ -416,7 +423,8 @@ namespace
void normalizeTimeToString(const Row& in, Row* out, uint32_t i)
{
string d = DataConvert::timeToString(in.getIntField(i));
out->setStringField(d, i);
utils::NullString ns(d);
out->setStringField(ns, i);
}
void normalizeXFloatToIntWithScaleInt128(const Row& in, Row* out, uint32_t i)
@ -509,7 +517,8 @@ namespace
ostringstream os;
os.precision(15); // to match mysql's output
os << val;
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeXDoubleToString(const Row& in, Row* out, uint32_t i)
@ -518,7 +527,8 @@ namespace
ostringstream os;
os.precision(15); // to match mysql's output
os << val;
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeXFloatToWideXDecimal(const Row& in, Row* out, uint32_t i)
@ -593,7 +603,8 @@ namespace
ostringstream os;
os.precision(15); // to match mysql's output
os << val;
out->setStringField(os.str(), i);
utils::NullString ns(os.str());
out->setStringField(ns, i);
}
void normalizeLongDoubleToXDecimalInt128(const Row& in, Row* out, uint32_t i)
@ -675,14 +686,14 @@ namespace
int128_t val128 = 0;
in.getInt128Field(i, val128);
datatypes::Decimal dec(0, in.getScale(i), in.getPrecision(i), val128);
out->setStringField(dec.toString(), i);
out->setStringField(dec.toNullString(), i);
}
void normalizeXDecimalToString(const Row& in, Row* out, uint32_t i)
{
int64_t val = in.getIntField(i);
datatypes::Decimal dec(val, in.getScale(i), in.getPrecision(i));
out->setStringField(dec.toString(), i);
out->setStringField(dec.toNullString(), i);
}
void normalizeBlobVarbinary(const Row& in, Row* out, uint32_t i)
@ -1826,7 +1837,7 @@ void TupleUnion::writeNull(Row* out, uint32_t col)
case 7:
case 8: out->setUintField<8>(joblist::CHAR8NULL, col); break;
default: out->setStringField(joblist::CPNULLSTRMARK, col); break;
default: out->setStringField(nullptr, 0, col); break;
}
break;
@ -1836,7 +1847,7 @@ void TupleUnion::writeNull(Row* out, uint32_t col)
case CalpontSystemCatalog::VARBINARY:
// could use below if zero length and NULL are treated the same
// out->setVarBinaryField("", col); break;
out->setVarBinaryField(joblist::CPNULLSTRMARK, col);
out->setVarBinaryField(nullptr, 0, col);
break;
default: