From bdb011da973747b1e558cea9993e9da9f6ae8cf9 Mon Sep 17 00:00:00 2001 From: randomdan Date: Mon, 16 Aug 2010 19:15:19 +0000 Subject: Add option to use a temporary view instead of a table to reduce WAL churn during SqlMerge --- project2/sqlMergeTask.cpp | 45 ++++++++++++++++++++++++++++++++++----------- project2/sqlMergeTask.h | 5 +++-- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/project2/sqlMergeTask.cpp b/project2/sqlMergeTask.cpp index 495a689..d59d356 100644 --- a/project2/sqlMergeTask.cpp +++ b/project2/sqlMergeTask.cpp @@ -4,6 +4,7 @@ #include #include #include +#include bool _SqlMergeTask::defaultUseTempTable = true; static void attach(Iterate i, ModifyCommand * insert); @@ -15,6 +16,7 @@ _SqlMergeTask::_SqlMergeTask(const xmlpp::Element * p) : updateWhere(p->get_attribute_value("updatewhere")), patchOrder(p->get_attribute_value("patchorder")), earlyKeys(p->get_attribute_value("earlykeys") == "yes"), + useView(p->get_attribute_value("useview") == "yes"), tempTableCreated(false), insCmd(NULL), destdb(NULL), @@ -25,12 +27,18 @@ _SqlMergeTask::_SqlMergeTask(const xmlpp::Element * p) : Loaders loaders; _Iterate::AddLoaders(loaders, sources); _LoaderBase::collectAll(loaders, "project2", p, true, true); + if (!sources.empty() && useView) { + throw std::runtime_error("useview not supported with iterate fillers"); + } BOOST_FOREACH(xmlpp::Node * psi, p->find("columns/column")) { xmlpp::Element * e = static_cast(psi); TargetColumnPtr tcp(new TargetColumn(e->get_child_text()->get_content())); tcp->maptable = e->get_attribute_value("maptable"); if (!tcp->maptable.empty()) { + if (useView) { + throw std::runtime_error("useview not supported with mapped columns"); + } tcp->mapcolumn = e->get_attribute_value("mapcolumn"); } cols.insert(tcp); @@ -95,16 +103,24 @@ _SqlMergeTask::execute() const void _SqlMergeTask::createTempTable() const { - ModifyCommand(*destdb, stringf( - "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s WHERE 0=1", - dtablet.c_str(), - dtable.c_str())).execute(); - BOOST_FOREACH(Columns::value_type c, cols) { - if (!c->maptable.empty()) { - ModifyCommand(*destdb, stringf( - "ALTER TABLE %s ADD COLUMN %s VARCHAR(1000)", - dtablet.c_str(), - c->mapcolumn.c_str())).execute(); + if (useView) { + ModifyCommand(*destdb, stringf( + "CREATE VIEW %s AS %s", + dtablet.c_str(), + boost::algorithm::join(sqls, " UNION ").c_str())).execute(); + } + else { + ModifyCommand(*destdb, stringf( + "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s WHERE 0=1", + dtablet.c_str(), + dtable.c_str())).execute(); + BOOST_FOREACH(Columns::value_type c, cols) { + if (!c->maptable.empty()) { + ModifyCommand(*destdb, stringf( + "ALTER TABLE %s ADD COLUMN %s VARCHAR(1000)", + dtablet.c_str(), + c->mapcolumn.c_str())).execute(); + } } } tempTableCreated = true; @@ -113,12 +129,18 @@ void _SqlMergeTask::dropTempTable() const { if (tempTableCreated) { - ModifyCommand(*destdb, "DROP TABLE " + dtablet).execute(); + if (useView) { + ModifyCommand(*destdb, "DROP VIEW " + dtablet).execute(); + } + else { + ModifyCommand(*destdb, "DROP TABLE " + dtablet).execute(); + } } } void _SqlMergeTask::createTempKey() const { + if (useView) return; /* Primary key */ Buffer idx; idx.appendf("ALTER TABLE %s ADD CONSTRAINT pk_%s PRIMARY KEY(", @@ -218,6 +240,7 @@ static void attach(Iterate i, ModifyCommand * insert) void _SqlMergeTask::copyToTempTable() const { + if (useView) return; BOOST_FOREACH(const Iterates::value_type & i, sources) { i.second->execute(); } diff --git a/project2/sqlMergeTask.h b/project2/sqlMergeTask.h index 16dcdc7..ce10f70 100644 --- a/project2/sqlMergeTask.h +++ b/project2/sqlMergeTask.h @@ -44,9 +44,10 @@ class _SqlMergeTask : public _Task { Columns cols; Keys keys; Keys indexes; - const Variable updateWhere; + const Variable updateWhere; const std::string patchOrder; - bool earlyKeys; + const bool earlyKeys; + const bool useView; private: virtual void copyToTempTable() const; -- cgit v1.2.3