From 5d405588fcb216563f45077838ebc12547a5e3a2 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 2 Jun 2017 14:09:30 +0100 Subject: [PATCH] MCOL-730 Fix decimals in cross engine join We would get strange values for scale/precision in the results column of a cross engine join causing bad results. This patch uses the values from the MariaDB client connector instead. --- dbcon/joblist/crossenginestep.cpp | 26 +++++++++++++++++--------- dbcon/joblist/crossenginestep.h | 5 ++++- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dbcon/joblist/crossenginestep.cpp b/dbcon/joblist/crossenginestep.cpp index 37ccb0345..88cc6bbd9 100644 --- a/dbcon/joblist/crossenginestep.cpp +++ b/dbcon/joblist/crossenginestep.cpp @@ -231,7 +231,7 @@ void CrossEngineStep::makeMappings() } -void CrossEngineStep::setField(int i, const char* value, unsigned long length, Row& row) +void CrossEngineStep::setField(int i, const char* value, unsigned long length, MYSQL_FIELD* field, Row& row) { CalpontSystemCatalog::ColDataType colType = row.getColType(i); @@ -257,8 +257,16 @@ void CrossEngineStep::setField(int i, const char* value, unsigned long length, R CalpontSystemCatalog::ColType ct; ct.colDataType = colType; ct.colWidth = row.getColumnWidth(i); - ct.scale = row.getScale(i); - ct.precision = row.getPrecision(i); + if (colType == CalpontSystemCatalog::DECIMAL) + { + ct.scale = field->decimals; + ct.precision = field->length; + } + else + { + ct.scale = row.getScale(i); + ct.precision = row.getPrecision(i); + } row.setIntField(convertValueNum(value, ct, row.getSignedNullValue(i)), i); } } @@ -494,7 +502,7 @@ void CrossEngineStep::execute() while ((rowIn = mysql->nextRow()) && !cancelled()) { for(int i = 0; i < num_fields; i++) - setField(i, rowIn[i], mysql->getFieldLength(i), fRowDelivered); + setField(i, rowIn[i], mysql->getFieldLength(i), mysql->getField(i), fRowDelivered); addRow(rgDataDelivered); } @@ -514,7 +522,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] != -1) - setField(fFe1Column[i], rowIn[i], mysql->getFieldLength(i), rowFe1); + setField(fFe1Column[i], rowIn[i], mysql->getFieldLength(i), mysql->getField(i), rowFe1); } if (fFeFilters && fFeInstance->evaluate(rowFe1, fFeFilters.get()) == false) @@ -528,7 +536,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] == -1) - setField(i, rowIn[i], mysql->getFieldLength(i), fRowDelivered); + setField(i, rowIn[i], mysql->getFieldLength(i), mysql->getField(i), fRowDelivered); } addRow(rgDataDelivered); @@ -546,7 +554,7 @@ void CrossEngineStep::execute() while ((rowIn = mysql->nextRow()) && !cancelled()) { for(int i = 0; i < num_fields; i++) - setField(i, rowIn[i], mysql->getFieldLength(i), rowFe3); + setField(i, rowIn[i], mysql->getFieldLength(i), mysql->getField(i), rowFe3); fFeInstance->evaluate(rowFe3, fFeSelects); fFeInstance->evaluate(rowFe3, fFeSelects); @@ -577,7 +585,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] != -1) - setField(fFe1Column[i], rowIn[i], mysql->getFieldLength(i), rowFe1); + setField(fFe1Column[i], rowIn[i], mysql->getFieldLength(i), mysql->getField(i), rowFe1); } if (fFeFilters && fFeInstance->evaluate(rowFe1, fFeFilters.get()) == false) @@ -591,7 +599,7 @@ void CrossEngineStep::execute() for(int i = 0; i < num_fields; i++) { if (fFe1Column[i] == -1) - setField(i, rowIn[i], mysql->getFieldLength(i), rowFe3); + setField(i, rowIn[i], mysql->getFieldLength(i), mysql->getField(i), rowFe3); } fFeInstance->evaluate(rowFe3, fFeSelects); diff --git a/dbcon/joblist/crossenginestep.h b/dbcon/joblist/crossenginestep.h index c198efbef..82bb8eda3 100644 --- a/dbcon/joblist/crossenginestep.h +++ b/dbcon/joblist/crossenginestep.h @@ -64,14 +64,17 @@ public: { char** row = mysql_fetch_row(fRes); fieldLengths = mysql_fetch_lengths(fRes); + fFields = mysql_fetch_fields(fRes); return row; } long getFieldLength(int field) { return fieldLengths[field]; } + MYSQL_FIELD* getField(int field) { return &fFields[field]; } const std::string& getError() { return fErrStr; } private: MYSQL* fCon; MYSQL_RES* fRes; + MYSQL_FIELD* fFields; std::string fErrStr; unsigned long *fieldLengths; }; @@ -157,7 +160,7 @@ protected: virtual void makeMappings(); virtual void addFilterStr(const std::vector&, const std::string&); virtual std::string makeQuery(); - virtual void setField(int, const char*, unsigned long, rowgroup::Row&); + virtual void setField(int, const char*, unsigned long, MYSQL_FIELD*, rowgroup::Row&); inline void addRow(rowgroup::RGData &); //inline void addRow(boost::shared_array&); virtual int64_t convertValueNum(