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

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 "Code_root.hpp"
  15. #include "Code_stmt.hpp"
  16. #include "Code_query.hpp"
  17. #include "Code_expr_param.hpp"
  18. #include "Code_root.hpp"
  19. // Plan_root
  20. Plan_root::~Plan_root()
  21. {
  22. }
  23. Plan_base*
  24. Plan_root::analyze(Ctx& ctx, Ctl& ctl)
  25. {
  26.     // analyze statement
  27.     ctx_assert(m_stmt != 0);
  28.     m_stmt = static_cast<Plan_stmt*>(m_stmt->analyze(ctx, ctl));
  29.     if (! ctx.ok())
  30. return 0;
  31.     ctx_assert(m_stmt != 0);
  32.     // analyze parameters
  33.     ctx_assert(m_paramList.size() > 0);
  34.     const unsigned paramCount = m_paramList.size() - 1;
  35.     DescArea& ipd = descArea(Desc_usage_IPD);
  36.     ipd.setCount(ctx, paramCount);
  37.     for (unsigned i = 1; i <= paramCount; i++) {
  38. Plan_expr_param* param = m_paramList[i];
  39. ctx_assert(param != 0);
  40. // analyze the parameter
  41. param->analyze(ctx, ctl);
  42. if (! ctx.ok())
  43.     return 0;
  44.     }
  45.     // must return self
  46.     return this;
  47. }
  48. void
  49. Plan_root::describe(Ctx& ctx)
  50. {
  51.     // describe statement
  52.     ctx_assert(m_stmt != 0);
  53.     m_stmt->describe(ctx);
  54.     // describe parameters
  55.     ctx_assert(m_paramList.size() > 0);
  56.     const unsigned paramCount = m_paramList.size() - 1;
  57.     DescArea& ipd = descArea(Desc_usage_IPD);
  58.     ipd.setCount(ctx, paramCount);
  59.     unsigned unbound = 0;
  60.     for (unsigned i = 1; i <= paramCount; i++) {
  61. Plan_expr_param* param = m_paramList[i];
  62. ctx_assert(param != 0);
  63. // describe the parameter
  64. param->describe(ctx);
  65. // check if SQL type is bound
  66. ctx_assert(param->sqlType().type() != SqlType::Undef);
  67. if (param->sqlType().type() == SqlType::Unbound)
  68.     unbound++;
  69.     }
  70.     if (unbound > 0)
  71. ctx_log2(("%u out of %u params have unbound SQL type", unbound, paramCount));
  72.     m_stmtArea.m_unbound = unbound;
  73. }
  74. Exec_base*
  75. Plan_root::codegen(Ctx& ctx, Ctl& ctl)
  76. {
  77.     Exec_root* execRoot = new Exec_root(m_stmtArea);
  78.     Exec_root::Code& code = *new Exec_root::Code;
  79.     execRoot->setCode(code);
  80.     // set root in helper struct
  81.     ctl.m_execRoot = execRoot;
  82.     // generate code for the statement
  83.     ctx_assert(m_stmt != 0);
  84.     Exec_stmt* execStmt = static_cast<Exec_stmt*>(m_stmt->codegen(ctx, ctl));
  85.     if (! ctx.ok())
  86. return 0;
  87.     execRoot->setStmt(execStmt);
  88.     // create parameters list
  89.     execRoot->m_paramList.resize(m_paramList.size());
  90.     for (unsigned i = 1; i < m_paramList.size(); i++) {
  91. Plan_expr_param* param = m_paramList[i];
  92. ctx_assert(param != 0);
  93. Exec_expr_param* execParam = static_cast<Exec_expr_param*>(param->codegen(ctx, ctl));
  94. ctx_assert(execParam != 0);
  95. execRoot->m_paramList[i] = execParam;
  96.     }
  97.     return execRoot;
  98. }
  99. void
  100. Plan_root::print(Ctx& ctx)
  101. {
  102.     ctx.print("[root");
  103.     Plan_base* a[] = { m_stmt };
  104.     printList(ctx, a, 1);
  105.     ctx.print("]n");
  106. }
  107. void
  108. Plan_root::saveNode(Plan_base* node)
  109. {
  110.     ctx_assert(node != 0);
  111.     m_nodeList.push_back(node);
  112. }
  113. void
  114. Plan_root::freeNodeList()
  115. {
  116.     for (NodeList::iterator i = m_nodeList.begin(); i != m_nodeList.end(); i++) {
  117. Plan_base* node = *i;
  118. *i = 0;
  119. delete node;
  120.     }
  121.     m_nodeList.clear();
  122. }
  123. // Exec_root
  124. Exec_root::Code::~Code()
  125. {
  126. }
  127. Exec_root::Data::~Data()
  128. {
  129. }
  130. Exec_root::~Exec_root()
  131. {
  132. }
  133. StmtArea&
  134. Exec_root::stmtArea() const
  135. {
  136.     return m_stmtArea;
  137. }
  138. void
  139. Exec_root::alloc(Ctx& ctx, Ctl& ctl)
  140. {
  141.     ctx_assert(m_stmt != 0);
  142.     m_stmt->alloc(ctx, ctl);
  143. }
  144. void
  145. Exec_root::bind(Ctx& ctx)
  146. {
  147.     // bind output cols
  148.     ctx_assert(m_stmt != 0);
  149.     m_stmt->bind(ctx);
  150.     // bind input params
  151.     for (unsigned i = 1; i < m_paramList.size(); i++) {
  152. Exec_expr_param* param = m_paramList[i];
  153. ctx_assert(param != 0);
  154. param->bind(ctx);
  155. if (! ctx.ok())
  156.     return;
  157.     }
  158. }
  159. void
  160. Exec_root::execute(Ctx& ctx, Ctl& ctl)
  161. {
  162.     ctx_assert(m_stmt != 0);
  163.     // check if data is needed
  164.     for (unsigned i = 1; i < m_paramList.size(); i++) {
  165. Exec_expr_param* param = m_paramList[i];
  166. ctx_assert(param != 0);
  167. Exec_expr_param::Data& paramData = param->getData();
  168. if (paramData.m_atExec && paramData.m_extPos == -1) {
  169.     ctx.setCode(SQL_NEED_DATA);
  170.     return;
  171. }
  172.     }
  173.     m_stmt->execute(ctx, ctl);
  174. }
  175. void
  176. Exec_root::fetch(Ctx& ctx, Ctl& ctl)
  177. {
  178.     ctx_assert(m_stmt != 0);
  179.     Exec_query* query = static_cast<Exec_query*>(m_stmt);
  180.     ctx_assert(query != 0);
  181.     query->fetch(ctx, ctl);
  182. }
  183. void
  184. Exec_root::close(Ctx& ctx)
  185. {
  186.     ctx_assert(m_stmt != 0);
  187.     m_stmt->close(ctx);
  188.     for (unsigned i = 1; i < m_paramList.size(); i++) {
  189. Exec_expr_param* param = m_paramList[i];
  190. ctx_assert(param != 0);
  191. param->close(ctx);
  192.     }
  193. }
  194. void
  195. Exec_root::print(Ctx& ctx)
  196. {
  197.     ctx.print("[root");
  198.     Exec_base* a[] = { m_stmt };
  199.     printList(ctx, a, sizeof(a)/sizeof(a[0]));
  200.     ctx.print("]n");
  201. }
  202. void
  203. Exec_root::saveNode(Exec_base* node)
  204. {
  205.     ctx_assert(node != 0);
  206.     m_nodeList.push_back(node);
  207. }
  208. void
  209. Exec_root::freeNodeList()
  210. {
  211.     for (NodeList::iterator i = m_nodeList.begin(); i != m_nodeList.end(); i++) {
  212. Exec_base* node = *i;
  213. *i = 0;
  214. delete node;
  215.     }
  216.     m_nodeList.clear();
  217. }
  218. // odbc support
  219. void
  220. Exec_root::sqlGetData(Ctx& ctx, SQLUSMALLINT columnNumber, SQLSMALLINT targetType, SQLPOINTER targetValue, SQLINTEGER bufferLength, SQLINTEGER* strlen_or_Ind)
  221. {
  222.     ctx_assert(m_stmt != 0);
  223.     Exec_query* query = static_cast<Exec_query*>(m_stmt);
  224.     ctx_assert(query != 0);
  225.     query->sqlGetData(ctx, columnNumber, targetType, targetValue, bufferLength, strlen_or_Ind);
  226. }
  227. void
  228. Exec_root::sqlParamData(Ctx& ctx, SQLPOINTER* value)
  229. {
  230.     ctx_assert(m_paramList.size() > 0);
  231.     unsigned count = m_paramList.size() - 1;
  232.     for (unsigned i = 1; i <= count; i++) {
  233. Exec_expr_param* param = m_paramList[i];
  234. ctx_assert(param != 0);
  235. Exec_expr_param::Data& paramData = param->getData();
  236. if (! paramData.m_atExec || paramData.m_extPos >= 0)
  237.     continue;
  238. ctx_assert(paramData.m_extField != 0);
  239. ExtField& extField = *paramData.m_extField;
  240. if (value != 0)
  241.     *value = extField.m_dataPtr;
  242. m_paramData = i;
  243. ctx.setCode(SQL_NEED_DATA);
  244. return;
  245.     }
  246. }
  247. void
  248. Exec_root::sqlPutData(Ctx& ctx, SQLPOINTER data, SQLINTEGER strlen_or_Ind)
  249. {
  250.     ctx_assert(m_paramList.size() > 0);
  251.     unsigned count = m_paramList.size() - 1;
  252.     unsigned i = m_paramData;
  253.     if (i == 0) {
  254. ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "missing call to SQLParamData");
  255. return;
  256.     }
  257.     if (i > count) {
  258. ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "parameter %u out of range 1 to %u", i, count);
  259. return;
  260.     }
  261.     Exec_expr_param* param = m_paramList[i];
  262.     ctx_assert(param != 0);
  263.     Exec_expr_param::Data& paramData = param->getData();
  264.     if (! paramData.m_atExec) {
  265. ctx.pushStatus(Sqlstate::_HY010, Error::Gen, "parameter %u not marked for data-at-exec", i);
  266. return;
  267.     }
  268.     ctx_assert(paramData.m_extField != 0);
  269.     ExtField extField(paramData.m_extField->extSpec(), data, 0, &strlen_or_Ind, i);
  270.     if (paramData.m_extPos == -1)
  271. paramData.m_extPos = 0;
  272.     extField.setPos(paramData.m_extPos);
  273.     // copy in and update position
  274.     SqlField& sqlField = paramData.m_sqlField;
  275.     sqlField.copyin(ctx, extField);
  276.     paramData.m_extPos = extField.getPos();
  277.     ctx_log4(("parameter %u data received", i));
  278. }