Code_query_count.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 <common/StmtArea.hpp>
  14. #include <dictionary/DictTable.hpp>
  15. #include <dictionary/DictColumn.hpp>
  16. #include "Code_query_count.hpp"
  17. #include "Code_column.hpp"
  18. #include "Code_expr_row.hpp"
  19. #include "Code_root.hpp"
  20. // Plan_query_count
  21. Plan_query_count::~Plan_query_count()
  22. {
  23. }
  24. Plan_expr_row*
  25. Plan_query_count::getRow()
  26. {
  27.     ctx_assert(m_exprRow != 0);
  28.     return m_exprRow;
  29. }
  30. Plan_base*
  31. Plan_query_count::analyze(Ctx& ctx, Ctl& ctl)
  32. {
  33.     ctx_assert(m_exprRow != 0);
  34.     ctl.m_aggrok = true;
  35.     ctl.m_aggrin = false;
  36.     m_exprRow->analyze(ctx, ctl);
  37.     ctl.m_aggrok = false;
  38.     if (! ctx.ok())
  39. return 0;
  40.     ctx_assert(m_query != 0);
  41.     m_query->analyze(ctx, ctl);
  42.     if (! ctx.ok())
  43. return 0;
  44.     return this;
  45. }
  46. Exec_base*
  47. Plan_query_count::codegen(Ctx& ctx, Ctl& ctl)
  48. {
  49.     // create code for the subquery
  50.     ctx_assert(m_query != 0);
  51.     Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
  52.     if (! ctx.ok())
  53. return 0;
  54.     ctx_assert(execQuery != 0);
  55.     // create code for the row based on query code
  56.     ctx_assert(m_exprRow != 0);
  57.     ctl.m_execQuery = execQuery;
  58.     Exec_expr_row* execRow = static_cast<Exec_expr_row*>(m_exprRow->codegen(ctx, ctl));
  59.     if (! ctx.ok())
  60. return 0;
  61.     ctx_assert(execRow != 0);
  62.     Exec_query_count* exec = new Exec_query_count(ctl.m_execRoot);
  63.     ctl.m_execRoot->saveNode(exec);
  64.     // re-use SqlSpecs from the row
  65.     const SqlSpecs& sqlSpecs = execRow->getCode().sqlSpecs();
  66.     Exec_query_count::Code& code = *new Exec_query_count::Code(sqlSpecs);
  67.     exec->setCode(code);
  68.     exec->setQuery(execQuery);
  69.     exec->setRow(execRow);
  70.     return exec;
  71. }
  72. void
  73. Plan_query_count::print(Ctx& ctx)
  74. {
  75.     ctx.print(" [query_count");
  76.     Plan_base* a[] = { m_query, m_exprRow };
  77.     printList(ctx, a, sizeof(a)/sizeof(a[0]));
  78.     ctx.print("]");
  79. }
  80. // Exec_query_count
  81. Exec_query_count::Code::~Code()
  82. {
  83. }
  84. Exec_query_count::Data::~Data()
  85. {
  86. }
  87. Exec_query_count::~Exec_query_count()
  88. {
  89. }
  90. const Exec_query*
  91. Exec_query_count::getRawQuery() const
  92. {
  93.     ctx_assert(m_query != 0);
  94.     return m_query;
  95. }
  96. void
  97. Exec_query_count::alloc(Ctx& ctx, Ctl& ctl)
  98. {
  99.     // allocate the subquery
  100.     ctx_assert(m_query != 0);
  101.     m_query->alloc(ctx, ctl);
  102.     // allocate the row based on subquery data
  103.     ctx_assert(m_exprRow != 0);
  104.     ctl.m_query = m_query;
  105.     m_exprRow->alloc(ctx, ctl);
  106.     if (! ctx.ok())
  107. return;
  108.     // re-use SqlRow from the expression row
  109.     const SqlRow& sqlRow = m_exprRow->getData().sqlRow();
  110.     Data& data = *new Data(this, sqlRow);
  111.     setData(data);
  112. }
  113. void
  114. Exec_query_count::execImpl(Ctx& ctx, Ctl& ctl)
  115. {
  116.     Data& data = getData();
  117.     // zero counters
  118.     ctx_assert(m_exprRow != 0);
  119.     m_exprRow->close(ctx);
  120.     data.m_done = false;
  121.     // execute the subquery
  122.     ctx_assert(m_query != 0);
  123.     m_query->execute(ctx, ctl);
  124. }
  125. bool
  126. Exec_query_count::fetchImpl(Ctx& ctx, Ctl& ctl)
  127. {
  128.     Data& data = getData();
  129.     // returns one row only
  130.     if (data.m_done)
  131. return false;
  132.     ctx_assert(m_query != 0 && m_exprRow != 0);
  133.     while (m_query->fetch(ctx, ctl)) {
  134. // accumulate values
  135. m_exprRow->evaluate(ctx, ctl);
  136. if (! ctx.ok())
  137.     return false;
  138.     }
  139.     data.m_done = true;
  140.     return true;
  141. }
  142. void
  143. Exec_query_count::close(Ctx& ctx)
  144. {
  145.     ctx_assert(m_query != 0);
  146.     m_query->close(ctx);
  147.     ctx_assert(m_exprRow != 0);
  148.     m_exprRow->close(ctx);
  149. }
  150. void
  151. Exec_query_count::print(Ctx& ctx)
  152. {
  153.     ctx.print(" [query_count");
  154.     Exec_base* a[] = { m_query };
  155.     printList(ctx, a, 1);
  156.     ctx.print("]");
  157. }