From 4fc7fa12cdc16909c3a904cf4b9679f676a5c018 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Fri, 4 Nov 2016 14:06:00 +0000 Subject: [PATCH] MCOL-129 INSERT/UPDATE strict mode support This changes the warning for truncation to the correct MariaDB error code (1264). In addition it passes the strict mode up into the DML class to roll back correctly. It also sets the abort_on_warning flag for updates as this isn't set on the rnd_init phase but is needed for strict mode to work. --- dbcon/dmlpackage/calpontdmlpackage.cpp | 2 +- dbcon/dmlpackage/calpontdmlpackage.h | 5 +++++ dbcon/mysql/ha_calpont_dml.cpp | 12 ++++++++++-- dbcon/mysql/ha_calpont_impl.cpp | 24 ++++++++++++++++++------ writeengine/server/we_dmlcommandproc.cpp | 18 +++++++++++++++++- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/dbcon/dmlpackage/calpontdmlpackage.cpp b/dbcon/dmlpackage/calpontdmlpackage.cpp index 634b5c06a..fa741899f 100644 --- a/dbcon/dmlpackage/calpontdmlpackage.cpp +++ b/dbcon/dmlpackage/calpontdmlpackage.cpp @@ -40,7 +40,7 @@ namespace dmlpackage std::string dmlStatement, int sessionID ) :fSchemaName(schemaName), fTableName( tableName ), fDMLStatement( dmlStatement ), fSessionID(sessionID), fPlan(new messageqcpp::ByteStream()), fTable(0), fHasFilter(false), fLogging(true), fIsInsertSelect(false), - fIsBatchInsert(false), fIsAutocommitOn(false), fTableOid(0) + fIsBatchInsert(false), fIsAutocommitOn(false), fIsWarnToError(false), fTableOid(0) { } diff --git a/dbcon/dmlpackage/calpontdmlpackage.h b/dbcon/dmlpackage/calpontdmlpackage.h index 983d9d392..eb0f7aa58 100644 --- a/dbcon/dmlpackage/calpontdmlpackage.h +++ b/dbcon/dmlpackage/calpontdmlpackage.h @@ -226,6 +226,10 @@ namespace dmlpackage bool get_isAutocommitOn() { return fIsAutocommitOn; } void set_isAutocommitOn( const bool isAutocommitOn ) { fIsAutocommitOn = isAutocommitOn; } + + bool get_isWarnToError() { return fIsWarnToError; } + void set_isWarnToError( const bool isWarnToError ) { fIsWarnToError = isWarnToError; } + uint32_t getTableOid() { return fTableOid; } void setTableOid( const uint32_t tableOid ) { fTableOid = tableOid; } @@ -254,6 +258,7 @@ namespace dmlpackage bool fIsInsertSelect; bool fIsBatchInsert; bool fIsAutocommitOn; + bool fIsWarnToError; uint32_t fTableOid; WriteEngine::ChunkManager* fCM; }; diff --git a/dbcon/mysql/ha_calpont_dml.cpp b/dbcon/mysql/ha_calpont_dml.cpp index 1e9cf42a6..24e7ec9d5 100755 --- a/dbcon/mysql/ha_calpont_dml.cpp +++ b/dbcon/mysql/ha_calpont_dml.cpp @@ -370,6 +370,11 @@ int doProcessInsertValues ( TABLE* table, uint32_t size, cal_connection_info& ci { pDMLPackage->set_isBatchInsert( true ); } + if (thd->is_strict_mode()) + { + pDMLPackage->set_isWarnToError( true ); + } + pDMLPackage->setTableOid (ci.tableOid); if (lastBatch) { @@ -514,8 +519,11 @@ int doProcessInsertValues ( TABLE* table, uint32_t size, cal_connection_info& ci } if ( b == dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING ) { - rc = 0; - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, errormsg.c_str()); + if (!thd->is_strict_mode()) + { + rc = 0; + } + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, errormsg.c_str()); } if ( rc != 0 ) diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index eb8f7c00d..f86a8a73c 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -1603,6 +1603,8 @@ uint32_t doUpdateDelete(THD *thd) command = "COMMIT"; else if ((useHdfs) && (b != 0)) command = "ROLLBACK"; + else if ((b == dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING) && thd->is_strict_mode()) + command = "ROLLBACK"; else if ((!(current_thd->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) && (( b == 0 ) || (b == dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING)) ) command = "COMMIT"; else if (( b != 0 ) && (b != dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING) ) @@ -1666,7 +1668,22 @@ uint32_t doUpdateDelete(THD *thd) thd->get_stmt_da()->set_overwrite_status(true); //cout << " error status " << ci->rc << endl; } - else + if (b == dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING) + { + if (thd->is_strict_mode()) + { + thd->set_row_count_func(0); + ci->rc = b; + // Turn this on as MariaDB doesn't do it until the next phase + thd->abort_on_warning= thd->is_strict_mode(); + } + else + { + thd->set_row_count_func(dmlRowCount); + } + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, errorMsg.c_str()); + } + else { // if (dmlRowCount != 0) //Bug 5117. Handling self join. thd->set_row_count_func(dmlRowCount); @@ -1674,11 +1691,6 @@ uint32_t doUpdateDelete(THD *thd) //cout << " error status " << ci->rc << " and rowcount = " << dmlRowCount << endl; } - if ( b == dmlpackageprocessor::DMLPackageProcessor::IDBRANGE_WARNING ) - { - //string errmsg ("Out of range value detected. Please check Calpont Syntax Guide for supported data range." ); - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 9999, errorMsg.c_str()); - } // @bug 4027. comment out the following because this will cause mysql // kernel assertion failure. not sure why this is here in the first place. diff --git a/writeengine/server/we_dmlcommandproc.cpp b/writeengine/server/we_dmlcommandproc.cpp index d5337248a..0afb5f342 100644 --- a/writeengine/server/we_dmlcommandproc.cpp +++ b/writeengine/server/we_dmlcommandproc.cpp @@ -654,6 +654,14 @@ uint8_t WE_DMLCommandProc::processSingleInsert(messageqcpp::ByteStream& bs, std: } args.add(cols); err = IDBErrorInfo::instance()->errorMsg(WARN_DATA_TRUNC,args); + // Strict mode enabled, so rollback on warning + if (insertPkg.get_isWarnToError()) + { + string applName ("SingleInsert"); + fWEWrapper.bulkRollback(tblOid,txnid.id,tableName.toString(), + applName, false, err); + BulkRollbackMgr::deleteMetaFile( tblOid ); + } } return rc; @@ -1243,7 +1251,15 @@ End-Disable use of MetaFile for bulk rollback support } args.add(cols); err = IDBErrorInfo::instance()->errorMsg(WARN_DATA_TRUNC,args); - + + // Strict mode enabled, so rollback on warning + if (insertPkg.get_isWarnToError()) + { + string applName ("BatchInsert"); + fWEWrapper.bulkRollback(tblOid,txnid.id,tableName.toString(), + applName, false, err); + BulkRollbackMgr::deleteMetaFile( tblOid ); + } } //cout << "Batch insert return code " << rc << endl; return rc;