1 24 25 package com.mckoi.database.interpret; 26 27 import com.mckoi.database.*; 28 import com.mckoi.util.IntegerVector; 29 import java.util.Vector ; 30 import java.util.ArrayList ; 31 import java.util.List ; 32 33 38 39 public class CreateTable extends Statement { 40 41 44 boolean temporary = false; 45 46 49 boolean only_if_not_exists = false; 50 51 54 String table_name; 55 56 59 ArrayList columns; 60 61 64 ArrayList constraints; 65 66 72 75 private TableName tname; 76 77 78 87 91 void addConstraintDef(ConstraintDef constraint) { 92 constraints.add(constraint); 93 } 94 95 104 108 DataTableDef createDataTableDef() throws DatabaseException { 109 DataTableDef table_def = new DataTableDef(); 111 table_def.setTableName(tname); 112 table_def.setTableClass("com.mckoi.database.VariableSizeDataTableFile"); 113 114 for (int i = 0; i < columns.size(); ++i) { 117 DataTableColumnDef cd = (DataTableColumnDef) columns.get(i); 118 table_def.addColumn(cd); 119 } 120 121 return table_def; 122 } 123 124 125 129 static void addSchemaConstraint(DatabaseConnection manager, 130 TableName table, ConstraintDef constraint) 131 throws DatabaseException { 132 if (constraint.type == ConstraintDef.PRIMARY_KEY) { 133 manager.addPrimaryKeyConstraint(table, 134 constraint.getColumnList(), constraint.deferred, constraint.name); 135 } 136 else if (constraint.type == ConstraintDef.FOREIGN_KEY) { 137 TableName ref_table = 139 TableName.resolve(constraint.reference_table_name); 140 String update_rule = constraint.getUpdateRule().toUpperCase(); 141 String delete_rule = constraint.getDeleteRule().toUpperCase(); 142 if (table.getSchema().equals(ref_table.getSchema())) { 143 manager.addForeignKeyConstraint( 144 table, constraint.getColumnList(), 145 ref_table, constraint.getColumnList2(), 146 delete_rule, update_rule, constraint.deferred, constraint.name); 147 } 148 else { 149 throw new DatabaseException("Foreign key reference error: " + 150 "Not permitted to reference a table outside of the schema: " + 151 table + " -> " + ref_table); 152 } 153 } 154 else if (constraint.type == ConstraintDef.UNIQUE) { 155 manager.addUniqueConstraint(table, constraint.getColumnList(), 156 constraint.deferred, constraint.name); 157 } 158 else if (constraint.type == ConstraintDef.CHECK) { 159 manager.addCheckConstraint(table, constraint.original_check_expression, 160 constraint.deferred, constraint.name); 161 } 162 else { 163 throw new DatabaseException("Unrecognized constraint type."); 164 } 165 } 166 167 171 static DataTableColumnDef convertColumnDef(ColumnDef cdef) { 172 TType type = cdef.type; 173 174 DataTableColumnDef dtcdef = new DataTableColumnDef(); 175 dtcdef.setName(cdef.name); 176 dtcdef.setNotNull(cdef.isNotNull()); 177 dtcdef.setFromTType(type); 178 179 if (cdef.index_str != null) { 180 dtcdef.setIndexScheme(cdef.index_str); 181 } 182 if (cdef.default_expression != null) { 183 dtcdef.setDefaultExpression(cdef.original_default_expression); 184 } 185 186 dtcdef.initTTypeInfo(); 187 return dtcdef; 188 } 189 190 193 void setupAllConstraints() throws DatabaseException { 194 for (int i = 0; i < constraints.size(); ++i) { 195 ConstraintDef constraint = (ConstraintDef) constraints.get(i); 196 197 addSchemaConstraint(database, tname, constraint); 199 } 200 } 201 202 203 204 205 207 public void prepare() throws DatabaseException { 208 209 temporary = cmd.getBoolean("temporary"); 211 only_if_not_exists = cmd.getBoolean("only_if_not_exists"); 212 table_name = (String ) cmd.getObject("table_name"); 213 ArrayList column_list = (ArrayList ) cmd.getObject("column_list"); 214 constraints = (ArrayList ) cmd.getObject("constraint_list"); 215 216 int size = column_list.size(); 218 columns = new ArrayList (size); 219 for (int i = 0; i < size; ++i) { 220 ColumnDef cdef = (ColumnDef) column_list.get(i); 221 columns.add(convertColumnDef(cdef)); 222 } 223 224 226 String schema_name = database.getCurrentSchema(); 227 tname = TableName.resolve(schema_name, table_name); 228 229 String name_strip = tname.getName(); 230 231 if (name_strip.indexOf('.') != -1) { 232 throw new DatabaseException("Table name can not contain '.' character."); 233 } 234 235 final boolean ignores_case = database.isInCaseInsensitiveMode(); 236 237 ColumnChecker checker = new ColumnChecker() { 239 240 String resolveColumnName(String col_name) throws DatabaseException { 241 String found_col = null; 243 for (int n = 0; n < columns.size(); ++n) { 244 DataTableColumnDef col = (DataTableColumnDef) columns.get(n); 245 if (!ignores_case) { 246 if (col.getName().equals(col_name)) { 247 return col_name; 248 } 249 } 250 else { 251 if (col.getName().equalsIgnoreCase(col_name)) { 252 if (found_col != null) { 253 throw new DatabaseException("Ambiguous column name '" + 254 col_name + "'"); 255 } 256 found_col = col.getName(); 257 } 258 } 259 } 260 return found_col; 261 } 262 263 }; 264 265 ArrayList unique_column_list = new ArrayList (); 266 ArrayList primary_key_column_list = new ArrayList (); 267 268 for (int i = 0; i < columns.size(); ++i) { 271 DataTableColumnDef cdef = (DataTableColumnDef) columns.get(i); 272 ColumnDef model_cdef = (ColumnDef) column_list.get(i); 273 checker.checkExpression(cdef.getDefaultExpression(database.getSystem())); 274 String col_name = cdef.getName(); 275 cdef.setName(checker.stripTableName(name_strip, col_name)); 277 if (model_cdef.isUnique()) { 279 unique_column_list.add(col_name); 280 } 281 if (model_cdef.isPrimaryKey()) { 283 primary_key_column_list.add(col_name); 284 } 285 } 286 287 if (unique_column_list.size() > 0) { 289 ConstraintDef constraint = new ConstraintDef(); 290 constraint.setUnique(unique_column_list); 291 addConstraintDef(constraint); 292 } 293 if (primary_key_column_list.size() > 0) { 294 ConstraintDef constraint = new ConstraintDef(); 295 constraint.setPrimaryKey(primary_key_column_list); 296 addConstraintDef(constraint); 297 } 298 299 for (int i = 0; i < constraints.size(); ++i) { 301 ConstraintDef constraint = (ConstraintDef) constraints.get(i); 302 checker.stripColumnList(name_strip, constraint.column_list); 303 if (constraint.type == ConstraintDef.FOREIGN_KEY) { 305 checker.stripColumnList(constraint.reference_table_name, 306 constraint.column_list2); 307 TableName ref_tname = 308 resolveTableName(constraint.reference_table_name, database); 309 if (database.isInCaseInsensitiveMode()) { 310 ref_tname = database.tryResolveCase(ref_tname); 311 } 312 constraint.reference_table_name = ref_tname.toString(); 313 314 DataTableDef ref_table_def; 315 if (database.tableExists(ref_tname)) { 316 ref_table_def = database.getDataTableDef(ref_tname); 318 } 319 else if (ref_tname.equals(tname)) { 320 ref_table_def = createDataTableDef(); 322 } 323 else { 324 throw new DatabaseException( 325 "Referenced table '" + ref_tname + "' in constraint '" + 326 constraint.name + "' does not exist."); 327 } 328 ref_table_def.resolveColumnsInArray(database, constraint.column_list2); 330 331 } 332 checker.checkExpression(constraint.check_expression); 333 checker.checkColumnList(constraint.column_list); 334 } 335 336 } 337 338 public Table evaluate() throws DatabaseException { 339 340 DatabaseQueryContext context = new DatabaseQueryContext(database); 341 342 boolean ignore_case = database.isInCaseInsensitiveMode(); 344 SchemaDef schema = 345 database.resolveSchemaCase(tname.getSchema(), ignore_case); 346 if (schema == null) { 347 throw new DatabaseException("Schema '" + tname.getSchema() + 348 "' doesn't exist."); 349 } 350 else { 351 tname = new TableName(schema.getName(), tname.getName()); 352 } 353 354 if (!database.getDatabase().canUserCreateTableObject(context, 356 user, tname)) { 357 throw new UserAccessException( 358 "User not permitted to create table: " + table_name); 359 } 360 361 362 363 365 366 367 368 if (!database.tableExists(tname)) { 370 371 DataTableDef table_def = createDataTableDef(); 374 database.createTable(table_def); 375 376 database.getGrantManager().addGrant( 379 Privileges.TABLE_ALL_PRIVS, GrantManager.TABLE, tname.toString(), 380 user.getUserName(), true, Database.INTERNAL_SECURE_USERNAME); 381 382 setupAllConstraints(); 384 385 return FunctionTable.resultTable(context, 0); 387 } 388 389 if (only_if_not_exists == false) { 391 throw new DatabaseException("Table '" + tname + "' already exists."); 392 } 393 394 return FunctionTable.resultTable(context, 0); 397 398 } 399 400 } 401 | Popular Tags |