diff options
Diffstat (limited to 'storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp')
-rw-r--r-- | storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp b/storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp new file mode 100644 index 00000000000..6be78b62bd9 --- /dev/null +++ b/storage/ndb/src/old_files/client/odbc/codegen/CodeGen.cpp @@ -0,0 +1,229 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <common/StmtArea.hpp> +#include <common/CodeTree.hpp> +#include <executor/Executor.hpp> +#include "CodeGen.hpp" +#include "Code_root.hpp" + +#include <FlexLexer.h> +#include "SimpleParser.hpp" + +void +CodeGen::prepare(Ctx& ctx) +{ + parse(ctx); + if (! ctx.ok()) + return; + analyze(ctx); + if (! ctx.ok()) + return; + describe(ctx); +} + +void +CodeGen::execute(Ctx& ctx) +{ + DescArea& ipd = m_stmtArea.descArea(Desc_usage_IPD); + if (m_stmtArea.m_unbound) { + analyze(ctx); + if (! ctx.ok()) + return; + describe(ctx); + if (! ctx.ok()) + return; + if (m_stmtArea.m_unbound) { + ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "%u input parameters have unbound SQL type", m_stmtArea.m_unbound); + return; + } + ipd.setBound(true); + } + if (! ipd.isBound()) { + ctx_log2(("IPD changed between executes - reanalyze")); + // jdbc can change parameter length at each execute + analyze(ctx); + if (! ctx.ok()) + return; + describe(ctx); + if (! ctx.ok()) + return; + freeExec(ctx); + codegen(ctx); + if (! ctx.ok()) + return; + alloc(ctx); + if (! ctx.ok()) + return; + ipd.setBound(true); + } + if (m_stmtArea.m_execTree == 0) { + codegen(ctx); + if (! ctx.ok()) + return; + alloc(ctx); + if (! ctx.ok()) + return; + } + Executor executor(m_stmtArea); + executor.execute(ctx); +} + +void +CodeGen::fetch(Ctx& ctx) +{ + // XXX parameter types are not checked any more + ctx_assert(! m_stmtArea.m_unbound); + Executor executor(m_stmtArea); + executor.fetch(ctx); +} + +void +CodeGen::parse(Ctx& ctx) +{ + Plan_root* planRoot = new Plan_root(m_stmtArea); + SimpleParser simpleParser(ctx, m_stmtArea, planRoot); + simpleParser.yyparse(); + if (! ctx.ok()) + return; + planRoot->m_paramList.resize(1 + simpleParser.paramNumber()); + ctx_log2(("CodeGen: parse done - plan tree follows")); + if (ctx.logLevel() >= 2) + planRoot->print(ctx); + m_stmtArea.m_planTree = planRoot; +} + +void +CodeGen::analyze(Ctx& ctx) +{ + Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree); + ctx_assert(planRoot != 0); + Plan_base::Ctl ctl(0); + planRoot->analyze(ctx, ctl); // returns itself + if (! ctx.ok()) + return; + ctx_log2(("CodeGen: analyze done - plan tree follows")); + if (ctx.logLevel() >= 2) + planRoot->print(ctx); +} + +void +CodeGen::describe(Ctx& ctx) +{ + Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree); + ctx_assert(planRoot != 0); + planRoot->describe(ctx); + ctx_log2(("CodeGen: describe done")); +} + +void +CodeGen::codegen(Ctx& ctx) +{ + Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree); + ctx_assert(planRoot != 0); + Plan_base::Ctl ctl(0); + Exec_root* execRoot = static_cast<Exec_root*>(planRoot->codegen(ctx, ctl)); + if (! ctx.ok()) + return; + ctx_assert(execRoot != 0); + ctx_log2(("CodeGen: codegen done - code tree follows")); + if (ctx.logLevel() >= 2) + execRoot->print(ctx); + m_stmtArea.m_execTree = execRoot; +} + +void +CodeGen::alloc(Ctx& ctx) +{ + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + ctx_assert(execRoot != 0); + Exec_base::Ctl ctl(0); + execRoot->alloc(ctx, ctl); + if (! ctx.ok()) + return; + ctx_log2(("CodeGen: alloc done")); +} + +void +CodeGen::close(Ctx& ctx) +{ + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + if (execRoot != 0) { + execRoot->close(ctx); + ctx_log2(("CodeGen: close done")); + } +} + +void +CodeGen::free(Ctx& ctx) +{ + freePlan(ctx); + freeExec(ctx); +} + +void +CodeGen::freePlan(Ctx & ctx) +{ + if (m_stmtArea.m_planTree != 0) { + Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree); + ctx_assert(planRoot != 0); + unsigned count = 1 + planRoot->m_nodeList.size(); + planRoot->freeNodeList(); + delete planRoot; + m_stmtArea.m_planTree = 0; + ctx_log3(("CodeGen: freed %u plan tree nodes", count)); + } +} + +void +CodeGen::freeExec(Ctx & ctx) +{ + if (m_stmtArea.m_execTree != 0) { + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + ctx_assert(execRoot != 0); + unsigned count = 1 + execRoot->m_nodeList.size(); + execRoot->freeNodeList(); + delete execRoot; + m_stmtArea.m_execTree = 0; + ctx_log3(("CodeGen: freed %u exec tree nodes", count)); + } +} + +// odbc support + +void +CodeGen::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind) +{ + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + ctx_assert(execRoot != 0); + execRoot->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind); +} + +void +CodeGen::sqlParamData(Ctx& ctx, SQLPOINTER* value) +{ + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + ctx_assert(execRoot != 0); + execRoot->sqlParamData(ctx, value); +} + +void +CodeGen::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind) +{ + Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree); + ctx_assert(execRoot != 0); + execRoot->sqlPutData(ctx, data, strlen_or_Ind); +} |