KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > TableWorks


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb;
33
34 import org.hsqldb.HsqlNameManager.HsqlName;
35 import org.hsqldb.index.RowIterator;
36 import org.hsqldb.lib.ArrayUtil;
37 import org.hsqldb.lib.HashSet;
38
39 /**
40  * The methods in this class perform alterations to the structure of an
41  * existing table which may result in a new Table object
42  *
43  * @author fredt@users
44  * @version 1.8.0
45  * @since 1.7.0
46  */

47 class TableWorks {
48
49     private Table table;
50     private Session session;
51
52     TableWorks(Session session, Table table) {
53         this.table = table;
54         this.session = session;
55     }
56
57     Table getTable() {
58         return table;
59     }
60
61     /**
62      * Creates a foreign key according to current sql.strict_fk or
63      * sql.strong_fk settings. Foreign keys are enforced via indexes on both
64      * the referencing (child) and referenced (parent) tables.
65      * <p>
66      * In versions 1.7.0 and 1.7.1 some non-standard features were supported
67      * for compatibility with older databases. These allowed foreign keys
68      * to be created without the prior existence of a unique constraint on
69      * the referenced columns.
70      * <p>
71      * In version 1.7.2, a unique constraint on the referenced columns must
72      * exist.
73      *
74      * The non-unique index on the referencing table is now always created
75      * whether or not a PK or unique constraint index on the columns exist.
76      * This closes the loopholes opened by the introduction of ALTER TABLE
77      * for adding foreign keys.
78      *
79      * Foriegn keys on temp tables can reference other temp tables with the
80      * same rules above. Foreign keys on permanent tables cannot reference
81      * temp tables.
82      *
83      * Duplicate foreign keys are now disallowed.
84      *
85      * -- The unique index on the referenced table must always belong to a
86      * constraint (PK or UNIQUE). Otherwise after a SHUTDOWN and restart the
87      * index will not exist at the time of creation of the foreign key when
88      * the foreign key is referencing the same table.
89      *
90      * -- The non-unique index on the referencing table is always created
91      * regardless of any existing index. This allows the foreign key
92      * constraint to be dropped when required.
93      *
94      *
95      * (fred@users)
96      *
97      * @param fkcol
98      * @param expcol
99      * @param name foreign key name
100      * @param expTable
101      * @param deleteAction
102      * @param updateAction
103      * @throws HsqlException
104      */

105     void createForeignKey(int[] fkcol, int[] expcol, HsqlName name,
106                           Table mainTable, int deleteAction,
107                           int updateAction) throws HsqlException {
108
109         table.database.schemaManager.checkConstraintExists(name.name,
110                 table.getSchemaName(), false);
111
112         // name check
113
if (table.getConstraint(name.name) != null) {
114             throw Trace.error(Trace.CONSTRAINT_ALREADY_EXISTS);
115         }
116
117         // existing FK check
118
if (table.getConstraintForColumns(mainTable, expcol, fkcol) != null) {
119             throw Trace.error(Trace.CONSTRAINT_ALREADY_EXISTS);
120         }
121
122         if (mainTable.isTemp() != table.isTemp()) {
123             throw Trace.error(Trace.FOREIGN_KEY_NOT_ALLOWED);
124         }
125
126         boolean isSelf = table == mainTable;
127         int offset = table.database.schemaManager.getTableIndex(table);
128         boolean isforward =
129             offset != -1
130             && offset < table.database.schemaManager.getTableIndex(mainTable);
131         Index exportindex =
132             mainTable.getUniqueConstraintIndexForColumns(expcol);
133
134         if (exportindex == null) {
135             throw Trace.error(Trace.SQL_CONSTRAINT_REQUIRED,
136                               mainTable.getName().statementName);
137         }
138
139         // existing rows, value checks
140
Constraint.checkReferencedRows(session, table, fkcol, exportindex);
141
142         // create
143
HsqlName iname = table.database.nameManager.newAutoName("IDX");
144         Index fkindex = createIndex(fkcol, iname, false, true, isforward);
145         HsqlName pkname = table.database.nameManager.newAutoName("REF",
146             name.name);
147
148         if (isSelf) {
149
150             // in case createIndex resulted in new Table object
151
mainTable = table;
152         }
153
154         Constraint c = new Constraint(pkname, name, mainTable, table, expcol,
155                                       fkcol, exportindex, fkindex,
156                                       deleteAction, updateAction);
157
158         table.addConstraint(c);
159         mainTable.addConstraint(new Constraint(pkname, c));
160         table.database.schemaManager.registerConstraintName(name.name,
161                 table.getName());
162     }
163
164     /**
165      * Because of the way indexes and column data are held in memory and
166      * on disk, it is necessary to recreate the table when an index is added
167      * to a non-empty table cached table.<p>
168      *
169      * With empty tables, Index objects are simply added<p>
170      *
171      * With MEOMRY and TEXT tables, a new index is built up and nodes for
172      * earch row are interlinked (fredt@users)
173      *
174      * @param col
175      * @param name
176      * @param unique
177      * @param constraint
178      * @param forward
179      * @return new index
180      * @throws HsqlException normally for lack of resources
181      */

182     Index createIndex(int[] col, HsqlName name, boolean unique,
183                       boolean constraint,
184                       boolean forward) throws HsqlException {
185
186         Index newindex;
187
188         if (table.isEmpty(session) || table.isIndexingMutable()) {
189             newindex = table.createIndex(session, col, name, unique,
190                                          constraint, forward);
191
192             table.database.schemaManager.clearTempTables(session, table);
193         } else {
194             Table tn = table.moveDefinition(null, null, -1, 0);
195
196             newindex = tn.createIndexStructure(col, name, unique, constraint,
197                                                forward);
198
199             tn.moveData(session, table, -1, 0);
200             tn.updateConstraintsTables(session, table, -1, 0);
201
202             int index = table.database.schemaManager.getTableIndex(table);
203
204             table.database.schemaManager.setTable(index, tn);
205
206             table = tn;
207         }
208
209         table.database.schemaManager.clearTempTables(session, table);
210         table.database.schemaManager.registerIndexName(
211             newindex.getName().name, table.getName());
212         table.database.schemaManager.recompileViews(table);
213
214         return newindex;
215     }
216
217     void addPrimaryKey(int[] cols, HsqlName name) throws HsqlException {
218
219         if (name == null) {
220             name = table.makeSysPKName();
221         }
222
223         table.database.schemaManager.checkConstraintExists(name.name,
224                 table.getSchemaName(), false);
225         addOrDropPrimaryKey(cols, false);
226
227         Constraint newconstraint = new Constraint(name, table,
228             table.getPrimaryIndex(), Constraint.PRIMARY_KEY);
229
230         table.addPKConstraint(newconstraint);
231         table.database.schemaManager.registerConstraintName(name.name,
232                 table.getName());
233     }
234
235     void addOrDropPrimaryKey(int[] cols,
236                              boolean identity) throws HsqlException {
237
238         if (cols == null) {
239             table.checkDropIndex(table.getIndexes()[0].getName().name, null,
240                                  true);
241         }
242
243         Table tn = table.moveDefinitionPK(cols, identity);
244
245         tn.moveData(session, table, -1, 0);
246         tn.updateConstraintsTables(session, table, -1, 0);
247
248         int index = table.database.schemaManager.getTableIndex(table);
249
250         table.database.schemaManager.setTable(index, tn);
251
252         table = tn;
253
254         table.database.schemaManager.recompileViews(table);
255     }
256
257     /**
258      * A unique constraint relies on a unique indexe on the table. It can
259      * cover a single column or multiple columns.
260      * <p>
261      * All unique constraint names are generated by Database.java as unique
262      * within the database. Duplicate constraints (more than one unique
263      * constriant on the same set of columns are still allowed but the
264      * names will be different. (fredt@users)
265      *
266      * @param col
267      * @param name
268      * @throws HsqlException
269      */

270     void createUniqueConstraint(int[] col,
271                                 HsqlName name) throws HsqlException {
272
273         table.database.schemaManager.checkConstraintExists(name.name,
274                 table.getSchemaName(), false);
275
276         Constraint[] constraints = table.getConstraints();
277
278         for (int i = 0, size = constraints.length; i < size; i++) {
279             Constraint c = constraints[i];
280
281             if (c.isEquivalent(col, Constraint.UNIQUE)
282                     || c.getName().name.equals(name.name)) {
283                 throw Trace.error(Trace.CONSTRAINT_ALREADY_EXISTS);
284             }
285         }
286
287         // create an autonamed index
288
HsqlName indexname = table.database.nameManager.newAutoName("IDX",
289             name.name);
290         Index index = createIndex(col, indexname, true, true, false);
291         Constraint newconstraint = new Constraint(name, table, index,
292             Constraint.UNIQUE);
293
294         table.addConstraint(newconstraint);
295         table.database.schemaManager.registerConstraintName(name.name,
296                 table.getName());
297     }
298
299     void createCheckConstraint(Constraint c,
300                                HsqlName name) throws HsqlException {
301
302         table.database.schemaManager.checkConstraintExists(name.name,
303                 table.getSchemaName(), false);
304
305         // check the existing rows
306
Expression e = c.core.check;
307
308         // this workaround is here to stop LIKE optimisation (for proper scripting)
309
e.setLikeOptimised();
310
311         Select s = Expression.getCheckSelect(session, table, e);
312         Result r = s.getResult(session, 1);
313
314         c.core.checkFilter = s.tFilter[0];
315         c.core.mainTable = table;
316
317         if (r.getSize() != 0) {
318             throw Trace.error(Trace.CHECK_CONSTRAINT_VIOLATION);
319         }
320
321         // getDDL() is here to ensure no subselects etc. are in condition
322
e.getDDL();
323
324         // removes reference to the Index object in filter
325
c.core.checkFilter.setAsCheckFilter();
326         table.addConstraint(c);
327         table.database.schemaManager.registerConstraintName(name.name,
328                 table.getName());
329     }
330
331     /**
332      * Because of the way indexes and column data are held in memory and
333      * on disk, it is necessary to recreate the table when an index is added
334      * to a non-empty table.<p>
335      * Originally, this method would break existing foreign keys as the
336      * table order in the DB was changed. The new table is now linked
337      * in place of the old table (fredt@users)
338      *
339      * @param indexname
340      * @throws HsqlException
341      */

342     void dropIndex(String JavaDoc indexname) throws HsqlException {
343
344         if (table.isIndexingMutable()) {
345             table.dropIndex(session, indexname);
346         } else {
347             int[] removeIndex = new int[]{ table.getIndexIndex(indexname) };
348             Table tn = table.moveDefinition(removeIndex, null, -1, 0);
349
350             tn.moveData(session, table, -1, 0);
351             tn.updateConstraintsTables(session, table, -1, 0);
352
353             int i = table.database.schemaManager.getTableIndex(table);
354
355             table.database.schemaManager.setTable(i, tn);
356
357             table = tn;
358         }
359
360         table.database.schemaManager.removeIndexName(indexname,
361                 table.getName());
362         table.database.schemaManager.recompileViews(table);
363     }
364
365     /**
366      *
367      * @param column
368      * @param colindex
369      * @throws HsqlException
370      */

371     void retypeColumn(Column column, int colindex) throws HsqlException {
372
373         if (table.isText() &&!table.isEmpty(session)) {
374             throw Trace.error(Trace.OPERATION_NOT_SUPPORTED);
375         }
376
377         table.database.schemaManager.checkColumnIsInView(table,
378                 table.getColumn(colindex).columnName.name);
379         table.checkColumnInCheckConstraint(
380             table.getColumn(colindex).columnName.name);
381
382         int[] dropIndexes = null;
383         Table tn = table.moveDefinition(dropIndexes, column, colindex, 0);
384
385         tn.moveData(session, table, colindex, 0);
386         tn.updateConstraintsTables(session, table, colindex, 0);
387
388         int i = table.database.schemaManager.getTableIndex(table);
389
390         table.database.schemaManager.setTable(i, tn);
391
392         table = tn;
393
394         table.database.schemaManager.recompileViews(table);
395     }
396
397     /**
398      *
399      * @param colIndex
400      * @throws HsqlException
401      */

402     void dropColumn(int colIndex) throws HsqlException {
403
404         HsqlName constNameRemove = null;
405
406         if (table.isText() &&!table.isEmpty(session)) {
407             throw Trace.error(Trace.OPERATION_NOT_SUPPORTED);
408         }
409
410         table.database.schemaManager.checkColumnIsInView(table,
411                 table.getColumn(colIndex).columnName.name);
412         table.checkColumnInCheckConstraint(
413             table.getColumn(colIndex).columnName.name);
414
415         Table tn = table;
416         int[] dropIndexes = null;
417         String JavaDoc colName = tn.getColumn(colIndex).columnName.name;
418
419         tn.checkColumnInFKConstraint(colIndex);
420
421         if (table.getPrimaryKey().length == 1
422                 && table.getPrimaryKey()[0] == colIndex) {
423             table.checkDropIndex(table.getIndex(0).getName().name, null,
424                                  true);
425
426             constNameRemove = table.constraintList[0].getName();
427             tn = table.moveDefinitionPK(null, false);
428         }
429
430         Constraint c = tn.getUniqueConstraintForColumns(new int[]{
431             colIndex });
432
433         if (c != null) {
434             Index idx = c.getMainIndex();
435
436             dropIndexes = new int[]{ tn.getIndexIndex(idx.getName().name) };
437             constNameRemove = c.getName();
438         }
439
440         tn = tn.moveDefinition(dropIndexes, null, colIndex, -1);
441
442         tn.moveData(session, table, colIndex, -1);
443         tn.updateConstraintsTables(session, table, colIndex, -1);
444
445         int i = table.database.schemaManager.getTableIndex(table);
446
447         table.database.schemaManager.setTable(i, tn);
448
449         table = tn;
450
451         table.database.schemaManager.recompileViews(table);
452
453         if (constNameRemove != null) {
454             table.removeConstraint(constNameRemove.name);
455             table.database.schemaManager.removeConstraintName(
456                 constNameRemove.name, table.getName());
457         }
458     }
459
460     /**
461      *
462      * @param column
463      * @param colIndex
464      * @throws HsqlException
465      */

466     void addColumn(Column column, int colIndex) throws HsqlException {
467
468         if (table.isText() &&!table.isEmpty(session)) {
469             throw Trace.error(Trace.OPERATION_NOT_SUPPORTED);
470         }
471
472         Table tn = table;
473
474         tn = tn.moveDefinition(null, column, colIndex, 1);
475
476         if (column.isPrimaryKey()) {
477             tn = tn.moveDefinitionPK(new int[]{ colIndex }, true);
478         }
479
480         tn.moveData(session, table, colIndex, 1);
481         tn.updateConstraintsTables(session, table, colIndex, 1);
482
483         int i = table.database.schemaManager.getTableIndex(table);
484
485         table.database.schemaManager.setTable(i, tn);
486
487         table = tn;
488
489         table.database.schemaManager.recompileViews(table);
490
491         if (column.isPrimaryKey()) {
492             HsqlName pkNameAdd = tn.makeSysPKName();
493             Constraint newconstraint = new Constraint(pkNameAdd, table,
494                 table.getPrimaryIndex(), Constraint.PRIMARY_KEY);
495
496             table.addConstraint(newconstraint);
497             table.database.schemaManager.registerConstraintName(
498                 pkNameAdd.name, table.getName());
499         }
500     }
501
502     /**
503      * Drop a named constraint
504      *
505      */

506     void dropConstraint(String JavaDoc name) throws HsqlException {
507
508         Constraint c = table.getConstraint(name);
509         int ctype;
510
511         if (c == null) {
512             throw Trace.error(Trace.CONSTRAINT_NOT_FOUND,
513                               Trace.TableWorks_dropConstraint, new Object JavaDoc[] {
514                 name, table.getName().name
515             });
516         }
517
518         ctype = c.getType();
519
520         if (ctype == Constraint.MAIN) {
521             throw Trace.error(Trace.DROP_SYSTEM_CONSTRAINT);
522         }
523
524         if (ctype == Constraint.PRIMARY_KEY) {
525             addOrDropPrimaryKey(null, false);
526             table.removeConstraint(name);
527         } else if (ctype == Constraint.FOREIGN_KEY) {
528             dropFKConstraint(c);
529         } else if (ctype == Constraint.UNIQUE) {
530             HashSet cset = new HashSet();
531
532             cset.add(c);
533
534             // throw if the index for unique constraint is shared
535
table.checkDropIndex(c.getMainIndex().getName().name, cset,
536                                  false);
537
538             // all is well if dropIndex throws for lack of resources
539
dropIndex(c.getMainIndex().getName().name);
540             table.removeConstraint(name);
541         } else if (ctype == Constraint.CHECK) {
542             table.removeConstraint(name);
543         }
544
545         table.database.schemaManager.removeConstraintName(name,
546                 table.getName());
547     }
548
549     void dropFKConstraint(Constraint c) throws HsqlException {
550
551         // drop the reference index, which is automatic and unused elsewhere
552
Index constIndex = c.getRefIndex();
553
554         // all is well if dropIndex throws for lack of resources
555
dropIndex(constIndex.getName().name);
556
557         Table mainTable = c.getMain();
558
559         // MAIN constraint was created after REF, so delete first
560
mainTable.removeConstraint(c.getPkName());
561         table.removeConstraint(c.getFkName());
562     }
563
564     void reTypeColumn(Column oldCol, Column newCol) throws HsqlException {
565
566         boolean notallowed = false;
567         int oldtype = oldCol.getType();
568         int newtype = newCol.getType();
569
570         switch (newtype) {
571
572             case Types.BINARY :
573             case Types.VARBINARY :
574             case Types.LONGVARBINARY :
575             case Types.OTHER :
576             case Types.JAVA_OBJECT :
577                 notallowed = !(newtype == oldtype || table.isEmpty(session));
578         }
579
580         switch (oldtype) {
581
582             case Types.BINARY :
583             case Types.VARBINARY :
584             case Types.LONGVARBINARY :
585             case Types.OTHER :
586             case Types.JAVA_OBJECT :
587                 notallowed = !(newtype == oldtype || table.isEmpty(session));
588                 break;
589
590             case Types.TINYINT :
591             case Types.SMALLINT :
592             case Types.INTEGER :
593             case Types.BIGINT :
594             case Types.REAL :
595             case Types.FLOAT :
596             case Types.DOUBLE :
597             case Types.NUMERIC :
598             case Types.DECIMAL :
599                 switch (newtype) {
600
601                     case Types.DATE :
602                     case Types.TIME :
603                     case Types.TIMESTAMP :
604                         notallowed = !table.isEmpty(session);
605                     default :
606                 }
607                 break;
608
609             case Types.DATE :
610             case Types.TIME :
611             case Types.TIMESTAMP :
612                 switch (newtype) {
613
614                     case Types.TINYINT :
615                     case Types.SMALLINT :
616                     case Types.INTEGER :
617                     case Types.BIGINT :
618                     case Types.REAL :
619                     case Types.FLOAT :
620                     case Types.DOUBLE :
621                     case Types.NUMERIC :
622                     case Types.DECIMAL :
623                         notallowed = !table.isEmpty(session);
624                     default :
625                 }
626                 break;
627         }
628
629         if (notallowed) {
630             throw Trace.error(Trace.INVALID_CONVERSION);
631         }
632
633         int colIndex = table.getColumnNr(oldCol.columnName.name);
634
635         if (table.getPrimaryKey().length > 1) {
636
637             // if there is a multi-column PK, do not change the PK attributes
638
if (newCol.isIdentity()) {
639                 throw Trace.error(Trace.SECOND_PRIMARY_KEY);
640             }
641
642             newCol.setPrimaryKey(oldCol.isPrimaryKey());
643
644             if (ArrayUtil.find(table.getPrimaryKey(), colIndex) != -1) {
645                 newCol.setNullable(false);
646             }
647         } else if (table.hasPrimaryKey()) {
648             if (oldCol.isPrimaryKey()) {
649                 newCol.setPrimaryKey(true);
650                 newCol.setNullable(false);
651             } else if (newCol.isPrimaryKey()) {
652                 throw Trace.error(Trace.SECOND_PRIMARY_KEY);
653             }
654         } else if (newCol.isPrimaryKey()) {
655             throw Trace.error(Trace.PRIMARY_KEY_NOT_ALLOWED);
656         }
657
658         // apply and return if only metadata change is required
659
if (newtype == oldtype && oldCol.isNullable() == newCol.isNullable()
660                 && oldCol.getScale() == newCol.getScale()
661                 && oldCol.isIdentity() == newCol.isIdentity()
662                 && oldCol.identityIncrement == newCol.identityIncrement
663                 && (oldCol.getSize() == newCol.getSize()
664                     || (oldCol.getSize() < newCol.getSize()
665                         && (oldtype == Types.VARCHAR
666                             || oldtype == Types.DECIMAL
667                             || oldtype == Types.NUMERIC)))) {
668
669             // size of some types may be increased with this command
670
// default expressions can change
671
oldCol.setType(newCol);
672             oldCol.setDefaultExpression(newCol.getDefaultExpression());
673             table.setColumnTypeVars(colIndex);
674             table.resetDefaultsFlag();
675
676             return;
677         }
678
679         table.database.schemaManager.checkColumnIsInView(table,
680                 table.getColumn(colIndex).columnName.name);
681         table.checkColumnInCheckConstraint(
682             table.getColumn(colIndex).columnName.name);
683         table.checkColumnInFKConstraint(colIndex);
684         checkConvertColDataType(oldCol, newCol);
685         retypeColumn(newCol, colIndex);
686     }
687
688     void checkConvertColDataType(Column oldCol,
689                                  Column newCol) throws HsqlException {
690
691         int colIndex = table.getColumnNr(oldCol.columnName.name);
692         RowIterator it = table.getPrimaryIndex().firstRow(session);
693
694         while (it.hasNext()) {
695             Row row = it.next();
696             Object JavaDoc o = row.getData()[colIndex];
697
698             Column.convertObject(session, o, newCol.getType(),
699                                  newCol.getSize(), newCol.getScale());
700         }
701     }
702
703     /**
704      * performs the work for changing the nullability of a column
705      */

706     void setColNullability(Column column,
707                            boolean nullable) throws HsqlException {
708
709         int colIndex = table.getColumnNr(column.columnName.name);
710
711         if (nullable) {
712             if (column.isPrimaryKey()) {
713                 throw Trace.error(Trace.TRY_TO_INSERT_NULL);
714             }
715
716             table.checkColumnInFKConstraint(colIndex, Constraint.SET_NULL);
717         } else {
718             RowIterator it = table.getPrimaryIndex().firstRow(session);
719
720             while (it.hasNext()) {
721                 Row row = it.next();
722                 Object JavaDoc o = row.getData()[colIndex];
723
724                 if (o == null) {
725                     throw Trace.error(Trace.TRY_TO_INSERT_NULL);
726                 }
727             }
728         }
729
730         column.setNullable(nullable);
731         table.setColumnTypeVars(colIndex);
732     }
733
734     /**
735      * performs the work for changing the default value of a column
736      */

737     void setColDefaultExpression(int colIndex,
738                                  Expression def) throws HsqlException {
739
740         if (def == null) {
741             table.checkColumnInFKConstraint(colIndex, Constraint.SET_DEFAULT);
742         }
743
744         table.setDefaultExpression(colIndex, def);
745     }
746 }
747
Popular Tags