EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.table]

COVERAGE SUMMARY FOR SOURCE FILE [Column.java]

nameclass, %method, %block, %line, %
Column.java100% (1/1)96%  (51/53)86%  (1076/1249)88%  (261.7/299)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Column100% (1/1)96%  (51/53)86%  (1076/1249)88%  (261.7/299)
setPrecision (long): void 0%   (0/1)0%   (0/4)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/3)0%   (0/1)
validateConvertUpdateSequence (Session, Value): Value 100% (1/1)53%  (121/228)64%  (28.3/44)
setSelectivity (int): void 100% (1/1)73%  (11/15)91%  (2.7/3)
isWideningConversion (Column): boolean 100% (1/1)84%  (72/86)70%  (16/23)
addCheckConstraint (Session, Expression): void 100% (1/1)85%  (73/86)92%  (18.5/20)
equals (Object): boolean 100% (1/1)85%  (34/40)70%  (7/10)
hashCode (): int 100% (1/1)88%  (14/16)67%  (2/3)
getCheckConstraint (Session, String): Expression 100% (1/1)88%  (36/41)98%  (10.8/11)
isEverything (ExpressionVisitor): boolean 100% (1/1)89%  (31/35)75%  (6/8)
updateSequenceIfRequired (Session, Value): void 100% (1/1)90%  (52/58)89%  (12.5/14)
convert (Value): Value 100% (1/1)96%  (50/52)99%  (6/6)
convertAutoIncrementToSequence (Session, Schema, int, boolean): void 100% (1/1)97%  (85/88)91%  (20/22)
Column (String, int): void 100% (1/1)100% (8/8)100% (2/2)
Column (String, int, long, int, int): void 100% (1/1)100% (43/43)100% (13/13)
computeValue (Session, Row): Value 100% (1/1)100% (13/13)100% (3/3)
copy (Column): void 100% (1/1)100% (65/65)100% (17/17)
getCheckConstraintSQL (Session, String): String 100% (1/1)100% (12/12)100% (2/2)
getClone (): Column 100% (1/1)100% (19/19)100% (3/3)
getColumnId (): int 100% (1/1)100% (3/3)100% (1/1)
getComment (): String 100% (1/1)100% (3/3)100% (1/1)
getComputed (): boolean 100% (1/1)100% (3/3)100% (1/1)
getCreateSQL (): String 100% (1/1)100% (151/151)100% (31/31)
getDataType (): DataType 100% (1/1)100% (4/4)100% (1/1)
getDefaultExpression (): Expression 100% (1/1)100% (3/3)100% (1/1)
getDefaultSQL (): String 100% (1/1)100% (9/9)100% (1/1)
getDisplaySize (): int 100% (1/1)100% (3/3)100% (1/1)
getName (): String 100% (1/1)100% (3/3)100% (1/1)
getOriginalSQL (): String 100% (1/1)100% (3/3)100% (1/1)
getPrecision (): long 100% (1/1)100% (3/3)100% (1/1)
getPrecisionAsInt (): int 100% (1/1)100% (4/4)100% (1/1)
getSQL (): String 100% (1/1)100% (4/4)100% (1/1)
getScale (): int 100% (1/1)100% (3/3)100% (1/1)
getSelectivity (): int 100% (1/1)100% (8/8)100% (1/1)
getSequence (): Sequence 100% (1/1)100% (3/3)100% (1/1)
getTable (): Table 100% (1/1)100% (3/3)100% (1/1)
getType (): int 100% (1/1)100% (3/3)100% (1/1)
isAutoIncrement (): boolean 100% (1/1)100% (3/3)100% (1/1)
isNullable (): boolean 100% (1/1)100% (3/3)100% (1/1)
isPrimaryKey (): boolean 100% (1/1)100% (3/3)100% (1/1)
prepareExpression (Session): void 100% (1/1)100% (27/27)100% (5/5)
removeCheckConstraint (): void 100% (1/1)100% (7/7)100% (3/3)
rename (String): void 100% (1/1)100% (4/4)100% (2/2)
setAutoIncrement (boolean, long, long): void 100% (1/1)100% (18/18)100% (7/7)
setComment (String): void 100% (1/1)100% (4/4)100% (2/2)
setComputedExpression (Expression): void 100% (1/1)100% (7/7)100% (3/3)
setConvertNullToDefault (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setDefaultExpression (Session, Expression): void 100% (1/1)100% (18/18)100% (6/6)
setNullable (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setOriginalSQL (String): void 100% (1/1)100% (4/4)100% (2/2)
setPrimaryKey (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setSequence (Sequence): void 100% (1/1)100% (4/4)100% (2/2)
setTable (Table, int): void 100% (1/1)100% (7/7)100% (3/3)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.table;
7 
8import java.sql.ResultSetMetaData;
9 
10import org.h2.api.ErrorCode;
11import org.h2.command.Parser;
12import org.h2.engine.Constants;
13import org.h2.engine.Mode;
14import org.h2.engine.Session;
15import org.h2.expression.ConditionAndOr;
16import org.h2.expression.Expression;
17import org.h2.expression.ExpressionVisitor;
18import org.h2.expression.SequenceValue;
19import org.h2.expression.ValueExpression;
20import org.h2.message.DbException;
21import org.h2.result.Row;
22import org.h2.schema.Schema;
23import org.h2.schema.Sequence;
24import org.h2.util.MathUtils;
25import org.h2.util.StringUtils;
26import org.h2.value.DataType;
27import org.h2.value.Value;
28import org.h2.value.ValueDate;
29import org.h2.value.ValueInt;
30import org.h2.value.ValueLong;
31import org.h2.value.ValueNull;
32import org.h2.value.ValueString;
33import org.h2.value.ValueTime;
34import org.h2.value.ValueTimestamp;
35import org.h2.value.ValueUuid;
36 
37/**
38 * This class represents a column in a table.
39 */
40public class Column {
41 
42    /**
43     * The name of the rowid pseudo column.
44     */
45    public static final String ROWID = "_ROWID_";
46 
47    /**
48     * This column is not nullable.
49     */
50    public static final int NOT_NULLABLE =
51            ResultSetMetaData.columnNoNulls;
52 
53    /**
54     * This column is nullable.
55     */
56    public static final int NULLABLE =
57            ResultSetMetaData.columnNullable;
58 
59    /**
60     * It is not know whether this column is nullable.
61     */
62    public static final int NULLABLE_UNKNOWN =
63            ResultSetMetaData.columnNullableUnknown;
64 
65    private final int type;
66    private long precision;
67    private int scale;
68    private int displaySize;
69    private Table table;
70    private String name;
71    private int columnId;
72    private boolean nullable = true;
73    private Expression defaultExpression;
74    private Expression checkConstraint;
75    private String checkConstraintSQL;
76    private String originalSQL;
77    private boolean autoIncrement;
78    private long start;
79    private long increment;
80    private boolean convertNullToDefault;
81    private Sequence sequence;
82    private boolean isComputed;
83    private TableFilter computeTableFilter;
84    private int selectivity;
85    private SingleColumnResolver resolver;
86    private String comment;
87    private boolean primaryKey;
88 
89    public Column(String name, int type) {
90        this(name, type, -1, -1, -1);
91    }
92 
93    public Column(String name, int type, long precision, int scale,
94            int displaySize) {
95        this.name = name;
96        this.type = type;
97        if (precision == -1 && scale == -1 && displaySize == -1) {
98            DataType dt = DataType.getDataType(type);
99            precision = dt.defaultPrecision;
100            scale = dt.defaultScale;
101            displaySize = dt.defaultDisplaySize;
102        }
103        this.precision = precision;
104        this.scale = scale;
105        this.displaySize = displaySize;
106    }
107 
108    @Override
109    public boolean equals(Object o) {
110        if (o == this) {
111            return true;
112        } else if (!(o instanceof Column)) {
113            return false;
114        }
115        Column other = (Column) o;
116        if (table == null || other.table == null ||
117                name == null || other.name == null) {
118            return false;
119        }
120        if (table != other.table) {
121            return false;
122        }
123        return name.equals(other.name);
124    }
125 
126    @Override
127    public int hashCode() {
128        if (table == null || name == null) {
129            return 0;
130        }
131        return table.getId() ^ name.hashCode();
132    }
133 
134    public Column getClone() {
135        Column newColumn = new Column(name, type, precision, scale, displaySize);
136        newColumn.copy(this);
137        return newColumn;
138    }
139 
140    /**
141     * Convert a value to this column's type.
142     *
143     * @param v the value
144     * @return the value
145     */
146    public Value convert(Value v) {
147        try {
148            return v.convertTo(type);
149        } catch (DbException e) {
150            if (e.getErrorCode() == ErrorCode.DATA_CONVERSION_ERROR_1) {
151                String target = (table == null ? "" : table.getName() + ": ") +
152                        getCreateSQL();
153                throw DbException.get(
154                        ErrorCode.DATA_CONVERSION_ERROR_1,
155                        v.getSQL() + " (" + target + ")");
156            }
157            throw e;
158        }
159    }
160 
161    boolean getComputed() {
162        return isComputed;
163    }
164 
165    /**
166     * Compute the value of this computed column.
167     *
168     * @param session the session
169     * @param row the row
170     * @return the value
171     */
172    synchronized Value computeValue(Session session, Row row) {
173        computeTableFilter.setSession(session);
174        computeTableFilter.set(row);
175        return defaultExpression.getValue(session);
176    }
177 
178    /**
179     * Set the default value in the form of a computed expression of other
180     * columns.
181     *
182     * @param expression the computed expression
183     */
184    public void setComputedExpression(Expression expression) {
185        this.isComputed = true;
186        this.defaultExpression = expression;
187    }
188 
189    /**
190     * Set the table and column id.
191     *
192     * @param table the table
193     * @param columnId the column index
194     */
195    public void setTable(Table table, int columnId) {
196        this.table = table;
197        this.columnId = columnId;
198    }
199 
200    public Table getTable() {
201        return table;
202    }
203 
204    /**
205     * Set the default expression.
206     *
207     * @param session the session
208     * @param defaultExpression the default expression
209     */
210    public void setDefaultExpression(Session session,
211            Expression defaultExpression) {
212        // also to test that no column names are used
213        if (defaultExpression != null) {
214            defaultExpression = defaultExpression.optimize(session);
215            if (defaultExpression.isConstant()) {
216                defaultExpression = ValueExpression.get(
217                        defaultExpression.getValue(session));
218            }
219        }
220        this.defaultExpression = defaultExpression;
221    }
222 
223    public int getColumnId() {
224        return columnId;
225    }
226 
227    public String getSQL() {
228        return Parser.quoteIdentifier(name);
229    }
230 
231    public String getName() {
232        return name;
233    }
234 
235    public int getType() {
236        return type;
237    }
238 
239    public long getPrecision() {
240        return precision;
241    }
242 
243    public void setPrecision(long p) {
244        precision = p;
245    }
246 
247    public int getDisplaySize() {
248        return displaySize;
249    }
250 
251    public int getScale() {
252        return scale;
253    }
254 
255    public void setNullable(boolean b) {
256        nullable = b;
257    }
258 
259    /**
260     * Validate the value, convert it if required, and update the sequence value
261     * if required. If the value is null, the default value (NULL if no default
262     * is set) is returned. Check constraints are validated as well.
263     *
264     * @param session the session
265     * @param value the value or null
266     * @return the new or converted value
267     */
268    public Value validateConvertUpdateSequence(Session session, Value value) {
269        if (value == null) {
270            if (defaultExpression == null) {
271                value = ValueNull.INSTANCE;
272            } else {
273                synchronized (this) {
274                    value = defaultExpression.getValue(session).convertTo(type);
275                }
276                if (primaryKey) {
277                    session.setLastIdentity(value);
278                }
279            }
280        }
281        Mode mode = session.getDatabase().getMode();
282        if (value == ValueNull.INSTANCE) {
283            if (convertNullToDefault) {
284                synchronized (this) {
285                    value = defaultExpression.getValue(session).convertTo(type);
286                }
287            }
288            if (value == ValueNull.INSTANCE && !nullable) {
289                if (mode.convertInsertNullToZero) {
290                    DataType dt = DataType.getDataType(type);
291                    if (dt.decimal) {
292                        value = ValueInt.get(0).convertTo(type);
293                    } else if (dt.type == Value.TIMESTAMP) {
294                        value = ValueTimestamp.fromMillis(session.getTransactionStart());
295                    } else if (dt.type == Value.TIME) {
296                        value = ValueTime.fromNanos(0);
297                    } else if (dt.type == Value.DATE) {
298                        value = ValueDate.fromMillis(session.getTransactionStart());
299                    } else {
300                        value = ValueString.get("").convertTo(type);
301                    }
302                } else {
303                    throw DbException.get(ErrorCode.NULL_NOT_ALLOWED, name);
304                }
305            }
306        }
307        if (checkConstraint != null) {
308            resolver.setValue(value);
309            Value v;
310            synchronized (this) {
311                v = checkConstraint.getValue(session);
312            }
313            // Both TRUE and NULL are ok
314            if (Boolean.FALSE.equals(v.getBoolean())) {
315                throw DbException.get(
316                        ErrorCode.CHECK_CONSTRAINT_VIOLATED_1,
317                        checkConstraint.getSQL());
318            }
319        }
320        value = value.convertScale(mode.convertOnlyToSmallerScale, scale);
321        if (precision > 0) {
322            if (!value.checkPrecision(precision)) {
323                String s = value.getTraceSQL();
324                if (s.length() > 127) {
325                    s = s.substring(0, 128) + "...";
326                }
327                throw DbException.get(ErrorCode.VALUE_TOO_LONG_2,
328                        getCreateSQL(), s + " (" + value.getPrecision() + ")");
329            }
330        }
331        updateSequenceIfRequired(session, value);
332        return value;
333    }
334 
335    private void updateSequenceIfRequired(Session session, Value value) {
336        if (sequence != null) {
337            long current = sequence.getCurrentValue();
338            long inc = sequence.getIncrement();
339            long now = value.getLong();
340            boolean update = false;
341            if (inc > 0 && now > current) {
342                update = true;
343            } else if (inc < 0 && now < current) {
344                update = true;
345            }
346            if (update) {
347                sequence.modify(now + inc, null, null, null);
348                session.setLastIdentity(ValueLong.get(now));
349                sequence.flush(session);
350            }
351        }
352    }
353 
354    /**
355     * Convert the auto-increment flag to a sequence that is linked with this
356     * table.
357     *
358     * @param session the session
359     * @param schema the schema where the sequence should be generated
360     * @param id the object id
361     * @param temporary true if the sequence is temporary and does not need to
362     *            be stored
363     */
364    public void convertAutoIncrementToSequence(Session session, Schema schema,
365            int id, boolean temporary) {
366        if (!autoIncrement) {
367            DbException.throwInternalError();
368        }
369        if ("IDENTITY".equals(originalSQL)) {
370            originalSQL = "BIGINT";
371        } else if ("SERIAL".equals(originalSQL)) {
372            originalSQL = "INT";
373        }
374        String sequenceName;
375        while (true) {
376            ValueUuid uuid = ValueUuid.getNewRandom();
377            String s = uuid.getString();
378            s = s.replace('-', '_').toUpperCase();
379            sequenceName = "SYSTEM_SEQUENCE_" + s;
380            if (schema.findSequence(sequenceName) == null) {
381                break;
382            }
383        }
384        Sequence seq = new Sequence(schema, id, sequenceName, start, increment);
385        if (temporary) {
386            seq.setTemporary(true);
387        } else {
388            session.getDatabase().addSchemaObject(session, seq);
389        }
390        setAutoIncrement(false, 0, 0);
391        SequenceValue seqValue = new SequenceValue(seq);
392        setDefaultExpression(session, seqValue);
393        setSequence(seq);
394    }
395 
396    /**
397     * Prepare all expressions of this column.
398     *
399     * @param session the session
400     */
401    public void prepareExpression(Session session) {
402        if (defaultExpression != null) {
403            computeTableFilter = new TableFilter(session, table, null, false, null);
404            defaultExpression.mapColumns(computeTableFilter, 0);
405            defaultExpression = defaultExpression.optimize(session);
406        }
407    }
408 
409    public String getCreateSQL() {
410        StringBuilder buff = new StringBuilder();
411        if (name != null) {
412            buff.append(Parser.quoteIdentifier(name)).append(' ');
413        }
414        if (originalSQL != null) {
415            buff.append(originalSQL);
416        } else {
417            buff.append(DataType.getDataType(type).name);
418            switch (type) {
419            case Value.DECIMAL:
420                buff.append('(').append(precision).append(", ").append(scale).append(')');
421                break;
422            case Value.BYTES:
423            case Value.STRING:
424            case Value.STRING_IGNORECASE:
425            case Value.STRING_FIXED:
426                if (precision < Integer.MAX_VALUE) {
427                    buff.append('(').append(precision).append(')');
428                }
429                break;
430            default:
431            }
432        }
433        if (defaultExpression != null) {
434            String sql = defaultExpression.getSQL();
435            if (sql != null) {
436                if (isComputed) {
437                    buff.append(" AS ").append(sql);
438                } else if (defaultExpression != null) {
439                    buff.append(" DEFAULT ").append(sql);
440                }
441            }
442        }
443        if (!nullable) {
444            buff.append(" NOT NULL");
445        }
446        if (convertNullToDefault) {
447            buff.append(" NULL_TO_DEFAULT");
448        }
449        if (sequence != null) {
450            buff.append(" SEQUENCE ").append(sequence.getSQL());
451        }
452        if (selectivity != 0) {
453            buff.append(" SELECTIVITY ").append(selectivity);
454        }
455        if (comment != null) {
456            buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
457        }
458        if (checkConstraint != null) {
459            buff.append(" CHECK ").append(checkConstraintSQL);
460        }
461        return buff.toString();
462    }
463 
464    public boolean isNullable() {
465        return nullable;
466    }
467 
468    public void setOriginalSQL(String original) {
469        originalSQL = original;
470    }
471 
472    public String getOriginalSQL() {
473        return originalSQL;
474    }
475 
476    public Expression getDefaultExpression() {
477        return defaultExpression;
478    }
479 
480    public boolean isAutoIncrement() {
481        return autoIncrement;
482    }
483 
484    /**
485     * Set the autoincrement flag and related properties of this column.
486     *
487     * @param autoInc the new autoincrement flag
488     * @param start the sequence start value
489     * @param increment the sequence increment
490     */
491    public void setAutoIncrement(boolean autoInc, long start, long increment) {
492        this.autoIncrement = autoInc;
493        this.start = start;
494        this.increment = increment;
495        this.nullable = false;
496        if (autoInc) {
497            convertNullToDefault = true;
498        }
499    }
500 
501    public void setConvertNullToDefault(boolean convert) {
502        this.convertNullToDefault = convert;
503    }
504 
505    /**
506     * Rename the column. This method will only set the column name to the new
507     * value.
508     *
509     * @param newName the new column name
510     */
511    public void rename(String newName) {
512        this.name = newName;
513    }
514 
515    public void setSequence(Sequence sequence) {
516        this.sequence = sequence;
517    }
518 
519    public Sequence getSequence() {
520        return sequence;
521    }
522 
523    /**
524     * Get the selectivity of the column. Selectivity 100 means values are
525     * unique, 10 means every distinct value appears 10 times on average.
526     *
527     * @return the selectivity
528     */
529    public int getSelectivity() {
530        return selectivity == 0 ? Constants.SELECTIVITY_DEFAULT : selectivity;
531    }
532 
533    /**
534     * Set the new selectivity of a column.
535     *
536     * @param selectivity the new value
537     */
538    public void setSelectivity(int selectivity) {
539        selectivity = selectivity < 0 ? 0 : (selectivity > 100 ? 100 : selectivity);
540        this.selectivity = selectivity;
541    }
542 
543    /**
544     * Add a check constraint expression to this column. An existing check
545     * constraint constraint is added using AND.
546     *
547     * @param session the session
548     * @param expr the (additional) constraint
549     */
550    public void addCheckConstraint(Session session, Expression expr) {
551        if (expr == null) {
552            return;
553        }
554        resolver = new SingleColumnResolver(this);
555        synchronized (this) {
556            String oldName = name;
557            if (name == null) {
558                name = "VALUE";
559            }
560            expr.mapColumns(resolver, 0);
561            name = oldName;
562        }
563        expr = expr.optimize(session);
564        resolver.setValue(ValueNull.INSTANCE);
565        // check if the column is mapped
566        synchronized (this) {
567            expr.getValue(session);
568        }
569        if (checkConstraint == null) {
570            checkConstraint = expr;
571        } else {
572            checkConstraint = new ConditionAndOr(ConditionAndOr.AND, checkConstraint, expr);
573        }
574        checkConstraintSQL = getCheckConstraintSQL(session, name);
575    }
576 
577    /**
578     * Remove the check constraint if there is one.
579     */
580    public void removeCheckConstraint() {
581        checkConstraint = null;
582        checkConstraintSQL = null;
583    }
584 
585    /**
586     * Get the check constraint expression for this column if set.
587     *
588     * @param session the session
589     * @param asColumnName the column name to use
590     * @return the constraint expression
591     */
592    public Expression getCheckConstraint(Session session, String asColumnName) {
593        if (checkConstraint == null) {
594            return null;
595        }
596        Parser parser = new Parser(session);
597        String sql;
598        synchronized (this) {
599            String oldName = name;
600            name = asColumnName;
601            sql = checkConstraint.getSQL();
602            name = oldName;
603        }
604        Expression expr = parser.parseExpression(sql);
605        return expr;
606    }
607 
608    String getDefaultSQL() {
609        return defaultExpression == null ? null : defaultExpression.getSQL();
610    }
611 
612    int getPrecisionAsInt() {
613        return MathUtils.convertLongToInt(precision);
614    }
615 
616    DataType getDataType() {
617        return DataType.getDataType(type);
618    }
619 
620    /**
621     * Get the check constraint SQL snippet.
622     *
623     * @param session the session
624     * @param asColumnName the column name to use
625     * @return the SQL snippet
626     */
627    String getCheckConstraintSQL(Session session, String asColumnName) {
628        Expression constraint = getCheckConstraint(session, asColumnName);
629        return constraint == null ? "" : constraint.getSQL();
630    }
631 
632    public void setComment(String comment) {
633        this.comment = comment;
634    }
635 
636    public String getComment() {
637        return comment;
638    }
639 
640    public void setPrimaryKey(boolean primaryKey) {
641        this.primaryKey = primaryKey;
642    }
643 
644    /**
645     * Visit the default expression, the check constraint, and the sequence (if
646     * any).
647     *
648     * @param visitor the visitor
649     * @return true if every visited expression returned true, or if there are
650     *         no expressions
651     */
652    boolean isEverything(ExpressionVisitor visitor) {
653        if (visitor.getType() == ExpressionVisitor.GET_DEPENDENCIES) {
654            if (sequence != null) {
655                visitor.getDependencies().add(sequence);
656            }
657        }
658        if (defaultExpression != null && !defaultExpression.isEverything(visitor)) {
659            return false;
660        }
661        if (checkConstraint != null && !checkConstraint.isEverything(visitor)) {
662            return false;
663        }
664        return true;
665    }
666 
667    public boolean isPrimaryKey() {
668        return primaryKey;
669    }
670 
671    @Override
672    public String toString() {
673        return name;
674    }
675 
676    /**
677     * Check whether the new column is of the same type and not more restricted
678     * than this column.
679     *
680     * @param newColumn the new (target) column
681     * @return true if the new column is compatible
682     */
683    public boolean isWideningConversion(Column newColumn) {
684        if (type != newColumn.type) {
685            return false;
686        }
687        if (precision > newColumn.precision) {
688            return false;
689        }
690        if (scale != newColumn.scale) {
691            return false;
692        }
693        if (nullable && !newColumn.nullable) {
694            return false;
695        }
696        if (convertNullToDefault != newColumn.convertNullToDefault) {
697            return false;
698        }
699        if (primaryKey != newColumn.primaryKey) {
700            return false;
701        }
702        if (autoIncrement || newColumn.autoIncrement) {
703            return false;
704        }
705        if (checkConstraint != null || newColumn.checkConstraint != null) {
706            return false;
707        }
708        if (convertNullToDefault || newColumn.convertNullToDefault) {
709            return false;
710        }
711        if (defaultExpression != null || newColumn.defaultExpression != null) {
712            return false;
713        }
714        if (isComputed || newColumn.isComputed) {
715            return false;
716        }
717        return true;
718    }
719 
720    /**
721     * Copy the data of the source column into the current column.
722     *
723     * @param source the source column
724     */
725    public void copy(Column source) {
726        checkConstraint = source.checkConstraint;
727        checkConstraintSQL = source.checkConstraintSQL;
728        displaySize = source.displaySize;
729        name = source.name;
730        precision = source.precision;
731        scale = source.scale;
732        // table is not set
733        // columnId is not set
734        nullable = source.nullable;
735        defaultExpression = source.defaultExpression;
736        originalSQL = source.originalSQL;
737        // autoIncrement, start, increment is not set
738        convertNullToDefault = source.convertNullToDefault;
739        sequence = source.sequence;
740        comment = source.comment;
741        computeTableFilter = source.computeTableFilter;
742        isComputed = source.isComputed;
743        selectivity = source.selectivity;
744        primaryKey = source.primaryKey;
745    }
746 
747}

[all classes][org.h2.table]
EMMA 2.0.5312 (C) Vladimir Roubtsov