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

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 "Code_delete.hpp"
  15. #include "Code_delete_lookup.hpp"
  16. #include "Code_delete_index.hpp"
  17. #include "Code_delete_scan.hpp"
  18. #include "Code_query_filter.hpp"
  19. #include "Code_query_lookup.hpp"
  20. #include "Code_query_index.hpp"
  21. #include "Code_query_scan.hpp"
  22. #include "Code_query_range.hpp"
  23. #include "Code_query_repeat.hpp"
  24. #include "Code_table.hpp"
  25. #include "Code_root.hpp"
  26. Plan_delete::~Plan_delete()
  27. {
  28. }
  29. Plan_base*
  30. Plan_delete::analyze(Ctx& ctx, Ctl& ctl)
  31. {
  32.     stmtArea().stmtInfo().setName(Stmt_name_delete);
  33.     // analyze the table
  34.     ctx_assert(m_table != 0);
  35.     m_table->analyze(ctx, ctl);
  36.     if (! ctx.ok())
  37. return 0;
  38.     // set name resolution scope
  39.     ctl.m_tableList.resize(1 + 1); // indexed from 1
  40.     ctl.m_tableList[1] = m_table;
  41.     Plan_dml* stmt = 0;
  42.     if (m_pred != 0) {
  43. // analyze the predicate
  44. ctl.m_topand = true;
  45. ctl.m_extra = false;
  46. m_pred = static_cast<Plan_pred*>(m_pred->analyze(ctx, ctl));
  47. if (! ctx.ok())
  48.     return 0;
  49. ctx_assert(m_pred != 0);
  50. // check for key match
  51. Plan_table::Index* indexBest = 0;
  52. for (unsigned i = 0; i <= m_table->indexCount(); i++) {
  53.     Plan_table::Index& index = m_table->m_indexList[i];
  54.     TableSet tsDone;
  55.     m_table->resolveSet(ctx, index, tsDone);
  56.     if (! ctx.ok())
  57. return 0;
  58.     if (! index.m_keyFound)
  59. continue;
  60.     // prefer smaller rank, less unused keys
  61.     int k;
  62.     (k = (indexBest == 0)) ||
  63. (k = (indexBest->m_rank - index.m_rank)) ||
  64. (k = (indexBest->m_keyCountUnused - index.m_keyCountUnused));
  65.     if (k > 0)
  66. indexBest = &index;
  67. }
  68. if (indexBest != 0) {
  69.     const bool exactKey = indexBest->m_rank <= 1 ? m_table->exactKey(ctx, indexBest) : false;
  70.     const bool direct = ! ctl.m_extra && exactKey;
  71.     ctx_log3(("delete direct=%d: extra=%d exact=%d", direct, ctl.m_extra, exactKey));
  72.     if (indexBest->m_rank == 0) {
  73. // primary key
  74. Plan_delete_lookup* deleteLookup = new Plan_delete_lookup(m_root);
  75. m_root->saveNode(deleteLookup);
  76. deleteLookup->setTable(m_table);
  77. if (direct) {
  78.     // key match with no extra conditions
  79.     Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
  80.     m_root->saveNode(queryRepeat);
  81.     deleteLookup->setQuery(queryRepeat);
  82. } else {
  83.     // key match with extra conditions
  84.     Plan_query_lookup* queryLookup = new Plan_query_lookup(m_root);
  85.     m_root->saveNode(queryLookup);
  86.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  87.     m_root->saveNode(queryFilter);
  88.     queryLookup->setTable(m_table);
  89.     queryFilter->setQuery(queryLookup);
  90.     queryFilter->setPred(m_pred);
  91.     queryFilter->m_topTable = m_table;
  92.     deleteLookup->setQuery(queryFilter);
  93. }
  94. stmt = deleteLookup;
  95.     } else if (indexBest->m_rank == 1) {
  96. // hash index
  97. Plan_delete_index* deleteIndex = new Plan_delete_index(m_root);
  98. m_root->saveNode(deleteIndex);
  99. deleteIndex->setTable(m_table, indexBest);
  100. if (direct) {
  101.     // key match with no extra conditions
  102.     Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
  103.     m_root->saveNode(queryRepeat);
  104.     deleteIndex->setQuery(queryRepeat);
  105. } else {
  106.     // key match with extra conditions
  107.     Plan_query_index* queryIndex = new Plan_query_index(m_root);
  108.     m_root->saveNode(queryIndex);
  109.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  110.     m_root->saveNode(queryFilter);
  111.     queryIndex->setTable(m_table, indexBest);
  112.     queryFilter->setQuery(queryIndex);
  113.     queryFilter->setPred(m_pred);
  114.     queryFilter->m_topTable = m_table;
  115.     deleteIndex->setQuery(queryFilter);
  116. }
  117. stmt = deleteIndex;
  118.     } else if (indexBest->m_rank == 2) {
  119. // ordered index
  120. Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
  121. m_root->saveNode(deleteScan);
  122. Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  123. m_root->saveNode(queryFilter);
  124. Plan_query_range* queryRange = new Plan_query_range(m_root);
  125. m_root->saveNode(queryRange);
  126. queryRange->setTable(m_table, indexBest);
  127. queryRange->setExclusive();
  128. queryFilter->setQuery(queryRange);
  129. queryFilter->setPred(m_pred);
  130. queryFilter->m_topTable = m_table;
  131. const TableSet& ts2 = m_pred->noInterp();
  132. ctx_assert(ts2.size() <= 1);
  133. if (ts2.size() == 0) {
  134.     queryRange->setInterp(m_pred);
  135. }
  136. deleteScan->setQuery(queryFilter);
  137. stmt = deleteScan;
  138.     } else {
  139. ctx_assert(false);
  140.     }
  141. } else {
  142.     // scan delete with filter
  143.     Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
  144.     m_root->saveNode(deleteScan);
  145.     Plan_query_filter* queryFilter = new Plan_query_filter(m_root);
  146.     m_root->saveNode(queryFilter);
  147.     Plan_query_scan* queryScan = new Plan_query_scan(m_root);
  148.     m_root->saveNode(queryScan);
  149.     queryScan->setTable(m_table);
  150.     queryScan->setExclusive();
  151.     queryFilter->setQuery(queryScan);
  152.     queryFilter->setPred(m_pred);
  153.     queryFilter->m_topTable = m_table;
  154.     // interpeter
  155.     const TableSet& ts2 = m_pred->noInterp();
  156.     ctx_assert(ts2.size() <= 1);
  157.     if (ts2.size() == 0) {
  158. queryScan->setInterp(m_pred);
  159.     }
  160.     deleteScan->setQuery(queryFilter);
  161.     stmt = deleteScan;
  162. }
  163.     } else {
  164. // scan delete without filter
  165. Plan_delete_scan* deleteScan = new Plan_delete_scan(m_root);
  166. m_root->saveNode(deleteScan);
  167. Plan_query_scan* queryScan = new Plan_query_scan(m_root);
  168. m_root->saveNode(queryScan);
  169. queryScan->setTable(m_table);
  170. queryScan->setExclusive();
  171. deleteScan->setQuery(queryScan);
  172. stmt = deleteScan;
  173.     }
  174.     // set base for column position offsets
  175.     m_table->m_resOff = 1;
  176.     return stmt;
  177. }
  178. void
  179. Plan_delete::describe(Ctx& ctx)
  180. {
  181.     stmtArea().setFunction(ctx, "DELETE WHERE", SQL_DIAG_DELETE_WHERE);
  182. }
  183. Exec_base*
  184. Plan_delete::codegen(Ctx& ctx, Ctl& ctl)
  185. {   
  186.     ctx_assert(false);
  187.     return 0;
  188. }    
  189. void
  190. Plan_delete::print(Ctx& ctx)
  191. {
  192.     ctx.print(" [delete");
  193.     Plan_base* a[] = { m_table, m_pred };
  194.     printList(ctx, a, 1);
  195.     ctx.print("]");
  196. }