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

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/StmtArea.hpp>
  14. #include <dictionary/DictTable.hpp>
  15. #include <dictionary/DictColumn.hpp>
  16. #include "Code_update.hpp"
  17. #include "Code_update_lookup.hpp"
  18. #include "Code_update_index.hpp"
  19. #include "Code_update_scan.hpp"
  20. #include "Code_table.hpp"
  21. #include "Code_query_project.hpp"
  22. #include "Code_query_filter.hpp"
  23. #include "Code_query_scan.hpp"
  24. #include "Code_query_lookup.hpp"
  25. #include "Code_query_index.hpp"
  26. #include "Code_query_range.hpp"
  27. #include "Code_query_repeat.hpp"
  28. #include "Code_root.hpp"
  29. // Plan_update
  30. Plan_update::~Plan_update()
  31. {
  32. }
  33. Plan_base*
  34. Plan_update::analyze(Ctx& ctx, Ctl& ctl)
  35. {
  36.     stmtArea().stmtInfo().setName(Stmt_name_update);
  37.     // analyze the table
  38.     ctx_assert(m_table != 0);
  39.     m_table->analyze(ctx, ctl);
  40.     if (! ctx.ok())
  41. return 0;
  42.     // get column and expression rows
  43.     ctx_assert(m_setRow != 0);
  44.     setDmlRow(m_setRow->m_dmlRow);
  45.     setExprRow(m_setRow->m_exprRow);
  46.     m_setRow = 0;
  47.     // implied by parse
  48.     ctx_assert(m_dmlRow->getSize() == m_exprRow->getSize());
  49.     // set name resolution scope
  50.     ctl.m_tableList.resize(1 + 1); // indexed from 1
  51.     ctl.m_tableList[1] = m_table;
  52.     // analyze the rows
  53.     m_dmlRow->analyze(ctx, ctl);
  54.     if (! ctx.ok())
  55. return 0;
  56.     ctl.m_dmlRow = m_dmlRow; // row type to convert to
  57.     ctl.m_const = true; // set to constants
  58.     m_exprRow->analyze(ctx, ctl);
  59.     if (! ctx.ok())
  60. return 0;
  61.     bool setConst = ctl.m_const;
  62.     ctl.m_dmlRow = 0;
  63.     Plan_dml* stmt = 0;
  64.     // top level query is a project
  65.     Plan_query_project* queryProject = new Plan_query_project(m_root);
  66.     m_root->saveNode(queryProject);
  67.     queryProject->setRow(m_exprRow);
  68.     if (m_pred != 0) {
  69. // analyze the predicate
  70. ctl.m_topand = true;
  71. ctl.m_extra = false;
  72. m_pred = static_cast<Plan_pred*>(m_pred->analyze(ctx, ctl));
  73. if (! ctx.ok())
  74.     return 0;
  75. ctx_assert(m_pred != 0);
  76. // check for key match
  77. Plan_table::Index* indexBest = 0;
  78. for (unsigned i = 0; i <= m_table->indexCount(); i++) {
  79.     Plan_table::Index& index = m_table->m_indexList[i];
  80.     TableSet tsDone;
  81.     m_table->resolveSet(ctx, index, tsDone);
  82.     if (! ctx.ok())
  83. return 0;
  84.     if (! index.m_keyFound)
  85. continue;
  86.     // prefer smaller rank, less unused keys
  87.     int k;
  88.     (k = (indexBest == 0)) ||
  89. (k = (indexBest->m_rank - index.m_rank)) ||
  90. (k = (indexBest->m_keyCountUnused - index.m_keyCountUnused));
  91.     if (k > 0)
  92. indexBest = &index;
  93. }
  94. if (indexBest != 0) {
  95.     const bool exactKey = indexBest->m_rank <= 1 ? m_table->exactKey(ctx, indexBest) : false;
  96.     const bool direct = setConst && ! ctl.m_extra && exactKey;
  97.     ctx_log3(("update direct=%d: const=%d extra=%d exact=%d", direct, setConst, ctl.m_extra, exactKey));
  98.     if (indexBest->m_rank == 0) {
  99. // primary key
  100. Plan_update_lookup* updateLookup = new Plan_update_lookup(m_root);
  101. m_root->saveNode(updateLookup);
  102. updateLookup->setTable(m_table);
  103. updateLookup->setDmlRow(m_dmlRow);
  104. if (direct) {
  105.     // constant values and exact key match
  106.     Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
  107.     m_root->saveNode(queryRepeat);
  108.     queryProject->setQuery(queryRepeat);
  109. } else {
  110.     // more conditions or non-constant values
  111.     Plan_query_lookup* queryLookup = new Plan_query_lookup(m_root);
  112.     m_root->saveNode(queryLookup);
  113.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  114.     m_root->saveNode(queryFilter);
  115.     queryLookup->setTable(m_table);
  116.     queryFilter->setQuery(queryLookup);
  117.     queryFilter->setPred(m_pred);
  118.     queryFilter->m_topTable = m_table;
  119.     queryProject->setQuery(queryFilter);
  120. }
  121. updateLookup->setQuery(queryProject);
  122. stmt = updateLookup;
  123.     } else if (indexBest->m_rank == 1) {
  124. // hash index
  125. Plan_update_index* updateIndex = new Plan_update_index(m_root);
  126. m_root->saveNode(updateIndex);
  127. updateIndex->setTable(m_table, indexBest);
  128. updateIndex->setDmlRow(m_dmlRow);
  129. if (direct) {
  130.     // constant values and exact key match
  131.     Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
  132.     m_root->saveNode(queryRepeat);
  133.     queryProject->setQuery(queryRepeat);
  134. } else {
  135.     // more conditions or non-constant values
  136.     Plan_query_index* queryIndex = new Plan_query_index(m_root);
  137.     m_root->saveNode(queryIndex);
  138.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  139.     m_root->saveNode(queryFilter);
  140.     queryIndex->setTable(m_table, indexBest);
  141.     queryFilter->setQuery(queryIndex);
  142.     queryFilter->setPred(m_pred);
  143.     queryFilter->m_topTable = m_table;
  144.     queryProject->setQuery(queryFilter);
  145. }
  146. updateIndex->setQuery(queryProject);
  147. stmt = updateIndex;
  148.     } else if (indexBest->m_rank == 2) {
  149. // ordered index
  150. Plan_update_scan* updateScan = new Plan_update_scan(m_root);
  151. m_root->saveNode(updateScan);
  152. updateScan->setTable(m_table);
  153. updateScan->setDmlRow(m_dmlRow);
  154. Plan_query_range* queryRange = new Plan_query_range(m_root);
  155. m_root->saveNode(queryRange);
  156. queryRange->setTable(m_table, indexBest);
  157. queryRange->setExclusive();
  158. Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  159. m_root->saveNode(queryFilter);
  160. queryFilter->setQuery(queryRange);
  161. queryFilter->setPred(m_pred);
  162. queryFilter->m_topTable = m_table;
  163. // interpeter
  164. const TableSet& ts2 = m_pred->noInterp();
  165. ctx_assert(ts2.size() <= 1);
  166. if (ts2.size() == 0) {
  167.     queryRange->setInterp(m_pred);
  168. }
  169. queryProject->setQuery(queryFilter);
  170. updateScan->setQuery(queryProject);
  171. stmt = updateScan;
  172.     } else {
  173. ctx_assert(false);
  174.     }
  175. } else {
  176.     // scan update with filter
  177.     Plan_update_scan* updateScan = new Plan_update_scan(m_root);
  178.     m_root->saveNode(updateScan);
  179.     updateScan->setTable(m_table);
  180.     updateScan->setDmlRow(m_dmlRow);
  181.     Plan_query_scan* queryScan = new Plan_query_scan(m_root);
  182.     m_root->saveNode(queryScan);
  183.     queryScan->setTable(m_table);
  184.     queryScan->setExclusive();
  185.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  186.     m_root->saveNode(queryFilter);
  187.     queryFilter->setQuery(queryScan);
  188.     queryFilter->setPred(m_pred);
  189.     queryFilter->m_topTable = m_table;
  190.     // interpeter
  191.     const TableSet& ts2 = m_pred->noInterp();
  192.     ctx_assert(ts2.size() <= 1);
  193.     if (ts2.size() == 0) {
  194. queryScan->setInterp(m_pred);
  195.     }
  196.     queryProject->setQuery(queryFilter);
  197.     updateScan->setQuery(queryProject);
  198.     stmt = updateScan;
  199. }
  200.     } else {
  201. // scan update without filter
  202. Plan_update_scan* updateScan = new Plan_update_scan(m_root);
  203. m_root->saveNode(updateScan);
  204. updateScan->setTable(m_table);
  205. updateScan->setDmlRow(m_dmlRow);
  206. Plan_query_scan* queryScan = new Plan_query_scan(m_root);
  207. m_root->saveNode(queryScan);
  208. queryScan->setTable(m_table);
  209. queryScan->setExclusive();
  210. queryProject->setQuery(queryScan);
  211. updateScan->setQuery(queryProject);
  212. stmt = updateScan;
  213.     }
  214.     // set base for column position offsets
  215.     m_table->m_resOff = 1;
  216.     return stmt;
  217. }
  218. void
  219. Plan_update::describe(Ctx& ctx)
  220. {
  221.     stmtArea().setFunction(ctx, "UPDATE WHERE", SQL_DIAG_UPDATE_WHERE);
  222. }
  223. Exec_base*
  224. Plan_update::codegen(Ctx& ctx, Ctl& ctl)
  225. {   
  226.     ctx_assert(false);
  227.     return 0;
  228. }    
  229. void
  230. Plan_update::print(Ctx& ctx)
  231. {
  232.     ctx.print(" [update");
  233.     Plan_base* a[] = { m_table, m_setRow, m_dmlRow, m_exprRow };
  234.     printList(ctx, a, 4);
  235.     ctx.print("]");
  236. }