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

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 "Code_pred.hpp"
  14. #include "Code_pred_op.hpp"
  15. #include "Code_root.hpp"
  16. // Pred_op
  17. const char*
  18. Pred_op::name() const
  19. {
  20.     switch (m_opcode) {
  21.     case And:
  22. return "and";
  23.     case Or:
  24. return "or";
  25.     case Not:
  26. return "not";
  27.     }
  28.     ctx_assert(false);
  29.     return "";
  30. }
  31. unsigned
  32. Pred_op::arity() const
  33. {
  34.     switch (m_opcode) {
  35.     case And:
  36.     case Or:
  37. return 2;
  38.     case Not:
  39. return 1;
  40.     }
  41.     ctx_assert(false);
  42.     return 0;
  43. }
  44. // Plan_pred_op
  45. Plan_pred_op::~Plan_pred_op()
  46. {
  47. }
  48. Plan_base*
  49. Plan_pred_op::analyze(Ctx& ctx, Ctl& ctl)
  50. {
  51.     m_exec = 0;
  52.     unsigned arity = m_op.arity();
  53.     // check if we remain in top-level AND-clause
  54.     const bool topand = ctl.m_topand;
  55.     if (m_op.m_opcode != Pred_op::And)
  56. ctl.m_topand = false;
  57.     // analyze sub-predicates
  58.     for (unsigned i = 1; i <= arity; i++) {
  59. ctx_assert(m_pred[i] != 0);
  60. m_pred[i]->analyze(ctx, ctl);
  61. if (! ctx.ok())
  62.     return 0;
  63.     }
  64.     // save top level predicate on list
  65.     if (topand && ! ctl.m_topand) {
  66. ctl.m_topcomp.push_back(this);
  67.     }
  68.     ctl.m_topand = topand;
  69.     // table dependencies are union from operands
  70.     m_tableSet.clear();
  71.     for (unsigned i = 1; i <= arity; i++) {
  72. const TableSet& ts = m_pred[i]->tableSet();
  73. m_tableSet.insert(ts.begin(), ts.end());
  74.     }
  75.     // set of tables for which interpreter cannot be used
  76.     m_noInterp.clear();
  77.     for (unsigned i = 1; i <= arity; i++) {
  78. const TableSet& ts = m_pred[i]->noInterp();
  79. m_noInterp.insert(ts.begin(), ts.end());
  80.     }
  81.     return this;
  82. }
  83. Exec_base*
  84. Plan_pred_op::codegen(Ctx& ctx, Ctl& ctl)
  85. {
  86.     if (m_exec != 0)
  87. return m_exec;
  88.     unsigned arity = m_op.arity();
  89.     Exec_pred_op* exec = new Exec_pred_op(ctl.m_execRoot);
  90.     ctl.m_execRoot->saveNode(exec);
  91.     // create code for operands
  92.     for (unsigned i = 1; i <= arity; i++) {
  93. ctx_assert(m_pred[i] != 0);
  94. Exec_pred* execPred = static_cast<Exec_pred*>(m_pred[i]->codegen(ctx, ctl));
  95. if (! ctx.ok())
  96.     return 0;
  97. ctx_assert(execPred != 0);
  98. exec->setPred(i, execPred);
  99.     }
  100.     // create the code
  101.     Exec_pred_op::Code& code = *new Exec_pred_op::Code(m_op);
  102.     exec->setCode(code);
  103.     m_exec = exec;
  104.     return exec;
  105. }
  106. void
  107. Plan_pred_op::print(Ctx& ctx)
  108. {
  109.     ctx.print(" [%s", m_op.name());
  110.     Plan_base* a[] = { m_pred[1], m_pred[2] };
  111.     printList(ctx, a, m_op.arity());
  112.     ctx.print("]");
  113. }
  114. bool
  115. Plan_pred_op::isGroupBy(const Plan_expr_row* row) const
  116. {
  117.     const unsigned arity = m_op.arity();
  118.     for (unsigned i = 1; i <= arity; i++) {
  119. ctx_assert(m_pred[i] != 0);
  120. if (! m_pred[i]->isGroupBy(row))
  121.     return false;
  122.     }
  123.     return true;
  124. }
  125. // Code_pred_op
  126. Exec_pred_op::Code::~Code()
  127. {
  128. }
  129. Exec_pred_op::Data::~Data()
  130. {
  131. }
  132. Exec_pred_op::~Exec_pred_op()
  133. {
  134. }
  135. void
  136. Exec_pred_op::alloc(Ctx& ctx, Ctl& ctl)
  137. {
  138.     const Code& code = getCode();
  139.     // allocate sub-predicates
  140.     unsigned arity = code.m_op.arity();
  141.     for (unsigned i = 1; i <= arity; i++) {
  142. ctx_assert(m_pred[i] != 0);
  143. m_pred[i]->alloc(ctx, ctl);
  144. if (! ctx.ok())
  145.     return;
  146.     }
  147.     Data& data = *new Data;
  148.     setData(data);
  149. }
  150. void
  151. Exec_pred_op::close(Ctx& ctx)
  152. {
  153.     const Code& code = getCode();
  154.     unsigned arity = code.m_op.arity();
  155.     for (unsigned i = 1; i <= arity; i++) {
  156. ctx_assert(m_pred[i] != 0);
  157. m_pred[i]->close(ctx);
  158.     }
  159. }
  160. void
  161. Exec_pred_op::print(Ctx& ctx)
  162. {
  163.     const Code& code = getCode();
  164.     ctx.print(" [%s", code.m_op.name());
  165.     Exec_base* a[] = { m_pred[1], m_pred[2] };
  166.     printList(ctx, a, code.m_op.arity());
  167.     ctx.print("]");
  168. }