Internal memory representation of MEDIUMINT datatype uses 24 bits. This is
true for both MariaDB server as well as ColumnStore. MCS plugin code uses
TypeHandlerSInt24 and TypeHandlerUInt24 classes to respectively convert the
binary representation of the signed and unsigned MEDIUMINT values passed by
the server to the plugin. The plugin then outputs the text representation
of these values into an open file descriptor which is piped to cpimport
for the final load into the MCS db files.
The TypeHandlerXInt24 classes were earlier incorrectly using
WriteBatchField::ColWriteBatchXInt32() functions which operate on a 4 byte
buffer. This resulted in incorrect parsing of MEDIUMINT values. As a fix,
we implement WriteBatchField::ColWriteBatchXInt24() functions which
correctly handle the 24 bit input buffer used for MEDIUMINT datatype.
This patch fixs the reported JIRA issue MCOL 5205, which consists of a wrong union type from two input Int types. The bug results in wrong unioned answers in CS. The fix includes more INT case discussions. Additionaly, this patch provides detailed unit tests for correctness in UNION processing with Int.
Signed-off-by: Jigao Luo <luojigao@outlook.com>
* build boost during build phase, not during configure
* add dependency for generated header files errorids.h messageids.h
see 7e868bc58833
* set explicit dependencies on external_boost for #include's
* clang-14 compatibility fix
* MCOL-5092 Ensure column width is correct for datatype
Change MODA return type to STRING
Modify MODA to handle every numeric type
* MCOL-5162 MODA to support char and varchar with collation support
Fixes to the aggregate bit functions
When we fixed the storage sign issue for MCOL-5092, it uncovered a problem in the bit aggregates (bit_and, bit_or and bit_xor). These aggregates should always return UBIGINT, but they relied on the type of the argument column, which gave bad results.
The idea is relatively simple - encode prefixes of collated strings as
integers and use them to compute extents' ranges. Then we can eliminate
extents with strings.
The actual patch does have all the code there but miss one important
step: we do not keep collation index, we keep charset index. Because of
this, some of the tests in the bugfix suite fail and thus main
functionality is turned off.
The reason of this patch to be put into PR at all is that it contains
changes that made CHAR/VARCHAR columns unsigned. This change is needed in
vectorization work.
* Fix clang warnings
* Remove vim tab guides
* initialize variables
* 'strncpy' output truncated before terminating nul copying as many bytes from a string as its length
* Fix ISO C++17 does not allow 'register' storage class specifier for outdated bison
* chars are unsigned on ARM, having if (ival < 0) always false
* chars are unsigned by default on ARM and comparison with -1 if always true
Part 1:
As part of MCOL-3776 to address synchronization issue while accessing
the fTimeZone member of the Func class, mutex locks were added to the
accessor and mutator methods. However, this slows down processing
of TIMESTAMP columns in PrimProc significantly as all threads across
all concurrently running queries would serialize on the mutex. This
is because PrimProc only has a single global object for the functor
class (class derived from Func in utils/funcexp/functor.h) for a given
function name. To fix this problem:
(1) We remove the fTimeZone as a member of the Func derived classes
(hence removing the mutexes) and instead use the fOperationType
member of the FunctionColumn class to propagate the timezone values
down to the individual functor processing functions such as
FunctionColumn::getStrVal(), FunctionColumn::getIntVal(), etc.
(2) To achieve (1), a timezone member is added to the
execplan::CalpontSystemCatalog::ColType class.
Part 2:
Several functors in the Funcexp code call dataconvert::gmtSecToMySQLTime()
and dataconvert::mySQLTimeToGmtSec() functions for conversion between seconds
since unix epoch and broken-down representation. These functions in turn call
the C library function localtime_r() which currently has a known bug of holding
a global lock via a call to __tz_convert. This significantly reduces performance
in multi-threaded applications where multiple threads concurrently call
localtime_r(). More details on the bug:
https://sourceware.org/bugzilla/show_bug.cgi?id=16145
This bug in localtime_r() caused processing of the Functors in PrimProc to
slowdown significantly since a query execution causes Functors code to be
processed in a multi-threaded manner.
As a fix, we remove the calls to localtime_r() from gmtSecToMySQLTime()
and mySQLTimeToGmtSec() by performing the timezone-to-offset conversion
(done in dataconvert::timeZoneToOffset()) during the execution plan
creation in the plugin. Note that localtime_r() is only called when the
time_zone system variable is set to "SYSTEM".
This fix also required changing the timezone type from a std::string to
a long across the system.
column width
RTSCommand was modified to use a fabric that produces CC class based on column width
NB this patch doesn't affect PseudoCC that also leverages ColumnCommand
non-wide decimal column in the HAVING clause.
In buildAggregateColumn(), if an aggregate function (such as avg)
is applied on a non-wide decimal column, we were setting the precision
of the resulting column as -1. This later down in the execution got
converted to 255 as in some cases, precision is stored as uint8_t.
The predicate operations on a DECIMAL column has logic that uses
the wide Decimal::s128value field if precision > 18. This logic incorrectly
used the Decimal::s128value instead of the correct value stored in the
narrow Decimal::value field, since precision of the Decimal column
was 255. The fix is to set the aggregate column precision to
datatypes::INT64MAXPRECISION (18) in buildAggregateColumn() when the
aggregate is applied on a non-wide decimal column.
This commit also partially fixes -Wstrict-aliasing GCC warnings.
mcsconfig.h and my_config.h have the following
pre-processor definitions:
1. Conflicting definitions coming from the standard cmake definitions:
- PACKAGE
- PACKAGE_BUGREPORT
- PACKAGE_NAME
- PACKAGE_STRING
- PACKAGE_TARNAME
- PACKAGE_VERSION
- VERSION
2. Conflicting definitions of other kinds:
- HAVE_STRTOLL - this is a dirt in MariaDB headers.
Should be fixed in the server code. my_config.h erroneously
performs "#define HAVE_STRTOLL" instead of "#define HAVE_STRTOLL 1".
in some cases. The former is not CMake compatible style. The latter is.
3. Non-conflicting definitions:
Otherwise, mcsconfig.h and my_config.h should be mutually compatible,
because both are generated by cmake on the same host machine. So
they should have exactly equal definitions like "HAVE_XXX", "SIZEOF_XXX", etc.
Observations:
- It's OK to include both mcsconfig.h and my_config.h providing that we
suppress duplicate definition of the above conflicting types #1 and #2.
- There is no a need to suppress duplicate definitions mentioned in #3,
as they are compatible!
- my_sys.h and m_ctype.h must always follow a CMake configuation header,
either my_config.h or mcsconfig.h (or both).
They must never be included without any preceeding configuration header.
This change make sure that we resolve conflicts by:
- either disallowing inclusion of mcsconfig.h and my_config.h
at the same time
- or by hiding conflicting definitions #1 and #2
(with their later restoring).
- also, by making sure that my_sys.h and m_ctype.h always follow
a CMake configuration file.
Details:
- idb_mysql.h can now only be included only after my_config.h
An attempt to use idb_mysql.h with mcsconfig.h instead of
my_config.h is caught by the "#error" preprocessor directive.
- mariadb_my_sys.h can now be only included after mcsconfig.h.
An attempt to use mariadb_my_sys.h without mcscofig.h
(e.g. with my_config.h) is also caught by "#error".
- collation.h now can now be included in two ways.
It now has the following effective structure:
#if defined(PREFER_MY_CONFIG_H) && defined(MY_CONFIG_H)
// Remember current conflicting definitions on the preprocessor stack
// Undefine current conflicting definitions
#endif
#include "mcsconfig.h"
#include "m_ctype.h"
#if defined(PREFER_MY_CONFIG_H) && defined(MY_CONFIG_H)
# Restore conflicting definitions from the preprocessor stack
#endif
and can be included as follows:
a. using only mcsconfig.h as a configuration header:
// my_config.h must not be included so far
#include "collation.h"
b. using my_config.h as the first included configuration file:
#define PREFER_MY_CONFIG_H // Force conflict resolution
#include "my_config.h" // can be included directly or indirectly
...
#include "collation.h"
Other changes:
- Adding helper header files
utils/common/mcsconfig_conflicting_defs_remember.h
utils/common/mcsconfig_conflicting_defs_restore.h
utils/common/mcsconfig_conflicting_defs_undef.h
to perform conflict resolution easier.
- Removing `#include "collation.h"` from a number of files,
as it's automatically included from rowgroup.h.
- Removing redundant `#include "utils_utf8.h"`.
This change is not directly related to the problem being fixed,
but it's nice to remove redundant directives for both collation.h
and utils_utf8.h from all the files that do not really need them.
(this change could probably have gone as a separate commit)
- Changing my_init() to MY_INIT(argv[0]) in the MCS services sources.
After the fix of the complitation failure it appeared that ColumnStore
services compiled with the debug build crash due to recent changes in
safemalloc. The crash happened in strcmp() with `my_progname` as an argument
(where my_progname is a mysys global variable). This problem should
probably be fixed on the server side as well to avoid passing NULL.
But, the majority of MariaDB executable programs also use MY_INIT(argv[0])
rather than my_init(). So let's make MCS do like the other programs do.
This patch fixes:
- MCOL-4614 calShowPartitions() precision loss for huge narrow decimal
- MCOL-4615 GROUP_CONCAT() precision loss for huge narrow decimal
- MCOL-4660 Narow decimal to string conversion is inconsistent about zero integral
Changes:
- Implementing Row::getDecimalField()
- Removing double arithmetic from the code printing DECIMAL values
in TypeHandlerXDecimal::format64() and GroupConcator::outputRow().
Using Decimal::toString() instead.
- Rewriting Decimal::toStringTSInt64(). The old implementation
was wrong, too complex and slow (used unnecessary memmove, memcpy).
An additional cleanup:
- Removing the ENGINE=COLUMNSTORE clause from tests for MCOL-4532 and MCOL-4640
type_decimal.test is combinations-aware. It's run two times with
default_storage_engine=MyISAM and default_storage_engine=COLUMNSTORE.
So the CREATE TABLE statements should not specify the engine explicitly.
- Adding --disable_warnings in the old fixed test.
We needed to suppress warnings when the MyISAM combination is being run.
Previously the table was erroneously created with ENGINE=COLUMNSTORE
even with the MyISAM combination run. So warning were not generated.
Progress keep and test commit
Progress keep and test commit
Progress keep and test commit
Again, trying to pinpoint problematic part of a change
Revert "Again, trying to pinpoint problematic part of a change"
This reverts commit 71874e7c0d7e4eeed0c201b12d306b583c07b9e2.
Revert "Progress keep and test commit"
This reverts commit 63c7bc67ae55bdb81433ca58bbd239d6171a1031.
Revert "Progress keep and test commit"
This reverts commit 121c09febd78dacd37158caeab9ac70f65b493df.
Small steps - I walk minefield here
Propagating changes - now CPInfo in convertValArray
Progress keep commit
Restoring old functionality
Progress keep commit
Small steps to avoid/better locate old problem with the write engine.
Progress keeping commit
Thread the CPInfo up to convertValArray call in writeColumnRec
About to test changes - I should get no regression and no updates in
ranges either.
Testing out why I get a regression
Investigating source of regression
Debugging prints
Fix compile error
Debugging print - debug regression
I clearly see calls to writeColumnRec and prints there added to discern
between these.
Fix warning error
Possible culprit
Add forgotten default parameter for convertValArray
New logic to test
Max/min gets updated during value conversion
To test results of updates
Debug logs
Debug logs
An attempt to provide proper sequence index
Debug logs
An attempt to provide proper sequence index - now magic for resetting
Debug logs
Debug logs
Debug logs
Trying to perform correct updates
Trying to perform correct updates - seqNum woes fight
COMMIT after INSERT performs 'mark extent as invalid' operation - investigating
To test: cut setting of CPInfo upon commit from DML processor
It may be superfluous as write engine does that too
Debug logs
Debug logs
Better interface for CPMaxMin
Old interface forgot to set isBinaryColumn field
Possible fix for the problems
I forgot to reassign the value in cpinfoList
Debug logs
Computation of 'binary' column property
logs indicated that it was not set in getExtentCPMaxMin, and it was impossible to compute there so I had to move that into writeengine.
To test: code to allow cross-extent insertion
To test: removed another assertion for probable cause of errors
Debug logs
Dropped excessive logs
Better reset code
Again, trying to fix ordering
Fixing order of rowids for LBID computation
Debug logs
Remove update of second LBID in split insert
I have to validate incorrect behaviour for this test
Restoring the case where everything almost worked
Tracking changes in newly created extents
Progress keeping commit
Fixing build errors with recent server
An ability to get old values from blocks we update
Progress keeping commit
Adding analysis of old values to write engine code.
It is needed for updates and deletes.
Progress keeping commit
Moving max/min range update from convertValArray into separate function with simpler logic.
To test and debug - logic is there
Fix build errors
Update logic to debug
There is a suspicious write engine method updateColumnRecs which
receives a vector of column types but does not iterate over them
(otherwise it will be identical to updateColumnRec in logic).
Other than that, the updateColumnRec looks like the center of all
updates - deleteRow calls it, for example, dml processor also calls it.
Debug logs for insert bookkeeping regression
Set up operation type in externally-callable interface
Internal operations depend on the operation type and consistency is what matters there.
Debug logs
Fix for extent range update failure during update operation
Fix build error
Debug logs
Fix for update on deletion
I am not completely sure in it - to debug.
Debug log
writeColumnRec cannot set m_opType to UPDATE unconditionally
It is called from deleteRow
Better diagnostics
Debug logs
Fixed search condition
Debug logs
Debugging invalid LBID appearance
Debug logs - fixed condition
Fix problems with std::vector reallocation during growth
Fix growing std::vector data dangling access error
Still fixing indexing errors
Make in-range update to work
Correct sequence numbers
Debug logs
Debug logs
Remove range drop from DML part of write engine
A hack to test the culprit of range non-keeping
Tests - no results for now
MTR-style comments
Empty test results
To be filled with actual results.
Special database and result selects for all tests
Pleasing MTR with better folder name
Pleasing MTR - testing test result comparison
Pleasing MTR by disabling warnings
All test results
Cleaning up result files
Reset ranges before update
Remove comments from results - point of failure in MTR
Remove empty line from result - another MTR failure point
Probably fix for deletes
Possible fix for remaining failed delete test
Fix a bug in writeRows
It should not affect delete-with-range test case, yet it is a bug.
Debug logs
Debug logs
Tests reorganization and description
Support for unsigned integer for new tests
Fix type omission
Fix test failure due to warnings on clean installation
Support for bigint to test
Fix for failed signed bigint test
Set proper unsignedness flag
Removed that assignment during refactoring.
Tests for types with column width 1 and 2
Support for types in new tests
Remove trailing empty lines from results
Tests had failed because of extra empty lines.
Remove debug logs
Update README with info about new tests
Move tests for easier testing
Add task tag to tests
Fix invalid unsaigned range check
Fix for signed types
Fix regressions - progress keeping commit
Do not set invalid ranges into valid state
A possible fix for mcs81_self_join test
MCOL 2044 test database cleanup
Missing expected results
Delete extraneous assignment to m_opType
nullptr instead of NULL
Refactor extended CPInfo with TypeHandler
Better handling of ranges - safer types, less copy-paste
Fix logic error related to typo
Fix logic error related to typo
Trying to figure out why invalid ranges aren't displayed as NULL..NULL
Debug logs
Debug logs
Debug logs
Debug logs for worker node
Debug logs for worker node in extent map
Debugging virtual table fill operation
Debugging virtual table fill operation
Fix for invalid range computation
Remove debug logs
Change handling of invalid ranges
They are also set, but to invalid state.
Complete change
Fix typo
Remove unused code
"Fix" for tests - -1..0 instead of NULL..NULL for invalid unsigned ranges
Not a good change, yet I cannot do better for now.
MTR output requires tabs instead of spaces
Debug logs
Debug logs
Debug logs - fix build
Debug logs and logic error fix
Fix for clearly incorrect firstLBID in CPInfo being set - to test
Fix for system catalog operations suppot
Better interface to fix build errors
Delete tests we cannot satisfy due to extent rescan due to WHERE
Tests for wide decimals
Testing support for wide decimals
Fix for wide decimals tests
Fix for delete within range
Memory leak fix and, possible, double free fix
Dispatch on CalpontSystemCatalog::ColDataType is more robust
Add support for forgotten MEDINT type
Add forgottent BIGINT
empty() instead of size() > 0
Better layout
Remove confusing comment
Sensible names for special values of seqNum field
Tests for wide decimal support
Addressing concerns of drrtuy
Remove test we cannot satisfy
Final touches for PR
Remove unused result file
Bugs fixed:
- MCOL-4649 CAST(double AS UNSIGNED) returns 0
- MCOL-4631 CAST(double AS SIGNED) returns 0 or NULL
- MCOL-4647 SEC_TO_TIME(double_or_float) returns a wrong result
Problems:
- The code in Func_cast_unsigned::getUintVal() and
Func_cast_signed::getIntVal() did not properly check
the double value to fit inside a uint64_t/int64_t range.
So the corner cases:
- numeric_limits<uint64_t>::max()-2 for uint64_t
- numeric_limits<int64_t>::max() for int64_t
produced unexpected results.
The problem was in tests like this:
if (value > (double) numeric_limits<int64_t>::max())
A correct test would be:
if (value >= (double) numeric_limits<int64_t>::max())
- The code in Func_sec_to_time::getStrVal() searched for the decimal
dot character, assuming that the next character after the dot
was the leftmost fractional digit.
This assumption was wrong because huge double numbers use
scientific notation. So for example in "2.5e-40" the
digit "5" following the dot is NOT the leftmost fractional digit.
Also, the code in Func_sec_to_time::getStrVal() was slow
because of using non necessary to-string and from-string
data conversion.
Also, the code in Func_sec_to_time::getStrVal() evaluated
the argument two times: using getStrVal() then using getIntVal().
Solution:
- Adding new classes TDouble and TLongDouble.
- Adding a few function templates to reuse the code easier.
- Moving the conversion code inside TDouble and TLongDouble
methods toMCSSInt64Round() and toMCSUInt64Round().
- Reusing new classes and their methods in func_cast.cc and
func_sec_to_time.cc.
- MCOL-4618 FLOOR(-9999.0) returns a bad result
- MCOL-4653 CEIL(negativeNarrowDecimal) returns a wrong result
Main changes:
a. Moving ROUND, CEIL, FLOOR related code into a new simple
class template DecomposedDecimal, which is reused for
64 and 128 bit decimal.
b. Using DecomposedDecimal in TDecimal64 and TDecimal128
to implement ROUND, CEIL, FLOOR related methods.
c. Adding corresponding wrapper methods to the class Decimal.
d. Using new Decimal methods in Func_ceil and Func_floor.
Additional minor changed:
- Adding "explicit" to TSInt128 constructors to avoid
hidden data type conversion and erroneous choice between
64 vs 128 bit APIs when using Decimal.
Now one can call constructors in this self explanatory way:
- Decimal(TSInt128(some_int_value), scale, precision)
to create a wide decimal
- Decimal(TSInt64(some_int_value, scale, precision)
to create a narrow decimal
TODO:
Consider changing
Decimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128 = 0)
to
Decimal(int64_t val, int8_t s, uint8_t p, const int128_t &val128)
(or even removing this constructor) to disallow compilation of:
Decimal(some_trivial_type_value, scale, precision)
The "SIGNED" part of the problem was previously fixed by MCOL-4640.
Fixing the "UNSIGNED" part.
- Adding TDecimal64::toUInt64Round() and Decimal::decimal64ToUInt64Round()
- Renaming Decimal::narrowRound() to decimal64ToSInt64Round(),
for a more self-descriptive name, and for symmetry with decimal64ToUInt64Round()
- Reusing TDecimal64::toSInt64Round() inside decimal64ToSInt64Round().
This change was forgotten in MCOL-4640 :(
- Removing the old code in Func_cast_unsigned::getUintVal with pow().
It caused precision loss, hence the bug. Adding a call for
Decimal::decimal64ToUInt64Round() instead.
- Adding tests for both SIGNED and UNSIGNED casts.
Additional change:
- Moving the wide-decimal-to-uint64_t rounding code from Func_cast_unsigned::getUintVal()
to TDecimal128::toUInt64Round() (with refactoring). Adding TDecimal::toUInt64Round()
for symmetry with TDecimal::toSInt64Round(). It will be easier to reuse the code
with way.
Detailed change list:
- Splitting out the narrow part of "class Decimal" into a separate class TDecimal64
- Adding a method TDecimal64::toSInt64Round()
- Reusing the method TDecimal64::toSInt64Round() in:
* Func_cast_signed::getIntVal()
* Func_char::getStrVal()
* Func_elt::getStrVal()
* makedate()
* Func_maketime::getStrVal()
Note, reusing this method in Func_char::getStrVal() also fixed this bug:
MCOL-4634 CHAR(negativeWideDecimal) is not like InnoDB
because the old code handled negative wide decimal values
in a wrong way.
- Adding a new class TDecimal128 for symmetry.
Moving a few wide decimal methods and constexpr's from Decimal to TDecimal128.
The new class TDecimal128 does not do much at this point yet.
Later we should be able to use TDecimal128 vs TDecimal64 in templates.
This change fixes:
MCOL-4462 CAST(varchar_expr AS DECIMAL(M,N)) returns a wrong result
MCOL-4500 Bit functions processing throws internally trying to cast char into decimal representation
MCOL-4532 CAST(AS DECIMAL) returns a garbage for large values
Also, this change makes string-to-decimal conversion 5-10 times faster,
depending on exact data.
Performance implemenent is achieved by the fact that (unlike in the old
implementation), the new version does not do any "string" object copying.
On aarch64, just use memcpy, don't use asm instructions to optimize it.
Because if gcc uses NEON extensions moving 16 bytes with memcpy,
it might be wise to just use memcpy instead