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

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_expr.hpp"
  14. #include "Code_expr_op.hpp"
  15. #include "Code_expr_conv.hpp"
  16. #include "Code_root.hpp"
  17. // Expr_op
  18. const char*
  19. Expr_op::name() const
  20. {
  21.     switch (m_opcode) {
  22.     case Add:
  23. return "+";
  24.     case Subtract:
  25. return "-";
  26.     case Multiply:
  27. return "*";
  28.     case Divide:
  29. return "/";
  30.     case Plus:
  31. return "+";
  32.     case Minus:
  33. return "-";
  34.     }
  35.     ctx_assert(false);
  36.     return "";
  37. }
  38. unsigned
  39. Expr_op::arity() const
  40. {
  41.     switch (m_opcode) {
  42.     case Add:
  43.     case Subtract:
  44.     case Multiply:
  45.     case Divide:
  46. return 2;
  47.     case Plus:
  48.     case Minus:
  49. return 1;
  50.     }
  51.     ctx_assert(false);
  52.     return 0;
  53. }
  54. // Plan_expr_op
  55. Plan_expr_op::~Plan_expr_op()
  56. {
  57. }
  58. Plan_base*
  59. Plan_expr_op::analyze(Ctx& ctx, Ctl& ctl)
  60. {
  61.     m_exec = 0;
  62.     unsigned arity = m_op.arity();
  63.     // analyze operands
  64.     m_isAggr = false;
  65.     m_isBound = true;
  66.     for (unsigned i = 1; i <= arity; i++) {
  67. ctx_assert(m_expr[i] != 0);
  68. m_expr[i]->analyze(ctx, ctl);
  69. if (! ctx.ok())
  70.     return 0;
  71. if (m_expr[i]->m_isAggr)
  72.     m_isAggr = true;
  73. if (! m_expr[i]->m_isBound)
  74.     m_isBound = false;
  75.     }
  76.     // find result type and conversion types (currently same)
  77.     SqlType res;
  78.     SqlType con[1 + 2];
  79.     if (arity == 1) {
  80. const SqlType& t1 = m_expr[1]->sqlType();
  81. switch (t1.type()) {
  82. case SqlType::Char:
  83. case SqlType::Varchar:
  84.     break;
  85. case SqlType::Smallint:
  86. case SqlType::Integer:
  87. case SqlType::Bigint:
  88.     res.setType(ctx, SqlType::Bigint);
  89.     con[1] = res;
  90.     break;
  91. case SqlType::Real:
  92. case SqlType::Double:
  93.     res.setType(ctx, SqlType::Double);
  94.     con[1] = res;
  95.     break;
  96. case SqlType::Null:
  97.     res.setType(ctx, SqlType::Null);
  98.     con[1] = res;
  99.     break;
  100. case SqlType::Unbound:
  101.     res.setType(ctx, SqlType::Unbound);
  102.     con[1] = res;
  103. default:
  104.     break;
  105. }
  106. if (con[1].type() == SqlType::Undef) {
  107.     char b1[40];
  108.     t1.print(b1, sizeof(b1));
  109.     ctx.pushStatus(Error::Gen, "type mismatch in operation: %s %s", m_op.name(), b1);
  110.     return 0;
  111. }
  112.     } else if (arity == 2) {
  113. const SqlType& t1 = m_expr[1]->sqlType();
  114. const SqlType& t2 = m_expr[2]->sqlType();
  115. switch (t1.type()) {
  116. case SqlType::Char: // handle char types as in oracle
  117.     switch (t2.type()) {
  118.     case SqlType::Char:
  119. res.setType(ctx, SqlType::Char, t1.length() + t2.length());
  120. con[1] = t1;
  121. con[2] = t2;
  122. break;
  123.     case SqlType::Varchar:
  124. res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
  125. con[1] = t1;
  126. con[2] = t2;
  127. break;
  128.     case SqlType::Null:
  129. res.setType(ctx, SqlType::Varchar, t1.length());
  130. con[1] = t1;
  131. con[2] = t2;
  132. break;
  133.     case SqlType::Unbound:
  134. res.setType(ctx, SqlType::Unbound);
  135. con[1] = con[2] = res;
  136. break;
  137.     default:
  138. break;
  139.     }
  140.     break;
  141. case SqlType::Varchar:
  142.     switch (t2.type()) {
  143.     case SqlType::Char:
  144. res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
  145. con[1] = t1;
  146. con[2] = t2;
  147. break;
  148.     case SqlType::Varchar:
  149. res.setType(ctx, SqlType::Varchar, t1.length() + t2.length());
  150. con[1] = t1;
  151. con[2] = t2;
  152. break;
  153.     case SqlType::Null:
  154. res.setType(ctx, SqlType::Varchar, t1.length());
  155. con[1] = t1;
  156. con[2] = t2;
  157. break;
  158.     case SqlType::Unbound:
  159. res.setType(ctx, SqlType::Unbound);
  160. con[1] = con[2] = res;
  161. break;
  162.     default:
  163. break;
  164.     }
  165.     break;
  166. case SqlType::Smallint:
  167. case SqlType::Integer:
  168. case SqlType::Bigint:
  169.     switch (t2.type()) {
  170.     case SqlType::Smallint:
  171.     case SqlType::Integer:
  172.     case SqlType::Bigint:
  173. res.setType(ctx, SqlType::Bigint);
  174. con[1] = con[2] = res;
  175. if (t1.unSigned() || t2.unSigned()) {
  176.     con[1].unSigned(true);
  177.     con[2].unSigned(true);
  178. }
  179. break;
  180.     case SqlType::Real:
  181.     case SqlType::Double:
  182. res.setType(ctx, SqlType::Double);
  183. con[1] = con[2] = res;
  184. break;
  185.     case SqlType::Null:
  186. res.setType(ctx, SqlType::Null);
  187. con[1] = con[2] = res;
  188. break;
  189.     case SqlType::Unbound:
  190. res.setType(ctx, SqlType::Unbound);
  191. con[1] = con[2] = res;
  192. break;
  193.     default:
  194. break;
  195.     }
  196.     break;
  197. case SqlType::Real:
  198. case SqlType::Double:
  199.     switch (t2.type()) {
  200.     case SqlType::Smallint:
  201.     case SqlType::Integer:
  202.     case SqlType::Bigint:
  203.     case SqlType::Real:
  204.     case SqlType::Double:
  205. res.setType(ctx, SqlType::Double);
  206. con[1] = con[2] = res;
  207. break;
  208.     case SqlType::Null:
  209. res.setType(ctx, SqlType::Null);
  210. con[1] = con[2] = res;
  211. break;
  212.     case SqlType::Unbound:
  213. res.setType(ctx, SqlType::Unbound);
  214. con[1] = con[2] = res;
  215. break;
  216.     default:
  217. break;
  218.     }
  219.     break;
  220. case SqlType::Null:
  221.     switch (t2.type()) {
  222.     case SqlType::Char:
  223.     case SqlType::Varchar:
  224. res.setType(ctx, SqlType::Varchar, t2.length());
  225. con[1] = con[2] = res;
  226. break;
  227.     case SqlType::Unbound:
  228. res.setType(ctx, SqlType::Unbound);
  229. con[1] = con[2] = res;
  230. break;
  231.     default:
  232. res.setType(ctx, SqlType::Null);
  233. con[1] = con[2] = res;
  234. break;
  235.     }
  236.     break;
  237. case SqlType::Unbound:
  238.     res.setType(ctx, SqlType::Unbound);
  239.     con[1] = con[2] = res;
  240.     break;
  241. default:
  242.     break;
  243. }
  244. if (con[1].type() == SqlType::Undef || con[2].type() == SqlType::Undef) {
  245.     char b1[40], b2[40];
  246.     t1.print(b1, sizeof(b1));
  247.     t2.print(b2, sizeof(b2));
  248.     ctx.pushStatus(Error::Gen, "type mismatch in operation: %s %s %s", b1, m_op.name(), b2);
  249.     return 0;
  250. }
  251.     } else {
  252. ctx_assert(false);
  253. return 0;
  254.     }
  255.     if (! ctx.ok())
  256. return 0;
  257.     // insert required conversions
  258.     for (unsigned i = 1; i <= arity; i++) {
  259. if (con[i].type() == SqlType::Undef) {
  260.     ctx.pushStatus(Error::Gen, "mismatched types in operation");
  261.     return 0;
  262. }
  263. if (con[i].type() == SqlType::Unbound) {
  264.     // parameter type not yet bound
  265.     continue;
  266. }
  267. Plan_expr_conv* exprConv = new Plan_expr_conv(m_root, con[i]);
  268. m_root->saveNode(exprConv);
  269. exprConv->setExpr(m_expr[i]);
  270. m_expr[i] = static_cast<Plan_expr*>(exprConv->analyze(ctx, ctl));
  271. if (! ctx.ok())
  272.     return 0;
  273. ctx_assert(m_expr[i] != 0);
  274.     }
  275.     // set result type
  276.     m_sqlType = res;
  277.     // table dependencies are union from operands
  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 alias name  XXX misses operator precedence
  283.     if (arity == 1) {
  284. m_alias.assign(m_op.name());
  285. m_alias.append(m_expr[1]->m_alias);
  286.     } else if (arity == 2) {
  287. m_alias.assign(m_expr[1]->m_alias);
  288. m_alias.append(m_op.name());
  289. m_alias.append(m_expr[2]->m_alias);
  290.     }
  291.     return this;
  292. }
  293. Exec_base*
  294. Plan_expr_op::codegen(Ctx& ctx, Ctl& ctl)
  295. {
  296.     if (m_exec != 0)
  297. return m_exec;
  298.     unsigned arity = m_op.arity();
  299.     Exec_expr_op* exec = new Exec_expr_op(ctl.m_execRoot);
  300.     ctl.m_execRoot->saveNode(exec);
  301.     // create code for operands
  302.     for (unsigned i = 1; i <= arity; i++) {
  303. ctx_assert(m_expr[i] != 0);
  304. Exec_expr* execExpr = static_cast<Exec_expr*>(m_expr[i]->codegen(ctx, ctl));
  305. if (! ctx.ok())
  306.     return 0;
  307. ctx_assert(execExpr != 0);
  308. exec->setExpr(i, execExpr);
  309.     }
  310.     // create the code
  311.     SqlSpec sqlSpec(sqlType(), SqlSpec::Physical);
  312.     Exec_expr_op::Code& code = *new Exec_expr_op::Code(m_op, sqlSpec);
  313.     exec->setCode(code);
  314.     m_exec = exec;
  315.     return exec;
  316. }
  317. void
  318. Plan_expr_op::print(Ctx& ctx)
  319. {
  320.     ctx.print(" [%s", m_op.name());
  321.     Plan_base* a[] = { m_expr[1], m_expr[2] };
  322.     printList(ctx, a, m_op.arity());
  323.     ctx.print("]");
  324. }
  325. bool
  326. Plan_expr_op::isEqual(const Plan_expr* expr) const
  327. {
  328.     ctx_assert(expr != 0);
  329.     if (expr->type() != Plan_expr::TypeOp)
  330. return false;
  331.     const Plan_expr_op* expr2 = static_cast<const Plan_expr_op*>(expr);
  332.     if (m_op.m_opcode != expr2->m_op.m_opcode)
  333. return false;
  334.     const unsigned arity = m_op.arity();
  335.     for (unsigned i = 1; i <= arity; i++) {
  336. ctx_assert(m_expr[i] != 0);
  337. if (! m_expr[i]->isEqual(expr2->m_expr[i]))
  338.     return false;
  339.     }
  340.     return true;
  341. }
  342. bool
  343. Plan_expr_op::isGroupBy(const Plan_expr_row* row) const
  344. {
  345.     if (isAnyEqual(row))
  346. return true;
  347.     const unsigned arity = m_op.arity();
  348.     for (unsigned i = 1; i <= arity; i++) {
  349. ctx_assert(m_expr[i] != 0);
  350. if (! m_expr[i]->isGroupBy(row))
  351.     return false;
  352.     }
  353.     return true;
  354. }
  355. // Code_expr_op
  356. Exec_expr_op::Code::~Code()
  357. {
  358. }
  359. Exec_expr_op::Data::~Data()
  360. {
  361. }
  362. Exec_expr_op::~Exec_expr_op()
  363. {
  364. }
  365. void
  366. Exec_expr_op::alloc(Ctx& ctx, Ctl& ctl)
  367. {
  368.     if (m_data != 0)
  369. return;
  370.     const Code& code = getCode();
  371.     // allocate subexpressions
  372.     unsigned arity = code.m_op.arity();
  373.     for (unsigned i = 1; i <= arity; i++) {
  374. ctx_assert(m_expr[i] != 0);
  375. m_expr[i]->alloc(ctx, ctl);
  376. if (! ctx.ok())
  377.     return;
  378.     }
  379.     SqlField sqlField(code.m_sqlSpec);
  380.     Data& data = *new Data(sqlField);
  381.     setData(data);
  382. }
  383. void
  384. Exec_expr_op::close(Ctx& ctx)
  385. {
  386.     const Code& code = getCode();
  387.     unsigned arity = code.m_op.arity();
  388.     for (unsigned i = 1; i <= arity; i++) {
  389. ctx_assert(m_expr[i] != 0);
  390. m_expr[i]->close(ctx);
  391.     }
  392.     Data& data = getData();
  393.     data.m_groupField.clear();
  394. }
  395. void
  396. Exec_expr_op::print(Ctx& ctx)
  397. {
  398.     const Code& code = getCode();
  399.     ctx.print(" [%s", code.m_op.name());
  400.     Exec_base* a[] = { m_expr[1], m_expr[2] };
  401.     printList(ctx, a, code.m_op.arity());
  402.     ctx.print("]");
  403. }