File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\command\ddl\CreateTable.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.command.ddl;
8
9 import java.util.ArrayList;
10 import org.h2.command.CommandInterface;
11 import org.h2.command.dml.Insert;
12 import org.h2.command.dml.Query;
13 import org.h2.constant.ErrorCode;
14 import org.h2.engine.Database;
15 import org.h2.engine.Session;
16 import org.h2.expression.Expression;
17 import org.h2.message.DbException;
18 import org.h2.schema.Schema;
19 import org.h2.schema.Sequence;
20 import org.h2.table.Column;
21 import org.h2.table.IndexColumn;
22 import org.h2.table.Table;
23 import org.h2.util.New;
24 import org.h2.value.DataType;
25
26 /**
27 * This class represents the statement
28 * CREATE TABLE
29 */
30 public class CreateTable extends SchemaCommand {
31
32 private final CreateTableData data = new CreateTableData();
33 private final ArrayList<DefineCommand> constraintCommands = New.arrayList();
34 private IndexColumn[] pkColumns;
35 private boolean ifNotExists;
36 private boolean onCommitDrop;
37 private boolean onCommitTruncate;
38 private Query asQuery;
39 private String comment;
40 private boolean sortedInsertMode;
41
42 public CreateTable(Session session, Schema schema) {
43 super(session, schema);
44 data.persistIndexes = true;
45 data.persistData = true;
46 }
47
48 public void setQuery(Query query) {
49 this.asQuery = query;
50 }
51
52 public void setTemporary(boolean temporary) {
53 data.temporary = temporary;
54 }
55
56 public void setTableName(String tableName) {
57 data.tableName = tableName;
58 }
59
60 /**
61 * Add a column to this table.
62 *
63 * @param column the column to add
64 */
65 public void addColumn(Column column) {
66 data.columns.add(column);
67 }
68
69 /**
70 * Add a constraint statement to this statement.
71 * The primary key definition is one possible constraint statement.
72 *
73 * @param command the statement to add
74 */
75 public void addConstraintCommand(DefineCommand command) {
76 if (command instanceof CreateIndex) {
77 constraintCommands.add(command);
78 } else {
79 AlterTableAddConstraint con = (AlterTableAddConstraint) command;
80 boolean alreadySet;
81 if (con.getType() == CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY) {
82 alreadySet = setPrimaryKeyColumns(con.getIndexColumns());
83 } else {
84 alreadySet = false;
85 }
86 if (!alreadySet) {
87 constraintCommands.add(command);
88 }
89 }
90 }
91
92 public void setIfNotExists(boolean ifNotExists) {
93 this.ifNotExists = ifNotExists;
94 }
95
96 public int update() {
97 if (!transactional) {
98 session.commit(true);
99 }
100 Database db = session.getDatabase();
101 if (!db.isPersistent()) {
102 data.persistIndexes = false;
103 }
104 if (getSchema().findTableOrView(session, data.tableName) != null) {
105 if (ifNotExists) {
106 return 0;
107 }
108 throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1, data.tableName);
109 }
110 if (asQuery != null) {
111 asQuery.prepare();
112 if (data.columns.size() == 0) {
113 generateColumnsFromQuery();
114 } else if (data.columns.size() != asQuery.getColumnCount()) {
115 throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
116 }
117 }
118 if (pkColumns != null) {
119 for (Column c : data.columns) {
120 for (IndexColumn idxCol : pkColumns) {
121 if (c.getName().equals(idxCol.columnName)) {
122 c.setNullable(false);
123 }
124 }
125 }
126 }
127 data.id = getObjectId();
128 data.create = create;
129 data.session = session;
130 boolean isSessionTemporary = data.temporary && !data.globalTemporary;
131 if (!isSessionTemporary) {
132 db.lockMeta(session);
133 }
134 Table table = getSchema().createTable(data);
135 ArrayList<Sequence> sequences = New.arrayList();
136 for (Column c : data.columns) {
137 if (c.isAutoIncrement()) {
138 int objId = getObjectId();
139 c.convertAutoIncrementToSequence(session, getSchema(), objId, data.temporary);
140 }
141 Sequence seq = c.getSequence();
142 if (seq != null) {
143 sequences.add(seq);
144 }
145 }
146 table.setComment(comment);
147 if (isSessionTemporary) {
148 if (onCommitDrop) {
149 table.setOnCommitDrop(true);
150 }
151 if (onCommitTruncate) {
152 table.setOnCommitTruncate(true);
153 }
154 session.addLocalTempTable(table);
155 } else {
156 db.lockMeta(session);
157 db.addSchemaObject(session, table);
158 }
159 try {
160 for (Column c : data.columns) {
161 c.prepareExpression(session);
162 }
163 for (Sequence sequence : sequences) {
164 table.addSequence(sequence);
165 }
166 for (DefineCommand command : constraintCommands) {
167 command.setTransactional(transactional);
168 command.update();
169 }
170 if (asQuery != null) {
171 boolean old = session.isUndoLogEnabled();
172 try {
173 session.setUndoLogEnabled(false);
174 Insert insert = null;
175 insert = new Insert(session);
176 insert.setSortedInsertMode(sortedInsertMode);
177 insert.setQuery(asQuery);
178 insert.setTable(table);
179 insert.setInsertFromSelect(true);
180 insert.prepare();
181 insert.update();
182 } finally {
183 session.setUndoLogEnabled(old);
184 }
185 }
186 } catch (DbException e) {
187 db.checkPowerOff();
188 db.removeSchemaObject(session, table);
189 if (!transactional) {
190 session.commit(true);
191 }
192 throw e;
193 }
194 return 0;
195 }
196
197 private void generateColumnsFromQuery() {
198 int columnCount = asQuery.getColumnCount();
199 ArrayList<Expression> expressions = asQuery.getExpressions();
200 for (int i = 0; i < columnCount; i++) {
201 Expression expr = expressions.get(i);
202 int type = expr.getType();
203 String name = expr.getAlias();
204 long precision = expr.getPrecision();
205 int displaySize = expr.getDisplaySize();
206 DataType dt = DataType.getDataType(type);
207 if (precision > 0 && (dt.defaultPrecision == 0 ||
208 (dt.defaultPrecision > precision && dt.defaultPrecision < Byte.MAX_VALUE))) {
209 // dont' set precision to MAX_VALUE if this is the default
210 precision = dt.defaultPrecision;
211 }
212 int scale = expr.getScale();
213 if (scale > 0 && (dt.defaultScale == 0 ||
214 (dt.defaultScale > scale && dt.defaultScale < precision))) {
215 scale = dt.defaultScale;
216 }
217 if (scale > precision) {
218 precision = scale;
219 }
220 Column col = new Column(name, type, precision, scale, displaySize);
221 addColumn(col);
222 }
223 }
224
225 /**
226 * Sets the primary key columns, but also check if a primary key
227 * with different columns is already defined.
228 *
229 * @param columns the primary key columns
230 * @return true if the same primary key columns where already set
231 */
232 private boolean setPrimaryKeyColumns(IndexColumn[] columns) {
233 if (pkColumns != null) {
234 int len = columns.length;
235 if (len != pkColumns.length) {
236 throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
237 }
238 for (int i = 0; i < len; i++) {
239 if (!columns[i].columnName.equals(pkColumns[i].columnName)) {
240 throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
241 }
242 }
243 return true;
244 }
245 this.pkColumns = columns;
246 return false;
247 }
248
249 public void setPersistIndexes(boolean persistIndexes) {
250 data.persistIndexes = persistIndexes;
251 }
252
253 public void setGlobalTemporary(boolean globalTemporary) {
254 data.globalTemporary = globalTemporary;
255 }
256
257 /**
258 * This temporary table is dropped on commit.
259 */
260 public void setOnCommitDrop() {
261 this.onCommitDrop = true;
262 }
263
264 /**
265 * This temporary table is truncated on commit.
266 */
267 public void setOnCommitTruncate() {
268 this.onCommitTruncate = true;
269 }
270
271 public void setComment(String comment) {
272 this.comment = comment;
273 }
274
275 public void setPersistData(boolean persistData) {
276 data.persistData = persistData;
277 if (!persistData) {
278 data.persistIndexes = false;
279 }
280 }
281
282 public void setSortedInsertMode(boolean sortedInsertMode) {
283 this.sortedInsertMode = sortedInsertMode;
284 }
285
286 public void setTableEngine(String tableEngine) {
287 data.tableEngine = tableEngine;
288 }
289
290 public void setHidden(boolean isHidden) {
291 data.isHidden = isHidden;
292 }
293
294 public int getType() {
295 return CommandInterface.CREATE_TABLE;
296 }
297
298 }
299