Code_query_filter.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_query_filter.hpp"
  14. #include "Code_query_join.hpp"
  15. #include "Code_query_scan.hpp"
  16. #include "Code_root.hpp"
  17. // Plan_query_filter
  18. Plan_query_filter::~Plan_query_filter()
  19. {
  20. }
  21. Plan_base*
  22. Plan_query_filter::analyze(Ctx& ctx, Ctl& ctl)
  23. {
  24.     ctx_assert(m_query != 0);
  25.     m_query->analyze(ctx, ctl);
  26.     if (! ctx.ok())
  27. return 0;
  28.     ctx_assert(m_pred != 0);
  29.     m_pred->analyze(ctx, ctl);
  30.     if (! ctx.ok())
  31. return 0;
  32.     return this;
  33. }
  34. Exec_base*
  35. Plan_query_filter::codegen(Ctx& ctx, Ctl& ctl)
  36. {
  37.     // generate code for the subquery
  38.     ctx_assert(m_query != 0);
  39.     Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
  40.     if (! ctx.ok())
  41. return 0;
  42.     ctx_assert(execQuery != 0);
  43.     // create code for the predicate based on query code
  44.     Exec_pred* execPred = 0;
  45.     ctl.m_execQuery = execQuery;
  46.     ctx_assert(m_topTable != 0);
  47.     ctl.m_topTable = m_topTable;
  48.     ctx_assert(m_pred != 0);
  49.     execPred = static_cast<Exec_pred*>(m_pred->codegen(ctx, ctl));
  50.     if (! ctx.ok())
  51. return 0;
  52.     ctx_assert(execPred != 0);
  53.     ctl.m_topTable = 0;
  54.     // re-use SqlSpecs from subquery
  55.     const Exec_query::Code& codeQuery = execQuery->getCode();
  56.     const SqlSpecs& sqlSpecs = codeQuery.sqlSpecs();
  57.     Exec_query_filter* exec = new Exec_query_filter(ctl.m_execRoot);
  58.     ctl.m_execRoot->saveNode(exec);
  59.     Exec_query_filter::Code& code = *new Exec_query_filter::Code(sqlSpecs);
  60.     exec->setCode(code);
  61.     exec->setQuery(execQuery);
  62.     exec->setPred(execPred);
  63.     return exec;
  64. }
  65. void
  66. Plan_query_filter::print(Ctx& ctx)
  67. {
  68.     ctx.print(" [query_filter");
  69.     Plan_base* a[] = { m_query, m_pred };
  70.     printList(ctx, a, 2);
  71.     ctx.print("]");
  72. }
  73. // Exec_query_filter
  74. Exec_query_filter::Code::~Code()
  75. {
  76. }
  77. Exec_query_filter::Data::~Data()
  78. {
  79. }
  80. Exec_query_filter::~Exec_query_filter()
  81. {
  82. }
  83. void
  84. Exec_query_filter::alloc(Ctx& ctx, Ctl& ctl)
  85. {
  86.     // allocate the subquery
  87.     ctx_assert(m_query != 0);
  88.     m_query->alloc(ctx, ctl);
  89.     if (! ctx.ok())
  90. return;
  91.     // allocate the predicate
  92.     ctl.m_query = m_query;
  93.     ctx_assert(m_pred != 0);
  94.     m_pred->alloc(ctx, ctl);
  95.     if (! ctx.ok())
  96. return;
  97.     // re-use SqlRow from subquery
  98.     Exec_query::Data& dataQuery = m_query->getData();
  99.     Data& data = *new Data(this, dataQuery.sqlRow());
  100.     setData(data);
  101. }
  102. void
  103. Exec_query_filter::execImpl(Ctx& ctx, Ctl& ctl)
  104. {
  105.     // execute subquery
  106.     ctx_assert(m_query != 0);
  107.     m_query->execute(ctx, ctl);
  108. }
  109. bool
  110. Exec_query_filter::fetchImpl(Ctx& ctx, Ctl& ctl)
  111. {
  112.     // invoke fetch on subquery until predicate is true
  113.     ctx_assert(m_query != 0);
  114.     while (m_query->fetch(ctx, ctl)) {
  115. ctx_assert(m_pred != 0);
  116. m_pred->evaluate(ctx, ctl);
  117. if (! ctx.ok())
  118.     return false;
  119. if (m_pred->getData().getValue() == Pred_value_true) {
  120.     ctl.m_postEval = true;
  121.     m_pred->evaluate(ctx, ctl);
  122.     ctl.m_postEval = false;
  123.     return true;
  124. }
  125.     }
  126.     return false;
  127. }
  128. void
  129. Exec_query_filter::close(Ctx& ctx)
  130. {
  131.     ctx_assert(m_query != 0);
  132.     m_query->close(ctx);
  133.     ctx_assert(m_pred != 0);
  134.     m_pred->close(ctx);
  135. }
  136. void
  137. Exec_query_filter::print(Ctx& ctx)
  138. {
  139.     ctx.print(" [query_filter");
  140.     Exec_base* a[] = { m_query, m_pred };
  141.     printList(ctx, a, 2);
  142.     ctx.print("]");
  143. }