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

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 <dictionary/DictColumn.hpp>
  14. #include "Code_pred.hpp"
  15. #include "Code_comp_op.hpp"
  16. #include "Code_expr_conv.hpp"
  17. #include "Code_expr_column.hpp"
  18. #include "Code_table.hpp"
  19. #include "Code_root.hpp"
  20. // Comp_op
  21. const char*
  22. Comp_op::name() const
  23. {
  24.     switch (m_opcode) {
  25.     case Eq:
  26. return "=";
  27.     case Noteq:
  28. return "!=";
  29.     case Lt:
  30. return "<";
  31.     case Lteq:
  32. return "<=";
  33.     case Gt:
  34. return ">";
  35.     case Gteq:
  36. return ">=";
  37.     case Like:
  38. return "like";
  39.     case Notlike:
  40. return "not like";
  41.     case Isnull:
  42. return "is null";
  43.     case Isnotnull:
  44. return "is not null";
  45.     }
  46.     ctx_assert(false);
  47.     return "";
  48. }
  49. unsigned
  50. Comp_op::arity() const
  51. {
  52.     switch (m_opcode) {
  53.     case Eq:
  54.     case Noteq:
  55.     case Lt:
  56.     case Lteq:
  57.     case Gt:
  58.     case Gteq:
  59.     case Like:
  60.     case Notlike:
  61. return 2;
  62.     case Isnull:
  63.     case Isnotnull:
  64. return 1;
  65.     }
  66.     ctx_assert(false);
  67.     return 0;
  68. }
  69. // Plan_comp_op
  70. Plan_comp_op::~Plan_comp_op()
  71. {
  72. }
  73. Plan_base*
  74. Plan_comp_op::analyze(Ctx& ctx, Ctl& ctl)
  75. {
  76.     m_exec = 0;
  77.     const unsigned arity = m_op.arity();
  78.     // analyze operands
  79.     for (unsigned i = 1; i <= arity; i++) {
  80. ctx_assert(m_expr[i] != 0);
  81. m_expr[i]->analyze(ctx, ctl);
  82. if (! ctx.ok())
  83.     return 0;
  84.     }
  85.     // for each operand, find type to convert to
  86.     SqlType con[1 + 2];
  87.     if (arity == 1) {
  88. const SqlType& t1 = m_expr[1]->sqlType();
  89. switch (t1.type()) {
  90. case SqlType::Char:
  91. case SqlType::Varchar:
  92. case SqlType::Smallint:
  93. case SqlType::Integer:
  94. case SqlType::Bigint:
  95. case SqlType::Real:
  96. case SqlType::Double:
  97. case SqlType::Datetime:
  98. case SqlType::Null:
  99. case SqlType::Unbound:
  100.     con[1] = t1;
  101.     break;
  102. default:
  103.     break;
  104. }
  105. if (con[1].type() == SqlType::Undef) {
  106.     char b1[40];
  107.     t1.print(b1, sizeof(b1));
  108.     ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s", b1, m_op.name());
  109.     return 0;
  110. }
  111.     } else if (arity == 2) {
  112. const SqlType& t1 = m_expr[1]->sqlType();
  113. const SqlType& t2 = m_expr[2]->sqlType();
  114. switch (t1.type()) {
  115. case SqlType::Char:
  116.     switch (t2.type()) {
  117.     case SqlType::Char:
  118.     case SqlType::Varchar:
  119.     case SqlType::Null:
  120. con[1] = t1;
  121. con[2] = t2;
  122. break;
  123.     case SqlType::Unbound:
  124. con[1] = con[2] = t2;
  125. break;
  126.     default:
  127. break;
  128.     }
  129.     break;
  130. case SqlType::Varchar:
  131.     switch (t2.type()) {
  132.     case SqlType::Char:
  133.     case SqlType::Varchar:
  134.     case SqlType::Null:
  135. con[1] = t1;
  136. con[2] = t2;
  137. break;
  138.     case SqlType::Unbound:
  139. con[1] = con[2] = t2;
  140. break;
  141.     default:
  142. break;
  143.     }
  144.     break;
  145. case SqlType::Smallint:
  146. case SqlType::Integer:
  147. case SqlType::Bigint:
  148.     switch (t2.type()) {
  149.     case SqlType::Smallint:
  150.     case SqlType::Integer:
  151.     case SqlType::Bigint:
  152. // conversion would mask primary key optimization
  153. con[1] = t1;
  154. con[2] = t2;
  155. break;
  156.     case SqlType::Real:
  157.     case SqlType::Double:
  158. con[1].setType(ctx, SqlType::Double);
  159. con[2] = con[1];
  160. break;
  161.     case SqlType::Null:
  162. con[1] = t1;
  163. con[2] = t2;
  164. break;
  165.     case SqlType::Unbound:
  166. con[1] = con[2] = t2;
  167. break;
  168.     default:
  169. break;
  170.     }
  171.     break;
  172. case SqlType::Real:
  173. case SqlType::Double:
  174.     switch (t2.type()) {
  175.     case SqlType::Smallint:
  176.     case SqlType::Integer:
  177.     case SqlType::Bigint:
  178.     case SqlType::Real:
  179.     case SqlType::Double:
  180. con[1].setType(ctx, SqlType::Double);
  181. con[2] = con[1];
  182. break;
  183.     case SqlType::Null:
  184. con[1] = t1;
  185. con[2] = t2;
  186. break;
  187.     case SqlType::Unbound:
  188. con[1] = con[2] = t2;
  189. break;
  190.     default:
  191. break;
  192.     }
  193.     break;
  194. case SqlType::Datetime:
  195.     switch (t2.type()) {
  196.     case SqlType::Datetime:
  197. con[1] = t1;
  198. con[2] = t2;
  199. break;
  200.     case SqlType::Unbound:
  201. con[1] = con[2] = t2;
  202. break;
  203.     default:
  204. break;
  205.     }
  206.     break;
  207. case SqlType::Null:
  208.     switch (t2.type()) {
  209.     case SqlType::Char:
  210.     case SqlType::Varchar:
  211.     case SqlType::Smallint:
  212.     case SqlType::Integer:
  213.     case SqlType::Bigint:
  214.     case SqlType::Real:
  215.     case SqlType::Double:
  216.     case SqlType::Datetime:
  217. con[1] = t1;
  218. con[2] = t2;
  219. break;
  220.     case SqlType::Unbound:
  221. con[1] = con[2] = t2;
  222. break;
  223.     default:
  224. break;
  225.     }
  226.     break;
  227. case SqlType::Unbound:
  228.     con[1] = con[2] = t1;
  229.     break;
  230. default:
  231.     break;
  232. }
  233. if (con[1].type() == SqlType::Undef || con[2].type() == SqlType::Undef) {
  234.     char b1[40], b2[40];
  235.     t1.print(b1, sizeof(b1));
  236.     t2.print(b2, sizeof(b2));
  237.     ctx.pushStatus(Error::Gen, "type mismatch in comparison: %s %s %s", b1, m_op.name(), b2);
  238.     return 0;
  239. }
  240.     } else {
  241. ctx_assert(false);
  242. return 0;
  243.     }
  244.     if (! ctx.ok())
  245. return 0;
  246.     // insert required conversions
  247.     for (unsigned i = 1; i <= arity; i++) {
  248. if (con[i].type() == SqlType::Unbound) {
  249.     continue;
  250. }
  251. Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, con[i]);
  252. m_root->saveNode(exprConv);
  253. exprConv->setExpr(m_expr[i]);
  254. m_expr[i] = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
  255. if (! ctx.ok())
  256.     return 0;
  257. ctx_assert(m_expr[i] != 0);
  258.     }
  259.     // look for column=expr
  260.     if (ctl.m_topand && m_op.m_opcode == Comp_op::Eq) {
  261. ctx_assert(arity == 2);
  262. for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
  263.     if (m_expr[i]->type() != Plan_expr::TypeColumn)
  264. continue;
  265.     Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
  266.     if (! column->resolveEq(ctx, m_expr[j]))
  267. ctl.m_extra = true;
  268. }
  269.     } else {
  270. ctl.m_extra = true;
  271.     }
  272.     // save top level comparison on list
  273.     if (ctl.m_topand) {
  274. ctl.m_topcomp.push_back(this);
  275.     }
  276.     // table dependencies are union from operands
  277.     m_tableSet.clear();
  278.     for (unsigned i = 1; i <= arity; i++) {
  279. const TableSet& ts = m_expr[i]->tableSet();
  280. m_tableSet.insert(ts.begin(), ts.end());
  281.     }
  282.     // set of tables for which interpreter cannot be used
  283.     m_noInterp.clear();
  284.     // convenient
  285. #undef ustype
  286. #define ustype(b, n) (((b) ? 1 : 0) * 100 + (n))
  287.     if (arity == 1) {
  288. for (unsigned i = 1; i <= 1; i++) {
  289.     const SqlType t1 = m_expr[i]->sqlType();
  290.     switch (m_op.m_opcode) {
  291.     case Comp_op::Isnull:
  292.     case Comp_op::Isnotnull:
  293. if (m_expr[i]->type() == Plan_expr::TypeColumn) {
  294.     switch (ustype(t1.unSigned(), t1.type())) {
  295.     // all types accepted now
  296.     default:
  297. {
  298.     Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
  299.     ctx_assert(column->m_resTable != 0);
  300.     m_interpColumn[i] = column;
  301.     continue; // ok
  302. }
  303. break;
  304.     }
  305. }
  306. break;
  307.     default:
  308. break;
  309.     }
  310.     const TableSet& ts = m_expr[i]->tableSet();
  311.     m_noInterp.insert(ts.begin(), ts.end());
  312. }
  313.     } else if (arity == 2) {
  314. for (unsigned i = 1, j = 2; i <= 2; i++, j--) {
  315.     const SqlType t1 = m_expr[i]->sqlType();
  316.     switch (m_op.m_opcode) {
  317.     case Comp_op::Like:
  318.     case Comp_op::Notlike:
  319. if (i == 2) // col like val but not val like col
  320.     break;
  321. /*FALLTHRU*/
  322.     case Comp_op::Eq:
  323.     case Comp_op::Noteq:
  324.     case Comp_op::Lt:
  325.     case Comp_op::Lteq:
  326.     case Comp_op::Gt:
  327.     case Comp_op::Gteq:
  328. if (m_expr[i]->type() == Plan_expr::TypeColumn) {
  329.     switch (ustype(t1.unSigned(), t1.type())) {
  330.     case ustype(false, SqlType::Char):
  331.     case ustype(false, SqlType::Varchar):
  332.     case ustype(true, SqlType::Smallint):
  333.     case ustype(true, SqlType::Integer):
  334.     case ustype(true, SqlType::Bigint):
  335. {
  336.     Plan_expr_column* column = static_cast<Plan_expr_column*>(m_expr[i]);
  337.     ctx_assert(column->m_resTable != 0);
  338.     const TableSet& ts = m_expr[j]->tableSet();
  339.     if (ts.find(column->m_resTable) == ts.end()) {
  340. // candidate for column=const
  341. m_interpColumn[i] = column;
  342. continue; // ok
  343.     }
  344. }
  345. break;
  346.     default:
  347. break;
  348.     }
  349. }
  350. break;
  351.     default:
  352. break;
  353.     }
  354.     const TableSet& ts = m_expr[i]->tableSet();
  355.     m_noInterp.insert(ts.begin(), ts.end());
  356. }
  357.     } else {
  358. ctx_assert(false);
  359. return 0;
  360.     }
  361. #undef ustype
  362.     return this;
  363. }
  364. Exec_base*
  365. Plan_comp_op::codegen(Ctx& ctx, Ctl& ctl)
  366. {
  367.     if (m_exec != 0)
  368. return m_exec;
  369.     const unsigned arity = m_op.arity();
  370.     Exec_comp_op* exec = new Exec_comp_op(ctl.m_execRoot);
  371.     ctl.m_execRoot->saveNode(exec);
  372.     // create code for operands
  373.     for (unsigned i = 1; i <= arity; i++) {
  374. ctx_assert(m_expr[i] != 0);
  375. Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr[i]->codegen(ctx, ctl));
  376. if (! ctx.ok())
  377.     return 0;
  378. ctx_assert(execExpr != 0);
  379. exec->setExpr(i, execExpr);
  380.     }
  381.     // create the code
  382.     Exec_comp_op::Code& code = *new Exec_comp_op::Code(m_op);
  383.     // interpreted column=const
  384.     if (! ctl.m_having) {
  385. ctx_assert(ctl.m_topTable != 0);
  386. for (unsigned i = 1; i <= arity; i++) {
  387.     Plan_expr_column* column = m_interpColumn[i];
  388.     if (column == 0)
  389. continue;
  390.     ctx_assert(column->m_resTable != 0);
  391.     if (column->m_resTable != ctl.m_topTable)
  392. continue;
  393.     ctx_assert(code.m_interpColumn == 0);
  394.     code.m_interpColumn = i;
  395.     code.m_interpAttrId = column->dictColumn().getAttrId();
  396.     ctx_log2(("can use interpreter on %s", column->getPrintName()));
  397. }
  398.     }
  399.     exec->setCode(code);
  400.     m_exec = exec;
  401.     return exec;
  402. }
  403. void
  404. Plan_comp_op::print(Ctx& ctx)
  405. {
  406.     ctx.print(" [%s", m_op.name());
  407.     Plan_base* a[] = { m_expr[1], m_expr[2] };
  408.     printList(ctx, a, m_op.arity());
  409.     ctx.print("]");
  410. }
  411. bool
  412. Plan_comp_op::isGroupBy(const Plan_expr_row* row) const
  413. {
  414.     const unsigned arity = m_op.arity();
  415.     for (unsigned i = 1; i <= arity; i++) {
  416. ctx_assert(m_expr[i] != 0);
  417. if (! m_expr[i]->isGroupBy(row))
  418.     return false;
  419.     }
  420.     return true;
  421. }
  422. // Code_comp_op
  423. Exec_comp_op::Code::~Code()
  424. {
  425. }
  426. Exec_comp_op::Data::~Data()
  427. {
  428. }
  429. Exec_comp_op::~Exec_comp_op()
  430. {
  431. }
  432. void
  433. Exec_comp_op::alloc(Ctx& ctx, Ctl& ctl)
  434. {
  435.     const Code& code = getCode();
  436.     // allocate subexpressions
  437.     unsigned arity = code.m_op.arity();
  438.     for (unsigned i = 1; i <= arity; i++) {
  439. ctx_assert(m_expr[i] != 0);
  440. m_expr[i]->alloc(ctx, ctl);
  441. if (! ctx.ok())
  442.     return;
  443.     }
  444.     Data& data = *new Data;
  445.     setData(data);
  446. }
  447. void
  448. Exec_comp_op::close(Ctx& ctx)
  449. {
  450.     const Code& code = getCode();
  451.     unsigned arity = code.m_op.arity();
  452.     for (unsigned i = 1; i <= arity; i++) {
  453. ctx_assert(m_expr[i] != 0);
  454. m_expr[i]->close(ctx);
  455.     }
  456. }
  457. void
  458. Exec_comp_op::print(Ctx& ctx)
  459. {
  460.     const Code& code = getCode();
  461.     ctx.print(" [%s", code.m_op.name());
  462.     Exec_base* a[] = { m_expr[1], m_expr[2] };
  463.     printList(ctx, a, code.m_op.arity());
  464.     ctx.print("]");
  465. }