Code_expr_row.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 <common/DataType.hpp>
  14. #include "Code_expr_row.hpp"
  15. #include "Code_expr.hpp"
  16. #include "Code_expr_conv.hpp"
  17. #include "Code_dml_row.hpp"
  18. #include "Code_root.hpp"
  19. // Plan_expr_row
  20. Plan_expr_row::~Plan_expr_row()
  21. {
  22. }
  23. Plan_base*
  24. Plan_expr_row::analyze(Ctx& ctx, Ctl& ctl)
  25. {
  26.     unsigned size = getSize();
  27.     // analyze subexpressions
  28.     m_anyAggr = false;
  29.     m_allBound = true;
  30.     for (unsigned i = 1; i <= size; i++) {
  31. Plan_expr* expr1 = getExpr(i);
  32. Plan_expr* expr2 = static_cast<Plan_expr*>(expr1->analyze(ctx, ctl));
  33. if (! ctx.ok())
  34.     return 0;
  35. setExpr(i, expr2);
  36. if (expr2->isAggr())
  37.     m_anyAggr = true;
  38. if (! expr2->isBound())
  39.     m_allBound = false;
  40.     }
  41.     // insert conversions if requested  XXX ugly hack
  42.     if (ctl.m_dmlRow != 0) {
  43. if (ctl.m_dmlRow->getSize() > getSize()) {
  44.     ctx.pushStatus(Sqlstate::_21S01, Error::Gen, "not enough values (%u > %u)", ctl.m_dmlRow->getSize(), getSize());
  45.     return 0;
  46. }
  47. if (ctl.m_dmlRow->getSize() < getSize()) {
  48.     ctx.pushStatus(Sqlstate::_21S01, Error::Gen, "too many values (%u < %u)", ctl.m_dmlRow->getSize(), getSize());
  49.     return 0;
  50. }
  51. for (unsigned i = 1; i <= size; i++) {
  52.     const SqlType& sqlType = ctl.m_dmlRow->getColumn(i)->sqlType();
  53.     Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, sqlType);
  54.     m_root->saveNode(exprConv);
  55.     exprConv->setExpr(getExpr(i));
  56.     Plan_expr* expr = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
  57.     if (! ctx.ok())
  58. return 0;
  59.     ctx_assert(expr != 0);
  60.     setExpr(i, expr);
  61. }
  62.     }
  63.     // set aliases
  64.     m_aliasList.resize(1 + size);
  65.     for (unsigned i = 1; i <= size; i++) {
  66. if (m_aliasList[i].empty()) {
  67.     setAlias(i, getExpr(i)->getAlias());
  68. }
  69.     }
  70.     // node was not replaced
  71.     return this;
  72. }
  73. Exec_base*
  74. Plan_expr_row::codegen(Ctx& ctx, Ctl& ctl)
  75. {
  76.     unsigned size = getSize();
  77.     Exec_expr_row* exec = new Exec_expr_row(ctl.m_execRoot, size);
  78.     ctl.m_execRoot->saveNode(exec);
  79.     SqlSpecs sqlSpecs(size);
  80.     // create code for subexpressions
  81.     for (unsigned i = 1; i <= size; i++) {
  82. Plan_expr* planExpr = getExpr(i);
  83. Exec_expr* execExpr = static_cast<Exec_expr*>(planExpr->codegen(ctx, ctl));
  84. if (! ctx.ok())
  85.     return 0;
  86. ctx_assert(execExpr != 0);
  87. exec->setExpr(i, execExpr);
  88. const SqlSpec sqlSpec(execExpr->getCode().sqlSpec(), SqlSpec::Reference);
  89. sqlSpecs.setEntry(i, sqlSpec);
  90.     }
  91.     // create alias list
  92.     Exec_expr_row::Code::Alias* aliasList = new Exec_expr_row::Code::Alias[1 + size];
  93.     strcpy(aliasList[0], "?");
  94.     for (unsigned i = 1; i <= size; i++) {
  95. const char* s = m_aliasList[i].c_str();
  96. if (strlen(s) == 0)
  97.     s = getExpr(i)->getAlias().c_str();
  98. unsigned n = strlen(s);
  99. if (n >= sizeof(Exec_expr_row::Code::Alias))
  100.     n = sizeof(Exec_expr_row::Code::Alias) - 1;
  101. strncpy(aliasList[i], s, n);
  102. aliasList[i][n] = 0;
  103.     }
  104.     // create the code
  105.     Exec_expr_row::Code& code = *new Exec_expr_row::Code(sqlSpecs, aliasList);
  106.     exec->setCode(code);
  107.     return exec;
  108. }
  109. void
  110. Plan_expr_row::print(Ctx& ctx)
  111. {
  112.     const unsigned size = getSize();
  113.     ctx.print(" [expr_row");
  114.     for (unsigned i = 1; i <= size; i++) {
  115. Plan_base* a = m_exprList[i];
  116. a == 0 ?  ctx.print(" -") : a->print(ctx);
  117.     }
  118.     ctx.print("]");
  119. }
  120. bool
  121. Plan_expr_row::isAllGroupBy(const Plan_expr_row* row) const
  122. {
  123.     const unsigned size = getSize();
  124.     for (unsigned i = 1; i <= size; i++) {
  125. if (! getExpr(i)->isGroupBy(row))
  126.     return false;
  127.     }
  128.     return true;
  129. }
  130. // Exec_expr_row
  131. Exec_expr_row::Code::~Code()
  132. {
  133.     delete[] m_aliasList;
  134. }
  135. Exec_expr_row::Data::~Data()
  136. {
  137. }
  138. Exec_expr_row::~Exec_expr_row()
  139. {
  140.     delete[] m_expr;
  141. }
  142. void
  143. Exec_expr_row::alloc(Ctx& ctx, Ctl& ctl)
  144. {
  145.     // allocate subexpressions
  146.     for (unsigned i = 1; i <= m_size; i++) {
  147. getExpr(i)->alloc(ctx, ctl);
  148.     }
  149.     // construct SqlRow of references
  150.     const Code& code = getCode();
  151.     SqlRow sqlRow(getCode().m_sqlSpecs);
  152.     for (unsigned i = 1; i <= m_size; i++) {
  153. const Exec_expr::Data& dataExpr = getExpr(i)->getData();
  154. const SqlSpec& sqlSpec = code.m_sqlSpecs.getEntry(i);
  155. const SqlField sqlField(sqlSpec, &dataExpr.sqlField());
  156. sqlRow.setEntry(i, sqlField);
  157.     }
  158.     // create the data
  159.     Data& data = *new Data(sqlRow);
  160.     setData(data);
  161. }
  162. void
  163. Exec_expr_row::evaluate(Ctx& ctx, Ctl& ctl)
  164. {
  165.     for (unsigned i = 1; i <= m_size; i++) {
  166. getExpr(i)->evaluate(ctx, ctl);
  167. if (! ctx.ok())
  168.     return;
  169.     }
  170. }
  171. void
  172. Exec_expr_row::close(Ctx& ctx)
  173. {
  174.     for (unsigned i = 1; i <= m_size; i++) {
  175. getExpr(i)->close(ctx);
  176.     }
  177. }
  178. void
  179. Exec_expr_row::print(Ctx& ctx)
  180. {
  181.     ctx.print(" [expr_row");
  182.     for (unsigned i = 1; i <= m_size; i++) {
  183. getExpr(i)->print(ctx);
  184.     }
  185.     ctx.print("]");
  186. }