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

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 <NdbApi.hpp>
  14. #include <common/StmtArea.hpp>
  15. #include <dictionary/DictTable.hpp>
  16. #include <dictionary/DictColumn.hpp>
  17. #include "Code_query_scan.hpp"
  18. #include "Code_column.hpp"
  19. #include "Code_root.hpp"
  20. // Plan_query_scan
  21. Plan_query_scan::~Plan_query_scan()
  22. {
  23. }
  24. Plan_base*
  25. Plan_query_scan::analyze(Ctx& ctx, Ctl& ctl)
  26. {
  27.     ctx_assert(m_table != 0);
  28.     m_table->analyze(ctx, ctl);
  29.     if (! ctx.ok())
  30. return 0;
  31.     if (m_interp != 0) {
  32. m_interp = static_cast<Plan_pred*>(m_interp->analyze(ctx, ctl));
  33. if (! ctx.ok())
  34.     return 0;
  35. ctx_assert(m_interp != 0);
  36.     }
  37.     return this;
  38. }
  39. Exec_base*
  40. Plan_query_scan::codegen(Ctx& ctx, Ctl& ctl)
  41. {
  42.     // set up
  43.     ctx_assert(m_table != 0);
  44.     const BaseString& tableName = m_table->getName();
  45.     const DictTable& dictTable = m_table->dictTable();
  46.     const ColumnVector& columns = m_table->exprColumns();
  47.     ctx_assert(columns.size() > 0);
  48.     const unsigned attrCount = columns.size() - 1;
  49.     // create the code
  50.     Exec_query_scan::Code& code = *new Exec_query_scan::Code(attrCount);
  51.     code.m_tableName = strcpy(new char[tableName.length() + 1], tableName.c_str());
  52.     code.m_exclusive = m_exclusive;
  53.     // queried attributes
  54.     code.m_attrId = new NdbAttrId[1 + attrCount];
  55.     code.m_attrId[0] = (NdbAttrId)-1;
  56.     for (unsigned i = 1; i <= attrCount; i++) {
  57. Plan_column* column = columns[i];
  58. ctx_assert(column != 0);
  59. const DictColumn& dictColumn = column->dictColumn();
  60. const SqlType& sqlType = dictColumn.sqlType();
  61. SqlSpec sqlSpec(sqlType, SqlSpec::Physical);
  62. code.m_sqlSpecs.setEntry(i, sqlSpec);
  63. code.m_attrId[i] = dictColumn.getAttrId();
  64.     }
  65.     // create the exec
  66.     Exec_query_scan* exec = new Exec_query_scan(ctl.m_execRoot);
  67.     ctl.m_execRoot->saveNode(exec);
  68.     exec->setCode(code);
  69.     // interpreter
  70.     Exec_pred* execInterp = 0;
  71.     ctl.m_execQuery = exec;
  72.     ctl.m_topTable = m_table;
  73.     if (m_interp != 0) {
  74. execInterp = static_cast<Exec_pred*>(m_interp->codegen(ctx, ctl));
  75. if (! ctx.ok())
  76.     return 0;
  77. ctx_assert(execInterp != 0);
  78.     }
  79.     ctl.m_topTable = 0;
  80.     if (m_interp != 0)
  81. exec->setInterp(execInterp);
  82.     return exec;
  83. }
  84. void
  85. Plan_query_scan::print(Ctx& ctx)
  86. {
  87.     ctx.print(" [query_scan");
  88.     Plan_base* a[] = { m_table, m_interp };
  89.     printList(ctx, a, 2);
  90.     ctx.print("]");
  91. }
  92. // Exec_query_scan
  93. Exec_query_scan::Code::~Code()
  94. {
  95.     delete[] m_tableName;
  96.     delete[] m_attrId;
  97. }
  98. Exec_query_scan::Data::~Data()
  99. {
  100.     delete[] m_recAttr;
  101. }
  102. Exec_query_scan::~Exec_query_scan()
  103. {
  104. }
  105. void
  106. Exec_query_scan::alloc(Ctx& ctx, Ctl& ctl)
  107. {
  108.     const Code& code = getCode();
  109.     // create data
  110.     Data& data = *new Data(this, code.sqlSpecs());
  111.     // needed for isNULL
  112.     data.m_recAttr = new NdbRecAttr* [1 + code.m_attrCount];
  113.     for (unsigned i = 0; i <= code.m_attrCount; i++) {
  114. data.m_recAttr[i] = 0;
  115.     }
  116.     data.m_parallel = code.m_exclusive ? 1 : 240; // best supported
  117.     setData(data);
  118.     // interpreter
  119.     ctl.m_query = this;
  120.     if (m_interp != 0) {
  121. //m_interp->alloc(ctx, ctl); XXX
  122. if (! ctx.ok())
  123.     return;
  124.     }
  125. }
  126. void
  127. Exec_query_scan::close(Ctx& ctx)
  128. {
  129.     Data& data = getData();
  130.     if (data.m_con != 0) {
  131. Ndb* const ndb = ndbObject();
  132. int ret = data.m_con->stopScan();
  133. if (ret == -1) {
  134.     ctx.pushStatus(ndb, data.m_con, data.m_op, "stopScan");
  135. }
  136. ndb->closeTransaction(data.m_con);
  137. data.m_con = 0;
  138. data.m_op = 0;
  139. ctx_log2(("scan closed at statement close"));
  140.     }
  141.     if (m_interp != 0)
  142. m_interp->close(ctx);
  143. }
  144. void
  145. Exec_query_scan::print(Ctx& ctx)
  146. {
  147.     ctx.print(" [query_scan");
  148.     if (m_code != 0) {
  149. const Code& code = getCode();
  150. ctx.print(" attrId=");
  151. for (unsigned i = 1; i <= code.m_attrCount; i++) {
  152.     if (i > 1)
  153. ctx.print(",");
  154.     ctx.print("%u", (unsigned)code.m_attrId[i]);
  155. }
  156. ctx.print(" table=%s", code.m_tableName);
  157.     }
  158.     if (m_interp != 0)
  159. m_interp->print(ctx);
  160.     ctx.print("]");
  161. }