Code_insert.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 <dictionary/DictTable.hpp>
  15. #include <dictionary/DictColumn.hpp>
  16. #include "Code_insert.hpp"
  17. #include "Code_query_repeat.hpp"
  18. #include "Code_query_project.hpp"
  19. #include "Code_table.hpp"
  20. #include "Code_root.hpp"
  21. // Plan_insert
  22. Plan_insert::~Plan_insert()
  23. {
  24. }
  25. Plan_base*
  26. Plan_insert::analyze(Ctx& ctx, Ctl& ctl)
  27. {
  28.     stmtArea().stmtInfo().setName(Stmt_name_insert);
  29.     ctx_assert(m_table != 0);
  30.     m_table->analyze(ctx, ctl);
  31.     if (! ctx.ok())
  32. return 0;
  33.     // handle MySql syntax
  34.     if (m_mysqlRow != 0) {
  35. setDmlRow(m_mysqlRow->m_dmlRow);
  36. setExprRow(m_mysqlRow->m_exprRow);
  37. m_mysqlRow = 0;
  38.     }
  39.     if (m_dmlRow == 0) {
  40. // construct column list
  41. setDmlRow(new Plan_dml_row(m_root));
  42. m_root->saveNode(m_dmlRow);
  43. const DictTable& dictTable = m_table->dictTable();
  44. unsigned n = dictTable.getSize();
  45. for (unsigned i = 1; i <= n; i++) {
  46.     DictColumn* dictColumn = dictTable.getColumn(i);
  47.     Plan_dml_column* column = new Plan_dml_column(m_root, dictColumn->getName());
  48.     m_root->saveNode(column);
  49.     m_dmlRow->addColumn(column);
  50. }
  51.     }
  52.     // set name resolution scope
  53.     ctl.m_tableList.resize(1 + 1); // indexed from 1
  54.     ctl.m_tableList[1] = m_table;
  55.     // analyze the dml columns
  56.     m_dmlRow->analyze(ctx, ctl);
  57.     if (! ctx.ok())
  58. return 0;
  59.     ctl.m_dmlRow = m_dmlRow; // row type to convert to
  60.     if (m_query != 0) {
  61. m_query->analyze(ctx, ctl);
  62. if (! ctx.ok())
  63.     return 0;
  64.     } else if (m_select == 0) {
  65. // analyze the expression row
  66. m_exprRow->analyze(ctx, ctl);
  67. if (! ctx.ok())
  68.     return 0;
  69. // transform the row into query
  70. Plan_query_repeat* queryRepeat = new Plan_query_repeat(m_root, 1);
  71. m_root->saveNode(queryRepeat);
  72. Plan_query_project* queryProject = new Plan_query_project(m_root);
  73. m_root->saveNode(queryProject);
  74. queryProject->setQuery(queryRepeat);
  75. queryProject->setRow(m_exprRow);
  76. setQuery(queryProject);
  77.     } else {
  78. // analyze the select into query
  79. Plan_query* query = static_cast<Plan_query*>(m_select->analyze(ctx, ctl));
  80. if (! ctx.ok())
  81.     return 0;
  82. setQuery(query);
  83.     }
  84.     return this;
  85. }
  86. void
  87. Plan_insert::describe(Ctx& ctx)
  88. {
  89.     stmtArea().setFunction(ctx, "INSERT", SQL_DIAG_INSERT);
  90. }
  91. Exec_base*
  92. Plan_insert::codegen(Ctx& ctx, Ctl& ctl)
  93. {
  94.     // create code for the query
  95.     ctx_assert(m_query != 0);
  96.     Exec_query* execQuery = static_cast<Exec_query*>(m_query->codegen(ctx, ctl));
  97.     if (! ctx.ok())
  98. return 0;
  99.     ctx_assert(execQuery != 0);
  100.     // set up
  101.     ctx_assert(m_table != 0);
  102.     const BaseString& tableName = m_table->getName();
  103.     const DictTable& dictTable = m_table->dictTable();
  104.     const ColumnVector& columns = m_table->dmlColumns();
  105.     ctx_assert(columns.size() > 0);
  106.     const unsigned attrCount = columns.size() - 1;
  107.     // create the code
  108.     Exec_insert::Code& code = *new Exec_insert::Code();
  109.     code.m_insertOp = m_insertOp;
  110.     code.m_tableName = strcpy(new char[tableName.length() + 1], tableName.c_str());
  111.     code.m_attrCount = attrCount;
  112.     code.m_attrId = new NdbAttrId[1 + attrCount];
  113.     code.m_isKey = new bool[1 + attrCount];
  114.     code.m_attrId[0] = (NdbAttrId)-1;
  115.     code.m_tupleId = dictTable.tupleId(); // maybe 0
  116.     code.m_autoIncrement = dictTable.autoIncrement(); // maybe 0
  117.     unsigned k;
  118.     if ((k = code.m_tupleId) != 0 || (k = code.m_autoIncrement) != 0) {
  119. const DictColumn& dictColumn = *dictTable.getColumn(k);
  120. code.m_idType = dictColumn.sqlType();
  121.     }
  122.     for (unsigned i = 1; i <= attrCount; i++) {
  123. Plan_column* column = columns[i];
  124. ctx_assert(column != 0);
  125. const DictColumn& dictColumn = column->dictColumn();
  126. code.m_attrId[i] = dictColumn.getAttrId();
  127. code.m_isKey[i] = dictColumn.isKey();
  128.     }
  129.     // default values XXX a mess
  130.     code.m_defaultCount = 0;
  131.     for (unsigned j = 1; j <= dictTable.getSize(); j++) {
  132. const DictColumn& dictColumn = *dictTable.getColumn(j);
  133. if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId()))
  134.     code.m_defaultCount++;
  135.     }
  136.     if (code.m_defaultCount != 0) {
  137. code.m_defaultId = new NdbAttrId[1 + code.m_defaultCount];
  138. for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
  139.     const DictColumn& dictColumn = *dictTable.getColumn(j);
  140.     if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId()))
  141. code.m_defaultId[++i] = dictColumn.getAttrId();
  142. }
  143. SqlSpecs sqlSpecs(code.m_defaultCount);
  144. for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
  145.     const DictColumn& dictColumn = *dictTable.getColumn(j);
  146.     if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId())) {
  147. SqlSpec sqlSpec(dictColumn.sqlType(), SqlSpec::Physical);
  148. sqlSpecs.setEntry(++i, sqlSpec);
  149.     }
  150. }
  151. code.m_defaultValue = new SqlRow(sqlSpecs);
  152. for (unsigned i = 0, j = 1; j <= dictTable.getSize(); j++) {
  153.     const DictColumn& dictColumn = *dictTable.getColumn(j);
  154.     if (dictColumn.getDefaultValue() != 0 && ! code.findAttrId(dictColumn.getAttrId())) {
  155. const char* defaultValue = dictColumn.getDefaultValue();
  156. ExtType extType(ExtType::Char);
  157. ExtSpec extSpec(extType);
  158. SQLINTEGER ind = SQL_NTS;
  159. ExtField extField(extSpec, (SQLPOINTER)defaultValue, 0, &ind);
  160. SqlField& f = code.m_defaultValue->getEntry(++i);
  161. f.copyin(ctx, extField);
  162. if (! ctx.ok())
  163.     return 0;
  164.     }
  165. }
  166.     }
  167.     // create the exec
  168.     Exec_insert* exec = new Exec_insert(ctl.m_execRoot);
  169.     ctl.m_execRoot->saveNode(exec);
  170.     exec->setCode(code);
  171.     exec->setQuery(execQuery);
  172.     return exec;
  173. }
  174. void
  175. Plan_insert::print(Ctx& ctx)
  176. {
  177.     ctx.print(" [%s", m_insertOp == Insert_op_insert ? "insert" : "write");
  178.     Plan_base* a[] = { m_table, m_dmlRow, m_exprRow, m_query };
  179.     printList(ctx, a, 4);
  180.     ctx.print("]");
  181. }
  182. // Exec_insert
  183. Exec_insert::Code::~Code()
  184. {
  185.     delete[] m_tableName;
  186.     delete[] m_attrId;
  187.     delete[] m_isKey;
  188.     delete[] m_defaultId;
  189.     delete m_defaultValue;
  190. }
  191. bool
  192. Exec_insert::Code::findAttrId(NdbAttrId attrId) const
  193. {
  194.     for (unsigned i = 1; i <= m_attrCount; i++) {
  195. if (m_attrId[i] == attrId)
  196.     return true;
  197.     }
  198.     return false;
  199. }
  200. Exec_insert::Data::~Data()
  201. {
  202. }
  203. Exec_insert::~Exec_insert()
  204. {
  205. }
  206. void
  207. Exec_insert::alloc(Ctx& ctx, Ctl& ctl)
  208. {
  209.     // allocate the query
  210.     ctx_assert(m_query != 0);
  211.     m_query->alloc(ctx, ctl);
  212.     // create data
  213.     Data& data = *new Data();
  214.     setData(data);
  215. }
  216. void
  217. Exec_insert::close(Ctx& ctx)
  218. {
  219. }
  220. void
  221. Exec_insert::print(Ctx& ctx)
  222. {
  223.     const Code& code = getCode();
  224.     ctx_assert(m_query != 0);
  225.     ctx.print(" [insert");
  226.     ctx.print(" attrId=");
  227.     for (unsigned i = 1; i <= code.m_attrCount; i++) {
  228. if (i > 1)
  229.     ctx.print(",");
  230. ctx.print("%u", (unsigned)code.m_attrId[i]);
  231.     }
  232.     ctx.print(" table=%s", code.m_tableName);
  233.     m_query->print(ctx);
  234.     ctx.print("]");
  235. }