Code_query_distinct.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 <algorithm>
  14. #include "Code_query_distinct.hpp"
  15. #include "Code_root.hpp"
  16. // Plan_query_distinct
  17. Plan_query_distinct::~Plan_query_distinct()
  18. {
  19. }
  20. Plan_expr_row*
  21. Plan_query_distinct::getRow()
  22. {
  23.     ctx_assert(m_query != 0);
  24.     return m_query->getRow();
  25. }
  26. Plan_base*
  27. Plan_query_distinct::analyze(Ctx& ctx, Ctl& ctl)
  28. {
  29.     ctx_assert(m_query != 0);
  30.     m_query->analyze(ctx, ctl);
  31.     if (! ctx.ok())
  32. return 0;
  33.     return this;
  34. }
  35. Exec_base*
  36. Plan_query_distinct::codegen(Ctx& ctx, Ctl& ctl)
  37. {
  38.     // create code for the subquery
  39.     ctx_assert(m_query != 0);
  40.     Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
  41.     if (! ctx.ok())
  42. return 0;
  43.     ctx_assert(execQuery != 0);
  44.     // the exec node
  45.     Exec_query_distinct* exec = new Exec_query_distinct(ctl.m_execRoot);
  46.     ctl.m_execRoot->saveNode(exec);
  47.     // re-use SqlSpecs from subquery
  48.     const Exec_query::Code& codeQuery = execQuery->getCode();
  49.     const SqlSpecs& sqlSpecs = codeQuery.sqlSpecs();
  50.     Exec_query_distinct::Code& code = *new Exec_query_distinct::Code(sqlSpecs);
  51.     exec->setCode(code);
  52.     exec->setQuery(execQuery);
  53.     return exec;
  54. }
  55. void
  56. Plan_query_distinct::print(Ctx& ctx)
  57. {
  58.     ctx.print(" [query_distinct");
  59.     Plan_base* a[] = { m_query };
  60.     printList(ctx, a, 1);
  61.     ctx.print("]");
  62. }
  63. // Exec_query_distinct
  64. Exec_query_distinct::Code::~Code()
  65. {
  66. }
  67. Exec_query_distinct::Data::~Data()
  68. {
  69.     for (DistinctList::iterator i = m_groupList.begin(); i != m_groupList.end(); i++) {
  70. delete (*i).first;
  71.     }
  72. }
  73. Exec_query_distinct::~Exec_query_distinct()
  74. {
  75. }
  76. const Exec_query*
  77. Exec_query_distinct::getRawQuery() const
  78. {
  79.     ctx_assert(m_query != 0);
  80.     return m_query->getRawQuery();
  81. }
  82. void
  83. Exec_query_distinct::alloc(Ctx& ctx, Ctl& ctl)
  84. {
  85.     // allocate subquery
  86.     ctx_assert(m_query != 0);
  87.     m_query->alloc(ctx, ctl);
  88.     if (! ctx.ok())
  89. return;
  90.     Data& data = *new Data(this, getCode().sqlSpecs());
  91.     setData(data);
  92. }
  93. void
  94. Exec_query_distinct::execImpl(Ctx& ctx, Ctl& ctl)
  95. {
  96.     ctx_assert(m_query != 0);
  97.     m_query->execute(ctx, ctl);
  98. }
  99. bool
  100. DistinctLess::operator()(const SqlRow* s1, const SqlRow* s2) const
  101. {
  102.     ctx_assert(s1 != 0 && s2 != 0);
  103.     const SqlRow& r1 = *s1;
  104.     const SqlRow& r2 = *s2;
  105.     for (unsigned i = 1; i <= r1.count(); i++) {
  106. const SqlField& f1 = r1.getEntry(i);
  107. const SqlField& f2 = r2.getEntry(i);
  108. // nulls last is default in oracle
  109. const bool f1null = f1.sqlNull();
  110. const bool f2null = f2.sqlNull();
  111. if (f1null && f2null)
  112.     continue;
  113. if (! f1null && f2null)
  114.     return true;
  115. if (f1null && ! f2null)
  116.     return false;
  117. if (f1.less(f2))
  118.     return true;
  119. if (f2.less(f1))
  120.     return false;
  121.     }
  122.     return false;
  123. }
  124. bool
  125. Exec_query_distinct::fetchImpl(Ctx& ctx, Ctl& ctl)
  126. {
  127.     Data& data = getData();
  128.     ctx_assert(m_query != 0);
  129.     if (! data.m_grouped) {
  130. // read and group all rows
  131. while (m_query->fetch(ctx, ctl)) {
  132.     const SqlRow* dataRow = &m_query->getData().sqlRow();
  133.     DistinctList::iterator i = data.m_groupList.find(dataRow);
  134.     if (i != data.m_groupList.end())
  135. continue;
  136.     unsigned index = data.m_count++;
  137.     dataRow = dataRow->copy();
  138.     const DistinctList::value_type groupPair(dataRow, index);
  139.     data.m_groupList.insert(groupPair);
  140.     data.m_groupVector.push_back(dataRow);
  141. }
  142. if (! ctx.ok())
  143.     return false;
  144. data.m_index = 0;
  145. data.m_grouped = true;
  146.     }
  147.     ctx_assert(data.m_count == data.m_groupVector.size());
  148.     if (data.m_index < data.m_count) {
  149. const SqlRow* currRow = data.m_groupVector[data.m_index];
  150. // make our SqlRow reference to it
  151. for (unsigned i = 1; i <= data.m_sqlRow.count(); i++) {
  152.     const SqlField& currField = currRow->getEntry(i);
  153.     SqlSpec sqlSpec(currField.sqlSpec(), SqlSpec::Reference);
  154.     SqlField sqlField(sqlSpec, &currField);
  155.     data.m_sqlRow.setEntry(i, sqlField);
  156. }
  157. data.m_index++;
  158. return true;
  159.     }
  160.     return false;
  161. }
  162. void
  163. Exec_query_distinct::close(Ctx& ctx)
  164. {
  165.     Data& data = getData();
  166.     ctx_assert(m_query != 0);
  167.     m_query->close(ctx);
  168.     data.m_grouped = false;
  169.     data.m_count = 0;
  170.     for (DistinctList::iterator i = data.m_groupList.begin(); i != data.m_groupList.end(); i++) {
  171. delete (*i).first;
  172.     }
  173.     data.m_groupList.clear();
  174.     data.m_groupVector.clear();
  175. }
  176. void
  177. Exec_query_distinct::print(Ctx& ctx)
  178. {
  179.     ctx.print(" [query_distinct");
  180.     Exec_base* a[] = { m_query };
  181.     printList(ctx, a, 1);
  182.     ctx.print("]");
  183. }