org.hsqldb.ColumnSchema Maven / Gradle / Ivy
Show all versions of hsqldb Show documentation
/* Copyright (c) 2001-2024, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb;
import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.RangeGroup.RangeGroupSimple;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.Iterator;
import org.hsqldb.lib.OrderedHashSet;
import org.hsqldb.rights.Grantee;
import org.hsqldb.types.Type;
import org.hsqldb.types.Types;
/**
* Implementation of SQL table column metadata.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.7.3
* @since 1.9.0
*/
public class ColumnSchema extends ColumnBase implements SchemaObject {
public static final ColumnSchema[] emptyArray = new ColumnSchema[]{};
//
private HsqlName columnName;
private boolean isPrimaryKey;
private Expression defaultExpression;
private Expression generatingExpression;
private Expression updateExpression;
private NumberSequence sequence;
private OrderedHashSet references;
private OrderedHashSet generatedColumnReferences;
private Expression accessor;
private int systemPeriodType;
ColumnSchema(HsqlName name, Type type) {
this.columnName = name;
this.dataType = type;
}
/**
* Creates a column defined in DDL statement.
*/
public ColumnSchema(
HsqlName name,
Type type,
boolean isNullable,
boolean isPrimaryKey,
Expression defaultExpression) {
columnName = name;
nullability = isNullable
? SchemaObject.Nullability.NULLABLE
: SchemaObject.Nullability.NO_NULLS;
this.dataType = type;
this.isPrimaryKey = isPrimaryKey;
this.defaultExpression = defaultExpression;
setReferences();
}
public int getType() {
return columnName.type;
}
public HsqlName getName() {
return columnName;
}
public String getNameString() {
return columnName.name;
}
public String getTableNameString() {
return columnName.parent == null
? null
: columnName.parent.name;
}
public HsqlName getSchemaName() {
return columnName.schema;
}
public String getSchemaNameString() {
return columnName.schema == null
? null
: columnName.schema.name;
}
public HsqlName getCatalogName() {
return columnName.schema == null
? null
: columnName.schema.schema;
}
public String getCatalogNameString() {
return columnName.schema == null
? null
: columnName.schema.schema == null
? null
: columnName.schema.schema.name;
}
public Grantee getOwner() {
return columnName.schema == null
? null
: columnName.schema.owner;
}
public OrderedHashSet getReferences() {
return references;
}
public void compile(Session session, SchemaObject table) {
if (generatingExpression == null) {
return;
}
generatingExpression.resetColumnReferences();
generatingExpression.resolveCheckOrGenExpression(
session,
new RangeGroupSimple(((Table) table).getDefaultRanges(), false),
false);
if (!dataType.canBeAssignedFrom(generatingExpression.getDataType())) {
throw Error.error(ErrorCode.X_42561);
}
setReferences();
}
public String getSQL() {
StringBuilder sb = new StringBuilder();
switch (parameterMode) {
case SchemaObject.ParameterModes.PARAM_IN :
sb.append(Tokens.T_IN).append(' ');
break;
case SchemaObject.ParameterModes.PARAM_OUT :
sb.append(Tokens.T_OUT).append(' ');
break;
case SchemaObject.ParameterModes.PARAM_INOUT :
sb.append(Tokens.T_INOUT).append(' ');
break;
default :
}
if (columnName != null) {
sb.append(columnName.statementName).append(' ');
}
sb.append(dataType.getTypeDefinition());
return sb.toString();
}
public long getChangeTimestamp() {
return 0;
}
public void setType(Type type) {
this.dataType = type;
setReferences();
}
public void setName(HsqlName name) {
this.columnName = name;
}
void setIdentity(NumberSequence sequence) {
this.sequence = sequence;
isIdentity = sequence != null;
}
void setType(ColumnSchema other) {
nullability = other.nullability;
dataType = other.dataType;
}
public NumberSequence getIdentitySequence() {
return sequence;
}
/**
* Is column nullable.
*
* @return boolean
*/
public boolean isNullable() {
boolean isNullable = super.isNullable();
if (isNullable) {
if (dataType.isDomainType()) {
return dataType.userTypeModifier.isNullable();
}
}
return isNullable;
}
public byte getNullability() {
return isPrimaryKey
? SchemaObject.Nullability.NO_NULLS
: super.getNullability();
}
public boolean isGenerated() {
return generatingExpression != null;
}
public boolean isAutoUpdate() {
return updateExpression != null;
}
public boolean hasDefault() {
return getDefaultExpression() != null;
}
public void setUpdateExpression(Expression updateExpression) {
this.updateExpression = updateExpression;
}
public Expression getUpdateExpression() {
return updateExpression;
}
/**
* Is column writeable or always generated
*
* @return boolean
*/
public boolean isWriteable() {
return isWriteable;
}
public void setWriteable(boolean value) {
isWriteable = value;
}
public boolean isSearchable() {
return Types.isSearchable(dataType.typeCode);
}
/**
* Is this single column primary key of the table.
*
* @return boolean
*/
public boolean isPrimaryKey() {
return isPrimaryKey;
}
/**
* Set primary key.
*
*/
void setPrimaryKey(boolean value) {
isPrimaryKey = value;
}
/**
* Returns default value in the session context.
*/
public Object getDefaultValue(Session session) {
return defaultExpression == null
? null
: defaultExpression.getValue(session, dataType);
}
/**
* Returns generated value in the session context.
*/
public Object getGeneratedValue(Session session) {
return generatingExpression == null
? null
: generatingExpression.getValue(session, dataType);
}
/**
* Returns SQL for default value.
*/
public String getDefaultSQL() {
String ddl = defaultExpression == null
? null
: defaultExpression.getSQL();
return ddl;
}
/**
* Returns default expression for the column.
*/
Expression getDefaultExpression() {
if (defaultExpression == null) {
if (dataType.isDomainType()) {
return dataType.userTypeModifier.getDefaultClause();
}
return null;
} else {
return defaultExpression;
}
}
void setDefaultExpression(Expression expr) {
defaultExpression = expr;
}
/**
* Returns generated expression for the column.
*/
public Expression getGeneratingExpression() {
return generatingExpression;
}
void setGeneratingExpression(Expression expr) {
generatingExpression = expr;
setWriteable(generatingExpression == null);
}
public boolean isSystemPeriod() {
return systemPeriodType
!= SchemaObject.PeriodSystemColumnType.PERIOD_ROW_NONE;
}
/**
* Returns system period type of the column.
*/
public int getSystemPeriodType() {
return systemPeriodType;
}
void setSystemPeriodType(int type) {
systemPeriodType = type;
boolean writable =
type == SchemaObject.PeriodSystemColumnType.PERIOD_ROW_NONE;
setWriteable(writable);
}
public ColumnSchema duplicate() {
ColumnSchema copy = new ColumnSchema(
columnName,
dataType,
true,
isPrimaryKey,
defaultExpression);
copy.setNullability(this.nullability);
copy.setGeneratingExpression(generatingExpression);
copy.setIdentity(sequence);
copy.setUpdateExpression(updateExpression);
copy.setSystemPeriodType(systemPeriodType);
return copy;
}
public Expression getAccessor() {
if (accessor == null) {
accessor = new ExpressionColumnAccessor(this);
}
return accessor;
}
public OrderedHashSet getGeneratedColumnReferences() {
return generatedColumnReferences;
}
private void setReferences() {
if (references != null) {
references.clear();
}
if (generatedColumnReferences != null) {
generatedColumnReferences.clear();
}
if (dataType.isDomainType() || dataType.isDistinctType()) {
HsqlName name = dataType.getName();
if (references == null) {
references = new OrderedHashSet<>();
}
references.add(name);
}
if (generatingExpression != null) {
OrderedHashSet set = new OrderedHashSet<>();
generatingExpression.collectObjectNames(set);
Iterator it = set.iterator();
while (it.hasNext()) {
HsqlName name = it.next();
if (name.type == SchemaObject.COLUMN
|| name.type == SchemaObject.TABLE) {
if (name.type == SchemaObject.COLUMN) {
if (generatedColumnReferences == null) {
generatedColumnReferences = new OrderedHashSet<>();
}
generatedColumnReferences.add(name);
}
} else {
if (references == null) {
references = new OrderedHashSet<>();
}
references.add(name);
}
}
}
}
}