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

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 <codegen/Code_pred_op.hpp>
  14. #include <NdbScanFilter.hpp>
  15. struct TableUnary {
  16.     Pred_value value1;
  17.     Pred_value result;
  18. };
  19. struct TableBinary {
  20.     Pred_value value1;
  21.     Pred_value value2;
  22.     Pred_value result;
  23. };
  24. static TableUnary
  25. tableNot[] = {
  26.     { Pred_value_unknown, Pred_value_unknown },
  27.     { Pred_value_false, Pred_value_true },
  28.     { Pred_value_true, Pred_value_false },
  29. };
  30. static TableBinary
  31. tableAnd[] = {
  32.     { Pred_value_unknown, Pred_value_unknown, Pred_value_unknown },
  33.     { Pred_value_unknown, Pred_value_false, Pred_value_false },
  34.     { Pred_value_unknown, Pred_value_true, Pred_value_unknown },
  35.     { Pred_value_false, Pred_value_unknown, Pred_value_false },
  36.     { Pred_value_false, Pred_value_false, Pred_value_false },
  37.     { Pred_value_false, Pred_value_true, Pred_value_false },
  38.     { Pred_value_true, Pred_value_unknown, Pred_value_unknown },
  39.     { Pred_value_true, Pred_value_false, Pred_value_false },
  40.     { Pred_value_true, Pred_value_true, Pred_value_true }
  41. };
  42. static TableBinary
  43. tableOr[] = {
  44.     { Pred_value_unknown, Pred_value_unknown, Pred_value_unknown },
  45.     { Pred_value_unknown, Pred_value_false, Pred_value_unknown },
  46.     { Pred_value_unknown, Pred_value_true, Pred_value_true },
  47.     { Pred_value_false, Pred_value_unknown, Pred_value_unknown },
  48.     { Pred_value_false, Pred_value_false, Pred_value_false },
  49.     { Pred_value_false, Pred_value_true, Pred_value_true },
  50.     { Pred_value_true, Pred_value_unknown, Pred_value_true },
  51.     { Pred_value_true, Pred_value_false, Pred_value_true },
  52.     { Pred_value_true, Pred_value_true, Pred_value_true }
  53. };
  54. void
  55. Exec_pred_op::execInterp(Ctx& ctx, Ctl& ctl)
  56. {
  57.     const Code& code = getCode();
  58.     Data& data = getData();
  59.     ctx_assert(ctl.m_scanFilter != 0);
  60.     NdbScanFilter& scanFilter = *ctl.m_scanFilter;
  61.     if (code.m_op.arity() == 1) {
  62. ctx_assert(m_pred[1] != 0);
  63. switch (code.m_op.m_opcode) {
  64. case Pred_op::Not:
  65.     scanFilter.begin(NdbScanFilter::NAND);
  66.     m_pred[1]-> execInterp(ctx, ctl);
  67.     if (! ctx.ok())
  68. return;
  69.     scanFilter.end();
  70.     break;
  71. default:
  72.     ctx_assert(false);
  73.     break;
  74. }
  75.     } else if (code.m_op.arity() == 2) {
  76. ctx_assert(m_pred[1] != 0 && m_pred[2] != 0);
  77. switch (code.m_op.m_opcode) {
  78. case Pred_op::And:
  79.     scanFilter.begin(NdbScanFilter::AND);
  80.     m_pred[1]-> execInterp(ctx, ctl);
  81.     if (! ctx.ok())
  82. return;
  83.     m_pred[2]-> execInterp(ctx, ctl);
  84.     if (! ctx.ok())
  85. return;
  86.     scanFilter.end();
  87.     break;
  88. case Pred_op::Or:
  89.     scanFilter.begin(NdbScanFilter::OR);
  90.     m_pred[1]-> execInterp(ctx, ctl);
  91.     if (! ctx.ok())
  92. return;
  93.     m_pred[2]-> execInterp(ctx, ctl);
  94.     if (! ctx.ok())
  95. return;
  96.     scanFilter.end();
  97.     break;
  98. default:
  99.     ctx_assert(false);
  100.     break;
  101. }
  102.     } else {
  103. ctx_assert(false);
  104.     }
  105. }
  106. void
  107. Exec_pred_op::evaluate(Ctx& ctx, Ctl& ctl)
  108. {
  109.     const Code& code = getCode();
  110.     Data& data = getData();
  111.     Pred_value v = Pred_value_unknown;
  112.     if (code.m_op.arity() == 1) {
  113. // evaluate sub-expression
  114. ctx_assert(m_pred[1] != 0);
  115. m_pred[1]->evaluate(ctx, ctl);
  116. if (! ctx.ok())
  117.     return;
  118. if (ctl.m_postEval)
  119.     return;
  120. Pred_value v1 = ctl.m_groupIndex == 0 ? m_pred[1]->getData().getValue() : m_pred[1]->getData().groupValue(ctl.m_groupIndex);
  121. // look up result
  122. TableUnary* table = 0;
  123. unsigned size = 0;
  124. switch (code.m_op.m_opcode) {
  125. case Pred_op::Not:
  126.     table = tableNot;
  127.     size = sizeof(tableNot) / sizeof(tableNot[0]);
  128.     break;
  129. default:
  130.     ctx_assert(false);
  131.     break;
  132. }
  133. unsigned i;
  134. for (i = 0; i < size; i++) {
  135.     if (table[i].value1 == v1) {
  136. v = table[i].result;
  137. break;
  138.     }
  139. }
  140. ctx_assert(i < size);
  141.     } else if (code.m_op.arity() == 2) {
  142. // evaluate sub-expressions
  143. ctx_assert(m_pred[1] != 0 && m_pred[2] != 0);
  144. m_pred[1]->evaluate(ctx, ctl);
  145. if (! ctx.ok())
  146.     return;
  147. m_pred[2]->evaluate(ctx, ctl);
  148. if (! ctx.ok())
  149.     return;
  150. if (ctl.m_postEval)
  151.     return;
  152. Pred_value v1 = ctl.m_groupIndex == 0 ? m_pred[1]->getData().getValue() : m_pred[1]->getData().groupValue(ctl.m_groupIndex);
  153. Pred_value v2 = ctl.m_groupIndex == 0 ? m_pred[2]->getData().getValue() : m_pred[2]->getData().groupValue(ctl.m_groupIndex);
  154. // look up result
  155. TableBinary* table = 0;
  156. unsigned size = 0;
  157. switch (code.m_op.m_opcode) {
  158. case Pred_op::And:
  159.     table = tableAnd;
  160.     size = sizeof(tableAnd) / sizeof(tableAnd[0]);
  161.     break;
  162. case Pred_op::Or:
  163.     table = tableOr;
  164.     size = sizeof(tableOr) / sizeof(tableOr[0]);
  165.     break;
  166. default:
  167.     ctx_assert(false);
  168.     break;
  169. }
  170. unsigned i;
  171. for (i = 0; i < size; i++) {
  172.     if (table[i].value1 == v1 && table[i].value2 == v2) {
  173. v = table[i].result;
  174. break;
  175.     }
  176. }
  177. ctx_assert(i < size);
  178.     } else {
  179. ctx_assert(false);
  180.     }
  181.     // set result
  182.     if (ctl.m_groupIndex == 0)
  183. data.m_value = v;
  184.     else
  185. data.groupValue(ctl.m_groupIndex, ctl.m_groupInit) = v;
  186. }