use of org.h2.engine.Database in project h2database by h2database.
the class AlterTableAlterColumn method update.
@Override
public int update() {
session.commit(true);
Database db = session.getDatabase();
Table table = getSchema().resolveTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter();
table.lock(session, true, true);
if (newColumn != null) {
checkDefaultReferencesTable(table, newColumn.getDefaultExpression());
checkClustering(newColumn);
}
if (columnsToAdd != null) {
for (Column column : columnsToAdd) {
checkDefaultReferencesTable(table, column.getDefaultExpression());
checkClustering(column);
}
}
switch(type) {
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NOT_NULL:
{
if (!oldColumn.isNullable()) {
// no change
break;
}
checkNoNullValues(table);
oldColumn.setNullable(false);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_NULL:
{
if (oldColumn.isNullable()) {
// no change
break;
}
checkNullable(table);
oldColumn.setNullable(true);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT:
{
Sequence sequence = oldColumn == null ? null : oldColumn.getSequence();
checkDefaultReferencesTable(table, defaultExpression);
oldColumn.setSequence(null);
oldColumn.setDefaultExpression(session, defaultExpression);
removeSequence(table, sequence);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE:
{
checkDefaultReferencesTable(table, defaultExpression);
oldColumn.setOnUpdateExpression(session, defaultExpression);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE:
{
// and does not affect the storage structure.
if (oldColumn.isWideningConversion(newColumn)) {
convertAutoIncrementColumn(table, newColumn);
oldColumn.copy(newColumn);
db.updateMeta(session, table);
} else {
oldColumn.setSequence(null);
oldColumn.setDefaultExpression(session, null);
oldColumn.setConvertNullToDefault(false);
if (oldColumn.isNullable() && !newColumn.isNullable()) {
checkNoNullValues(table);
} else if (!oldColumn.isNullable() && newColumn.isNullable()) {
checkNullable(table);
}
if (oldColumn.getVisible() ^ newColumn.getVisible()) {
oldColumn.setVisible(newColumn.getVisible());
}
convertAutoIncrementColumn(table, newColumn);
copyData(table);
}
table.setModified();
break;
}
case CommandInterface.ALTER_TABLE_ADD_COLUMN:
{
// ifNotExists only supported for single column add
if (ifNotExists && columnsToAdd != null && columnsToAdd.size() == 1 && table.doesColumnExist(columnsToAdd.get(0).getName())) {
break;
}
ArrayList<Sequence> sequences = generateSequences(columnsToAdd, false);
if (columnsToAdd != null) {
changePrimaryKeysToNotNull(columnsToAdd);
}
copyData(table, sequences, true);
break;
}
case CommandInterface.ALTER_TABLE_DROP_COLUMN:
{
if (table.getColumns().length - columnsToRemove.size() < 1) {
throw DbException.get(ErrorCode.CANNOT_DROP_LAST_COLUMN, columnsToRemove.get(0).getSQL());
}
table.dropMultipleColumnsConstraintsAndIndexes(session, columnsToRemove);
copyData(table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_SELECTIVITY:
{
int value = newSelectivity.optimize(session).getValue(session).getInt();
oldColumn.setSelectivity(value);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY:
{
oldColumn.setVisible(newVisibility);
table.setModified();
db.updateMeta(session, table);
break;
}
default:
DbException.throwInternalError("type=" + type);
}
return 0;
}
use of org.h2.engine.Database in project h2database by h2database.
the class AlterTableAddConstraint method tryUpdate.
/**
* Try to execute the statement.
*
* @return the update count
*/
private int tryUpdate() {
if (!transactional) {
session.commit(true);
}
Database db = session.getDatabase();
Table table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (ifTableExists) {
return 0;
}
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
if (getSchema().findConstraint(session, constraintName) != null) {
if (ifNotExists) {
return 0;
}
throw DbException.get(ErrorCode.CONSTRAINT_ALREADY_EXISTS_1, constraintName);
}
session.getUser().checkRight(table, Right.ALL);
db.lockMeta(session);
table.lock(session, true, true);
Constraint constraint;
switch(type) {
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY:
{
IndexColumn.mapColumns(indexColumns, table);
index = table.findPrimaryKey();
ArrayList<Constraint> constraints = table.getConstraints();
for (int i = 0; constraints != null && i < constraints.size(); i++) {
Constraint c = constraints.get(i);
if (Constraint.Type.PRIMARY_KEY == c.getConstraintType()) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
}
if (index != null) {
// if there is an index, it must match with the one declared
// we don't test ascending / descending
IndexColumn[] pkCols = index.getIndexColumns();
if (pkCols.length != indexColumns.length) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
for (int i = 0; i < pkCols.length; i++) {
if (pkCols[i].column != indexColumns[i].column) {
throw DbException.get(ErrorCode.SECOND_PRIMARY_KEY);
}
}
}
if (index == null) {
IndexType indexType = IndexType.createPrimaryKey(table.isPersistIndexes(), primaryKeyHash);
String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY);
int id = getObjectId();
try {
index = table.addIndex(session, indexName, id, indexColumns, indexType, true, null);
} finally {
getSchema().freeUniqueName(indexName);
}
}
index.getIndexType().setBelongsToConstraint(true);
int constraintId = getObjectId();
String name = generateConstraintName(table);
ConstraintUnique pk = new ConstraintUnique(getSchema(), constraintId, name, table, true);
pk.setColumns(indexColumns);
pk.setIndex(index, true);
constraint = pk;
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_UNIQUE:
{
IndexColumn.mapColumns(indexColumns, table);
boolean isOwner = false;
if (index != null && canUseUniqueIndex(index, table, indexColumns)) {
isOwner = true;
index.getIndexType().setBelongsToConstraint(true);
} else {
index = getUniqueIndex(table, indexColumns);
if (index == null) {
index = createIndex(table, indexColumns, true);
isOwner = true;
}
}
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintUnique unique = new ConstraintUnique(getSchema(), id, name, table, false);
unique.setColumns(indexColumns);
unique.setIndex(index, isOwner);
constraint = unique;
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_CHECK:
{
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintCheck check = new ConstraintCheck(getSchema(), id, name, table);
TableFilter filter = new TableFilter(session, table, null, false, null, 0, null);
checkExpression.mapColumns(filter, 0);
checkExpression = checkExpression.optimize(session);
check.setExpression(checkExpression);
check.setTableFilter(filter);
constraint = check;
if (checkExisting) {
check.checkExistingData(session);
}
break;
}
case CommandInterface.ALTER_TABLE_ADD_CONSTRAINT_REFERENTIAL:
{
Table refTable = refSchema.resolveTableOrView(session, refTableName);
if (refTable == null) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, refTableName);
}
session.getUser().checkRight(refTable, Right.ALL);
if (!refTable.canReference()) {
throw DbException.getUnsupportedException("Reference " + refTable.getSQL());
}
boolean isOwner = false;
IndexColumn.mapColumns(indexColumns, table);
if (index != null && canUseIndex(index, table, indexColumns, false)) {
isOwner = true;
index.getIndexType().setBelongsToConstraint(true);
} else {
index = getIndex(table, indexColumns, false);
if (index == null) {
index = createIndex(table, indexColumns, false);
isOwner = true;
}
}
if (refIndexColumns == null) {
Index refIdx = refTable.getPrimaryKey();
refIndexColumns = refIdx.getIndexColumns();
} else {
IndexColumn.mapColumns(refIndexColumns, refTable);
}
if (refIndexColumns.length != indexColumns.length) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
boolean isRefOwner = false;
if (refIndex != null && refIndex.getTable() == refTable && canUseIndex(refIndex, refTable, refIndexColumns, false)) {
isRefOwner = true;
refIndex.getIndexType().setBelongsToConstraint(true);
} else {
refIndex = null;
}
if (refIndex == null) {
refIndex = getIndex(refTable, refIndexColumns, false);
if (refIndex == null) {
refIndex = createIndex(refTable, refIndexColumns, true);
isRefOwner = true;
}
}
int id = getObjectId();
String name = generateConstraintName(table);
ConstraintReferential refConstraint = new ConstraintReferential(getSchema(), id, name, table);
refConstraint.setColumns(indexColumns);
refConstraint.setIndex(index, isOwner);
refConstraint.setRefTable(refTable);
refConstraint.setRefColumns(refIndexColumns);
refConstraint.setRefIndex(refIndex, isRefOwner);
if (checkExisting) {
refConstraint.checkExistingData(session);
}
refTable.addConstraint(refConstraint);
refConstraint.setDeleteAction(deleteAction);
refConstraint.setUpdateAction(updateAction);
constraint = refConstraint;
break;
}
default:
throw DbException.throwInternalError("type=" + type);
}
// parent relationship is already set with addConstraint
constraint.setComment(comment);
if (table.isTemporary() && !table.isGlobalTemporary()) {
session.addLocalTempTableConstraint(constraint);
} else {
db.addSchemaObject(session, constraint);
}
table.addConstraint(constraint);
return 0;
}
use of org.h2.engine.Database in project h2database by h2database.
the class Parser method readJoin.
private TableFilter readJoin(TableFilter top) {
TableFilter last = top;
while (true) {
TableFilter join;
if (readIf("RIGHT")) {
readIf("OUTER");
read("JOIN");
// the right hand side is the 'inner' table usually
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(join, top, true, on);
top = join;
} else if (readIf("LEFT")) {
readIf("OUTER");
read("JOIN");
join = readTableFilter();
join = readJoin(join);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, true, on);
} else if (readIf("FULL")) {
throw getSyntaxError();
} else if (readIf("INNER")) {
read("JOIN");
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("JOIN")) {
join = readTableFilter();
top = readJoin(top);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
}
addJoin(top, join, false, on);
} else if (readIf("CROSS")) {
read("JOIN");
join = readTableFilter();
addJoin(top, join, false, null);
} else if (readIf("NATURAL")) {
read("JOIN");
join = readTableFilter();
Column[] tableCols = last.getTable().getColumns();
Column[] joinCols = join.getTable().getColumns();
String tableSchema = last.getTable().getSchema().getName();
String joinSchema = join.getTable().getSchema().getName();
Expression on = null;
for (Column tc : tableCols) {
String tableColumnName = tc.getName();
for (Column c : joinCols) {
String joinColumnName = c.getName();
if (equalsToken(tableColumnName, joinColumnName)) {
join.addNaturalJoinColumn(c);
Expression tableExpr = new ExpressionColumn(database, tableSchema, last.getTableAlias(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, joinSchema, join.getTableAlias(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) {
on = equal;
} else {
on = new ConditionAndOr(ConditionAndOr.AND, on, equal);
}
}
}
}
addJoin(top, join, false, on);
} else {
break;
}
last = join;
}
return top;
}
use of org.h2.engine.Database in project h2database by h2database.
the class Parser method readCase.
private Expression readCase() {
if (readIf("END")) {
readIf("CASE");
return ValueExpression.getNull();
}
if (readIf("ELSE")) {
Expression elsePart = readExpression().optimize(session);
read("END");
readIf("CASE");
return elsePart;
}
int i;
Function function;
if (readIf("WHEN")) {
function = Function.getFunction(database, "CASE");
function.setParameter(0, null);
i = 1;
do {
function.setParameter(i++, readExpression());
read("THEN");
function.setParameter(i++, readExpression());
} while (readIf("WHEN"));
} else {
Expression expr = readExpression();
if (readIf("END")) {
readIf("CASE");
return ValueExpression.getNull();
}
if (readIf("ELSE")) {
Expression elsePart = readExpression().optimize(session);
read("END");
readIf("CASE");
return elsePart;
}
function = Function.getFunction(database, "CASE");
function.setParameter(0, expr);
i = 1;
read("WHEN");
do {
function.setParameter(i++, readExpression());
read("THEN");
function.setParameter(i++, readExpression());
} while (readIf("WHEN"));
}
if (readIf("ELSE")) {
function.setParameter(i, readExpression());
}
read("END");
readIf("CASE");
function.doneWithParameters();
return function;
}
use of org.h2.engine.Database in project h2database by h2database.
the class Command method stop.
@Override
public void stop() {
session.endStatement();
session.setCurrentCommand(null, false);
if (!isTransactional()) {
session.commit(true);
} else if (session.getAutoCommit()) {
session.commit(false);
} else if (session.getDatabase().isMultiThreaded()) {
Database db = session.getDatabase();
if (db != null) {
if (db.getLockMode() == Constants.LOCK_MODE_READ_COMMITTED) {
session.unlockReadLocks();
}
}
}
if (trace.isInfoEnabled() && startTimeNanos > 0) {
long timeMillis = (System.nanoTime() - startTimeNanos) / 1000 / 1000;
if (timeMillis > Constants.SLOW_QUERY_LIMIT_MS) {
trace.info("slow query: {0} ms", timeMillis);
}
}
}
Aggregations