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

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 "Code_create_row.hpp"
  14. #include "Code_root.hpp"
  15. Plan_create_row::~Plan_create_row()
  16. {
  17. }
  18. Plan_base*
  19. Plan_create_row::analyze(Ctx& ctx, Ctl& ctl)
  20. {
  21.     // check for duplicate column name
  22.     for (unsigned i = 1, n = countColumn(); i < n; i++) {
  23. const BaseString& a = getColumn(i)->getName();
  24. for (unsigned i2 = i + 1; i2 <= n; i2++) {
  25.     const BaseString& a2 = getColumn(i2)->getName();
  26.     if (strcmp(a.c_str(), a2.c_str()) == 0) {
  27. ctx.pushStatus(Error::Gen, "duplicate column %s", a.c_str());
  28. return 0;
  29.     }
  30. }
  31.     }
  32.     // move single-column primary key constraint to constraint list
  33.     for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  34. Plan_ddl_column* column = getColumn(i);
  35. if (column->m_primaryKey) {
  36.     Plan_ddl_row* ddlRow = new Plan_ddl_row(m_root);
  37.     m_root->saveNode(ddlRow);
  38.     ddlRow->addColumn(column);
  39.     Plan_ddl_constr* constr = new Plan_ddl_constr(m_root);
  40.     m_root->saveNode(constr);
  41.     constr->setRow(ddlRow);
  42.     addConstr(constr);
  43.     column->m_primaryKey = false; // will be set again
  44. }
  45.     }
  46.     // check primary key constraints
  47.     if (countConstr() < 1) {
  48. ctx.pushStatus(Error::Gen, "table must have a primary key");
  49. return 0;
  50.     }
  51.     if (countConstr() > 1) {
  52. ctx.pushStatus(Error::Gen, "table can have only one primary key");
  53. return 0;
  54.     }
  55.     Plan_ddl_row* ddlRow = getConstr(1)->getRow();
  56.     for (unsigned i = 1, n = ddlRow->countColumn(); i <= n; i++) {
  57. Plan_ddl_column* column = ddlRow->getColumn(i);
  58. const BaseString& a = column->getName();
  59. bool found = false;
  60. for (unsigned i2 = 1, n2 = countColumn(); i2 <= n2; i2++) {
  61.     Plan_ddl_column* column2 = getColumn(i2);
  62.     const BaseString& a2 = column2->getName();
  63.     if (strcmp(a.c_str(), a2.c_str()) != 0)
  64. continue;
  65.     if (column2->getPrimaryKey()) {
  66. ctx.pushStatus(Error::Gen, "duplicate primary key constraint on %s", a.c_str());
  67. return 0;
  68.     }
  69.     column2->setPrimaryKey();
  70.     found = true;
  71.     break;
  72. }
  73. if (! found) {
  74.     ctx.pushStatus(Error::Gen, "undefined primary key column %s", a.c_str());
  75.     return 0;
  76. }
  77.     }
  78.     // analyze column types
  79.     for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  80. getColumn(i)->analyze(ctx, ctl);
  81. if (! ctx.ok())
  82.     return 0;
  83.     }
  84.     // check TupleId
  85.     unsigned tupleId = 0;
  86.     for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  87. Plan_ddl_column* column = getColumn(i);
  88. if (! column->getTupleId())
  89.     continue;
  90. if (i != 1) {
  91.     ctx.pushStatus(Error::Gen, "tuple id column %u is not first column", i);
  92.     return 0;
  93. }
  94. if (tupleId != 0) { // cannot happen now since attr name is fixed
  95.     ctx.pushStatus(Error::Gen, "duplicate tuple id column %u", i);
  96.     return 0;
  97. }
  98. tupleId = i;
  99.     }
  100.     if (tupleId != 0) {
  101. for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  102.     Plan_ddl_column* column = getColumn(i);
  103.     if (i == tupleId)
  104. continue;
  105.     if (! column->getPrimaryKey())
  106. continue;
  107.     ctx.pushStatus(Error::Gen, "cannot have both tuple id and other primary key column %u", i);
  108.     return 0;
  109. }
  110.     }
  111.     // check auto-increment
  112.     unsigned autoIncrement = 0;
  113.     for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  114. Plan_ddl_column* column = getColumn(i);
  115. if (! column->getAutoIncrement())
  116.     continue;
  117. if (autoIncrement != 0) {
  118.     ctx.pushStatus(Error::Gen, "duplicate auto-increment column %u", i);
  119.     return 0;
  120. }
  121. autoIncrement = i;
  122.     }
  123.     if (autoIncrement != 0) {
  124. for (unsigned i = 1, n = countColumn(); i <= n; i++) {
  125.     Plan_ddl_column* column = getColumn(i);
  126.     if (i == autoIncrement)
  127. continue;
  128.     if (! column->getPrimaryKey())
  129. continue;
  130.     ctx.pushStatus(Error::Gen, "cannot have both auto-increment column and other primary key column %u", i);
  131.     return 0;
  132. }
  133.     }
  134.     return this;
  135. }
  136. Exec_base*
  137. Plan_create_row::codegen(Ctx& ctx, Ctl& ctl)
  138. {
  139.     ctx_assert(false);
  140.     return 0;
  141. }
  142. void
  143. Plan_create_row::print(Ctx& ctx)
  144. {
  145.     ctx.print(" [create_row");
  146.     for (unsigned i = 1; i <= countColumn(); i++) {
  147. Plan_base* a = m_columnList[i];
  148. printList(ctx, &a, 1);
  149.     }
  150.     for (unsigned i = 1; i <= countConstr(); i++) {
  151. Plan_base* a = m_constrList[i];
  152. printList(ctx, &a, 1);
  153.     }
  154. }