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

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 <algorithm>
  14. #include <common/StmtArea.hpp>
  15. #include <dictionary/DictTable.hpp>
  16. #include "Code_select.hpp"
  17. #include "Code_query_lookup.hpp"
  18. #include "Code_query_index.hpp"
  19. #include "Code_query_scan.hpp"
  20. #include "Code_query_range.hpp"
  21. #include "Code_query_sys.hpp"
  22. #include "Code_query_project.hpp"
  23. #include "Code_query_filter.hpp"
  24. #include "Code_query_join.hpp"
  25. #include "Code_query_count.hpp"
  26. #include "Code_query_sort.hpp"
  27. #include "Code_query_group.hpp"
  28. #include "Code_query_distinct.hpp"
  29. #include "Code_expr_column.hpp"
  30. #include "Code_expr_const.hpp"
  31. #include "Code_pred_op.hpp"
  32. #include "Code_root.hpp"
  33. Plan_select::~Plan_select()
  34. {
  35. }
  36. Plan_base*
  37. Plan_select::analyze(Ctx& ctx, Ctl& ctl)
  38. {
  39.     stmtArea().stmtInfo().setName(Stmt_name_select);
  40.     // analyze tables
  41.     ctx_assert(m_tableList != 0);
  42.     for (unsigned i = 1; i <= m_tableList->countTable(); i++) {
  43. Plan_table* table = m_tableList->getTable(i);
  44. table->analyze(ctx, ctl);
  45. if (! ctx.ok())
  46.     return 0;
  47.     }
  48.     ctx_assert(m_exprRow != 0);
  49.     if (m_exprRow->getAsterisk()) {
  50. // expand unqualified asterisk to table-qualified columns
  51. setRow(new Plan_expr_row(m_root));
  52. m_root->saveNode(m_exprRow);
  53. for (unsigned i = 1; i <= m_tableList->countTable(); i++) {
  54.     const Plan_table* table = m_tableList->getTable(i);
  55.     const DictTable& dictTable = table->dictTable();
  56.     for (unsigned i = 1; i <= dictTable.getSize(); i++) {
  57. DictColumn* dictColumn = dictTable.getColumn(i);
  58. Plan_expr_column* column = new Plan_expr_column(m_root, dictColumn->getName());
  59. m_root->saveNode(column);
  60. column->setCname(table->getCname());
  61. m_exprRow->addExpr(column);
  62.     }
  63. }
  64.     }
  65.     // set name resolution scope
  66.     ctl.m_tableList = m_tableList->m_tableList;
  67.     ctx_assert(ctl.m_tableList.size() >= 1 + 1);
  68.     ctl.m_aggrin = false;
  69.     // analyze select row
  70.     ctl.m_aggrok = true;
  71.     ctx_assert(m_exprRow != 0);
  72.     m_exprRow = static_cast<Plan_expr_row*>(m_exprRow->analyze(ctx, ctl));
  73.     if (! ctx.ok())
  74. return 0;
  75.     ctx_assert(m_exprRow != 0);
  76.     // analyze group by row
  77.     ctl.m_aggrok = false;
  78.     if (m_groupRow != 0) {
  79. m_groupRow = static_cast<Plan_expr_row*>(m_groupRow->analyze(ctx, ctl));
  80. if (! ctx.ok())
  81.     return 0;
  82. ctx_assert(m_groupRow != 0);
  83.     }
  84.     // analyze having predicate
  85.     ctl.m_aggrok = true;
  86.     if (m_havingPred != 0) {
  87. m_havingPred = static_cast<Plan_pred*>(m_havingPred->analyze(ctx, ctl));
  88. if (! ctx.ok())
  89.     return 0;
  90. ctx_assert(m_havingPred != 0);
  91.     }
  92.     // ana|yze order by row
  93.     ctl.m_aggrok = true;
  94.     if (m_sortRow != 0) {
  95. m_sortRow = static_cast<Plan_expr_row*>(m_sortRow->analyze(ctx, ctl));
  96. if (! ctx.ok())
  97.     return 0;
  98. ctx_assert(m_sortRow != 0);
  99.     }
  100.     // analyze the predicate
  101.     ctl.m_aggrok = false;
  102.     ctl.m_topand = true;
  103.     ctl.m_extra = false;
  104.     if (m_pred != 0) {
  105. m_pred = static_cast<Plan_pred*>(m_pred->analyze(ctx, ctl));
  106. if (! ctx.ok())
  107.     return 0;
  108. ctx_assert(m_pred != 0);
  109.     }
  110.     // check if group by required
  111.     if (m_exprRow->anyAggr() && ! m_exprRow->allBound() && m_groupRow == 0) {
  112. ctx.pushStatus(Error::Gen, "missing GROUP BY clause");
  113. return 0;
  114.     }
  115.     // in special cases add "group by 1"
  116.     if (m_groupRow == 0) {
  117. bool addgb = false;
  118. if (m_havingPred != 0) {
  119.     // allowed by oracle but nearly useless
  120.     addgb = true;
  121. } else if (m_exprRow->anyAggr() && m_sortRow != 0) {
  122.     // allowed by oracle but useless
  123.     ctx_assert(m_exprRow->allBound());
  124.     addgb = true;
  125. }
  126. if (addgb) {
  127.     ctx_log2(("adding 'group by 1'"));
  128.     m_groupRow = new Plan_expr_row(m_root);
  129.     m_root->saveNode(m_groupRow);
  130.     LexType type(LexType::Integer);
  131.     Plan_expr* expr = new Plan_expr_const(m_root, type, "1");
  132.     m_root->saveNode(expr);
  133.     m_groupRow->addExpr(expr);
  134.     m_groupRow = static_cast<Plan_expr_row*>(m_groupRow->analyze(ctx, ctl));
  135.     ctx_assert(ctx.ok());
  136.     ctx_assert(m_groupRow != 0);
  137. }
  138.     }
  139.     // check group by allowed
  140.     if (m_groupRow != 0) {
  141. if (! m_exprRow->isAllGroupBy(m_groupRow)) {
  142.     ctx.pushStatus(Error::Gen, "invalid GROUP BY expression in SELECT list");
  143.     return 0;
  144. }
  145. if (m_havingPred != 0) {
  146.     if (! m_havingPred->isGroupBy(m_groupRow)) {
  147. ctx.pushStatus(Error::Gen, "invalid GROUP BY expression in HAVING clause");
  148. return 0;
  149.     }
  150. }
  151. if (m_sortRow != 0) {
  152.     if (! m_sortRow->isAllGroupBy(m_groupRow)) {
  153. ctx.pushStatus(Error::Gen, "invalid GROUP BY expression in ORDER BY clause");
  154. return 0;
  155.     }
  156. }
  157.     }
  158.     // log top level predicate
  159.     {
  160. unsigned n = 0;
  161. for (PredList::iterator i = ctl.m_topcomp.begin(); i != ctl.m_topcomp.end(); i++)
  162.     ctx_log2(("top level pred %u: count tables = %u, not interp = %u",
  163.                      ++n, 
  164.                      (unsigned)(*i)->tableSet().size(), 
  165.                      (unsigned)(*i)->noInterp().size()));
  166.     }
  167.     // compose the raw query from lookups and scans
  168.     Plan_query* queryRaw = 0;
  169.     TableVector tableVector(1);
  170.     TableSet tsDone;
  171.     while (tableVector.size() < ctl.m_tableList.size()) {
  172. Plan_table* tableBest = 0;
  173. Plan_table::Index* indexBest = 0;
  174. for (unsigned n = 1; n < ctl.m_tableList.size(); n++) {
  175.     Plan_table* table = ctl.m_tableList[n];
  176.     if (tsDone.find(table) != tsDone.end())
  177. continue;
  178.     // get system table out of the way
  179.     if (table->dictTable().sysId()) {
  180. tableBest = table;
  181. break;
  182.     }
  183.     // find best match for primary key or index
  184.     for (unsigned i = 0; i <= table->indexCount(); i++) {
  185. Plan_table::Index& index = table->m_indexList[i];
  186. table->resolveSet(ctx, index, tsDone);
  187. if (! ctx.ok())
  188.     return 0;
  189. if (! index.m_keyFound)
  190.     continue;
  191. // prefer smaller dependency set, smaller rank, less unused keys
  192. int k;
  193. (k = (indexBest == 0)) ||
  194.     (k = (indexBest->m_keySet.size() - index.m_keySet.size())) ||
  195.     (k = (indexBest->m_rank - index.m_rank)) ||
  196.     (k = (indexBest->m_keyCountUnused - index.m_keyCountUnused));
  197. if (k > 0) {
  198.     tableBest = table;
  199.     indexBest = &index;
  200. }
  201.     }
  202. }
  203. Plan_query* queryNext = 0;
  204. Plan_table* tableNext = 0;
  205. Plan_query_scan* queryScan = 0; // for pushing interpreted program
  206. Plan_query_range* queryRange = 0; // ditto
  207. if (tableBest == 0) {
  208.     // scan first unprocessed table
  209.     for (unsigned n = 1; n < ctl.m_tableList.size(); n++) {
  210. Plan_table* table = ctl.m_tableList[n];
  211. if (tsDone.find(table) != tsDone.end())
  212.     continue;
  213. tableNext = table;
  214. break;
  215.     }
  216.     ctx_assert(tableNext != 0);
  217.     queryScan = new Plan_query_scan(m_root);
  218.     m_root->saveNode(queryScan);
  219.     queryScan->setTable(tableNext);
  220.     queryNext = queryScan;
  221.     ctx_log2(("optim: scan %s", tableNext->getPrintName()));
  222. } else if (tableBest->dictTable().sysId()) {
  223.     // "scan" system table
  224.     tableNext = tableBest;
  225.     Plan_query_sys* querySys = new Plan_query_sys(m_root);
  226.     m_root->saveNode(querySys);
  227.     querySys->setTable(tableNext);
  228.     queryNext = querySys;
  229.     ctx_log2(("optim: scan %s", tableNext->getPrintName()));
  230. } else if (indexBest->m_keySet.size() > 0) {
  231.     // scan first table this one depends on
  232.     const TableSet& keySet = indexBest->m_keySet;
  233.     for (unsigned n = 1; n < ctl.m_tableList.size(); n++) {
  234. Plan_table* table = ctl.m_tableList[n];
  235. if (keySet.find(table) == keySet.end())
  236.     continue;
  237. ctx_assert(tsDone.find(table) == tsDone.end());
  238. tableNext = table;
  239. break;
  240.     }
  241.     ctx_assert(tableNext != 0);
  242.     queryScan = new Plan_query_scan(m_root);
  243.     m_root->saveNode(queryScan);
  244.     queryScan->setTable(tableNext);
  245.     queryNext = queryScan;
  246.     ctx_log2(("optim: scan %s for %s", tableNext->getPrintName(), tableBest->getPrintName()));
  247. } else if (indexBest->m_rank == 0) {
  248.     // primary key depends only on processed tables
  249.     tableNext = tableBest;
  250.     Plan_query_lookup* queryLookup = new Plan_query_lookup(m_root);
  251.     m_root->saveNode(queryLookup);
  252.     queryLookup->setTable(tableNext);
  253.     queryNext = queryLookup;
  254.     ctx_log2(("optim: lookup %s", tableNext->getPrintName()));
  255. } else if (indexBest->m_rank == 1) {
  256.     // hash index key depends only on processed tables
  257.     tableNext = tableBest;
  258.     Plan_query_index* queryIndex = new Plan_query_index(m_root);
  259.     m_root->saveNode(queryIndex);
  260.     queryIndex->setTable(tableNext, indexBest);
  261.     queryNext = queryIndex;
  262.     ctx_log2(("optim: lookup %s via index %s", tableNext->getPrintName(), indexBest->m_dictIndex->getName().c_str()));
  263. } else if (indexBest->m_rank == 2) {
  264.     // ordered index key depends only on processed tables
  265.     tableNext = tableBest;
  266.     queryRange = new Plan_query_range(m_root);
  267.     m_root->saveNode(queryRange);
  268.     queryRange->setTable(tableNext, indexBest);
  269.     queryNext = queryRange;
  270.     ctx_log2(("optim: range scan %s via index %s", tableNext->getPrintName(), indexBest->m_dictIndex->getName().c_str()));
  271. } else {
  272.     ctx_assert(false);
  273. }
  274. if (queryRaw == 0) {
  275.     queryRaw = queryNext;
  276. } else {
  277.     Plan_query_join* queryJoin = new Plan_query_join(m_root);
  278.     m_root->saveNode(queryJoin);
  279.     queryJoin->setInner(queryRaw);
  280.     queryJoin->setOuter(queryNext);
  281.     queryRaw = queryJoin;
  282. }
  283. tableVector.push_back(tableNext);
  284. tsDone.insert(tableNext);
  285. // push down part of top level predicate to table scan or range scan
  286. Plan_pred* predPush = 0;
  287. Plan_pred* predInterp = 0;
  288. PredList::iterator i = ctl.m_topcomp.begin();
  289. while (i != ctl.m_topcomp.end()) {
  290.     const TableSet& ts = (*i)->tableSet();
  291.     if (! std::includes(tsDone.begin(), tsDone.end(), ts.begin(), ts.end())) {
  292. i++;
  293. continue;
  294.     }
  295.     predPush = predPush == 0 ? *i : predPush->opAnd(*i);
  296.     if (queryScan != 0) {
  297. const TableSet& ts2 = (*i)->noInterp();
  298. if (ts2.find(tableNext) == ts2.end())
  299.     predInterp = predInterp == 0 ? *i : predInterp->opAnd(*i);
  300.     }
  301.     if (queryRange != 0) {
  302. const TableSet& ts2 = (*i)->noInterp();
  303. if (ts2.find(tableNext) == ts2.end())
  304.     predInterp = predInterp == 0 ? *i : predInterp->opAnd(*i);
  305.     }
  306.     // remove it from top level predicate
  307.     PredList::iterator j = i;
  308.     i++;
  309.     ctl.m_topcomp.erase(j);
  310. }
  311. if (predPush != 0) {
  312.     Plan_query_filter* queryPush = new Plan_query_filter(m_root);
  313.     m_root->saveNode(queryPush);
  314.     queryPush->setQuery(queryRaw);
  315.     queryPush->setPred(predPush);
  316.     queryPush->m_topTable = tableNext;
  317.     queryRaw = queryPush;
  318. }
  319. if (predInterp != 0) {
  320.     if (queryScan != 0)
  321. queryScan->setInterp(predInterp);
  322.     else if (queryRange != 0)
  323. queryRange->setInterp(predInterp);
  324.     else
  325. ctx_assert(false);
  326. }
  327.     }
  328.     ctx_assert(ctl.m_topcomp.empty());
  329.     // set base for column position offsets
  330.     for (unsigned n = 1; n < tableVector.size(); n++) {
  331. Plan_table* table = tableVector[n];
  332. if (n == 1) {
  333.     table->m_resOff = 1;
  334. } else {
  335.     Plan_table* tablePrev = tableVector[n - 1];
  336.     table->m_resOff = tablePrev->m_resOff + tablePrev->m_exprColumns.size() - 1;
  337. }
  338.     }
  339.     // next level up is one of project, count, group by
  340.     Plan_query* queryTop;
  341.     if (m_groupRow == 0) {
  342. if (! m_exprRow->anyAggr()) {
  343.     Plan_query_project* queryProject = new Plan_query_project(m_root);
  344.     m_root->saveNode(queryProject);
  345.     queryProject->setQuery(queryRaw);
  346.     queryProject->setRow(m_exprRow);
  347.     queryProject->setLimit(m_limitOff, m_limitCnt);
  348.     queryTop = queryProject;
  349. } else {
  350.     ctx_assert(m_exprRow->allBound());
  351.     Plan_query_count* queryCount = new Plan_query_count(m_root);
  352.     m_root->saveNode(queryCount);
  353.     queryCount->setQuery(queryRaw);
  354.     queryCount->setRow(m_exprRow);
  355.     queryTop = queryCount;
  356. }
  357.     } else {
  358. Plan_query_group* queryGroup = new Plan_query_group(m_root);
  359. m_root->saveNode(queryGroup);
  360. queryGroup->setQuery(queryRaw);
  361. queryGroup->setDataRow(m_exprRow);
  362. queryGroup->setGroupRow(m_groupRow);
  363. if (m_havingPred != 0)
  364.     queryGroup->setHavingPred(m_havingPred);
  365. queryTop = queryGroup;
  366.     }
  367.     // optional sort becomes new top level
  368.     if (m_sortRow != 0) {
  369. Plan_query_sort* querySort = new Plan_query_sort(m_root);
  370. m_root->saveNode(querySort);
  371. querySort->setQuery(queryTop);
  372. querySort->setRow(m_sortRow);
  373. queryTop = querySort;
  374.     }
  375.     // optional distinct becomes new top level
  376.     if (m_distinct) {
  377. Plan_query_distinct* queryDistinct = new Plan_query_distinct(m_root);
  378. m_root->saveNode(queryDistinct);
  379. queryDistinct->setQuery(queryTop);
  380. queryTop = queryDistinct;
  381.     }
  382.     // return top node
  383.     return queryTop;
  384. }
  385. Exec_base*
  386. Plan_select::codegen(Ctx& ctx, Ctl& ctl)
  387. {   
  388.     ctx_assert(false);
  389.     return 0;
  390. }    
  391. void
  392. Plan_select::print(Ctx& ctx)
  393. {
  394.     ctx.print(" [select");
  395.     Plan_base* a[] = { m_tableList, m_exprRow, m_pred, m_groupRow, m_havingPred };
  396.     printList(ctx, a, 5);
  397.     ctx.print("]");
  398. }