CodeGen.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <common/StmtArea.hpp>
  14. #include <common/CodeTree.hpp>
  15. #include <executor/Executor.hpp>
  16. #include "CodeGen.hpp"
  17. #include "Code_root.hpp"
  18. #include <FlexLexer.h>
  19. #include "SimpleParser.hpp"
  20. void
  21. CodeGen::prepare(Ctx& ctx)
  22. {
  23.     parse(ctx);
  24.     if (! ctx.ok())
  25. return;
  26.     analyze(ctx);
  27.     if (! ctx.ok())
  28. return;
  29.     describe(ctx);
  30. }
  31. void
  32. CodeGen::execute(Ctx& ctx)
  33. {
  34.     DescArea& ipd = m_stmtArea.descArea(Desc_usage_IPD);
  35.     if (m_stmtArea.m_unbound) {
  36. analyze(ctx);
  37. if (! ctx.ok())
  38.     return;
  39. describe(ctx);
  40. if (! ctx.ok())
  41.     return;
  42. if (m_stmtArea.m_unbound) {
  43.     ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "%u input parameters have unbound SQL type", m_stmtArea.m_unbound);
  44.     return;
  45. }
  46. ipd.setBound(true);
  47.     }
  48.     if (! ipd.isBound()) {
  49. ctx_log2(("IPD changed between executes - reanalyze"));
  50. // jdbc can change parameter length at each execute
  51. analyze(ctx);
  52. if (! ctx.ok())
  53.     return;
  54. describe(ctx);
  55. if (! ctx.ok())
  56.     return;
  57. freeExec(ctx);
  58. codegen(ctx);
  59. if (! ctx.ok())
  60.     return;
  61. alloc(ctx);
  62. if (! ctx.ok())
  63.     return;
  64. ipd.setBound(true);
  65.     }
  66.     if (m_stmtArea.m_execTree == 0) {
  67. codegen(ctx);
  68. if (! ctx.ok())
  69.     return;
  70. alloc(ctx);
  71. if (! ctx.ok())
  72.     return;
  73.     }
  74.     Executor executor(m_stmtArea);
  75.     executor.execute(ctx);
  76. }
  77. void
  78. CodeGen::fetch(Ctx& ctx)
  79. {
  80.     // XXX parameter types are not checked any more
  81.     ctx_assert(! m_stmtArea.m_unbound);
  82.     Executor executor(m_stmtArea);
  83.     executor.fetch(ctx);
  84. }
  85. void
  86. CodeGen::parse(Ctx& ctx)
  87. {
  88.     Plan_root* planRoot = new Plan_root(m_stmtArea);
  89.     SimpleParser simpleParser(ctx, m_stmtArea, planRoot);
  90.     simpleParser.yyparse();
  91.     if (! ctx.ok())
  92. return;
  93.     planRoot->m_paramList.resize(1 + simpleParser.paramNumber());
  94.     ctx_log2(("CodeGen: parse done - plan tree follows"));
  95.     if (ctx.logLevel() >= 2)
  96. planRoot->print(ctx);
  97.     m_stmtArea.m_planTree = planRoot;
  98. }
  99. void
  100. CodeGen::analyze(Ctx& ctx)
  101. {
  102.     Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
  103.     ctx_assert(planRoot != 0);
  104.     Plan_base::Ctl ctl(0);
  105.     planRoot->analyze(ctx, ctl); // returns itself
  106.     if (! ctx.ok())
  107. return;
  108.     ctx_log2(("CodeGen: analyze done - plan tree follows"));
  109.     if (ctx.logLevel() >= 2)
  110. planRoot->print(ctx);
  111. }
  112. void
  113. CodeGen::describe(Ctx& ctx)
  114. {
  115.     Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
  116.     ctx_assert(planRoot != 0);
  117.     planRoot->describe(ctx);
  118.     ctx_log2(("CodeGen: describe done"));
  119. }
  120. void
  121. CodeGen::codegen(Ctx& ctx)
  122. {
  123.     Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
  124.     ctx_assert(planRoot != 0);
  125.     Plan_base::Ctl ctl(0);
  126.     Exec_root* execRoot = static_cast<Exec_root*>(planRoot->codegen(ctx, ctl));
  127.     if (! ctx.ok())
  128. return;
  129.     ctx_assert(execRoot != 0);
  130.     ctx_log2(("CodeGen: codegen done - code tree follows"));
  131.     if (ctx.logLevel() >= 2)
  132. execRoot->print(ctx);
  133.     m_stmtArea.m_execTree = execRoot;
  134. }
  135. void
  136. CodeGen::alloc(Ctx& ctx)
  137. {
  138.     Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  139.     ctx_assert(execRoot != 0);
  140.     Exec_base::Ctl ctl(0);
  141.     execRoot->alloc(ctx, ctl);
  142.     if (! ctx.ok())
  143. return;
  144.     ctx_log2(("CodeGen: alloc done"));
  145. }
  146. void
  147. CodeGen::close(Ctx& ctx)
  148. {
  149.     Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  150.     if (execRoot != 0) {
  151. execRoot->close(ctx);
  152. ctx_log2(("CodeGen: close done"));
  153.     }
  154. }
  155. void
  156. CodeGen::free(Ctx& ctx)
  157. {
  158.     freePlan(ctx);
  159.     freeExec(ctx);
  160. }
  161. void
  162. CodeGen::freePlan(Ctx & ctx)
  163. {
  164.     if (m_stmtArea.m_planTree != 0) {
  165. Plan_root* planRoot = static_cast<Plan_root*>(m_stmtArea.m_planTree);
  166. ctx_assert(planRoot != 0);
  167. unsigned count = 1 + planRoot->m_nodeList.size();
  168. planRoot->freeNodeList();
  169. delete planRoot;
  170. m_stmtArea.m_planTree = 0;
  171. ctx_log3(("CodeGen: freed %u plan tree nodes", count));
  172.     }
  173. }
  174. void
  175. CodeGen::freeExec(Ctx & ctx)
  176. {
  177.     if (m_stmtArea.m_execTree != 0) {
  178. Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  179. ctx_assert(execRoot != 0);
  180. unsigned count = 1 + execRoot->m_nodeList.size();
  181. execRoot->freeNodeList();
  182. delete execRoot;
  183. m_stmtArea.m_execTree = 0;
  184. ctx_log3(("CodeGen: freed %u exec tree nodes", count));
  185.     }
  186. }
  187. // odbc support
  188. void
  189. CodeGen::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
  190. {
  191.     Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  192.     ctx_assert(execRoot != 0);
  193.     execRoot->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind);
  194. }
  195. void
  196. CodeGen::sqlParamData(Ctx& ctx, SQLPOINTER* value)
  197. {
  198.     Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  199.     ctx_assert(execRoot != 0);
  200.     execRoot->sqlParamData(ctx, value);
  201. }
  202. void
  203. CodeGen::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind)
  204. {
  205.     Exec_root* execRoot = static_cast<Exec_root*>(m_stmtArea.m_execTree);
  206.     ctx_assert(execRoot != 0);
  207.     execRoot->sqlPutData(ctx, data, strlen_or_Ind);
  208. }