org.glowroot.shaded.h2.constraint.ConstraintCheck Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.glowroot.shaded.h2.constraint;
import java.util.HashSet;
import java.util.Iterator;
import org.glowroot.shaded.h2.api.ErrorCode;
import org.glowroot.shaded.h2.engine.Session;
import org.glowroot.shaded.h2.expression.Expression;
import org.glowroot.shaded.h2.expression.ExpressionVisitor;
import org.glowroot.shaded.h2.index.Index;
import org.glowroot.shaded.h2.message.DbException;
import org.glowroot.shaded.h2.result.ResultInterface;
import org.glowroot.shaded.h2.result.Row;
import org.glowroot.shaded.h2.schema.Schema;
import org.glowroot.shaded.h2.table.Column;
import org.glowroot.shaded.h2.table.Table;
import org.glowroot.shaded.h2.table.TableFilter;
import org.glowroot.shaded.h2.util.New;
import org.glowroot.shaded.h2.util.StringUtils;
/**
* A check constraint.
*/
public class ConstraintCheck extends Constraint {
private TableFilter filter;
private Expression expr;
public ConstraintCheck(Schema schema, int id, String name, Table table) {
super(schema, id, name, table);
}
@Override
public String getConstraintType() {
return Constraint.CHECK;
}
public void setTableFilter(TableFilter filter) {
this.filter = filter;
}
public void setExpression(Expression expr) {
this.expr = expr;
}
@Override
public String getCreateSQLForCopy(Table forTable, String quotedName) {
StringBuilder buff = new StringBuilder("ALTER TABLE ");
buff.append(forTable.getSQL()).append(" ADD CONSTRAINT ");
if (forTable.isHidden()) {
buff.append("IF NOT EXISTS ");
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
}
buff.append(" CHECK").append(StringUtils.enclose(expr.getSQL()))
.append(" NOCHECK");
return buff.toString();
}
private String getShortDescription() {
return getName() + ": " + expr.getSQL();
}
@Override
public String getCreateSQLWithoutIndexes() {
return getCreateSQL();
}
@Override
public String getCreateSQL() {
return getCreateSQLForCopy(table, getSQL());
}
@Override
public void removeChildrenAndResources(Session session) {
table.removeConstraint(this);
database.removeMeta(session, getId());
filter = null;
expr = null;
table = null;
invalidate();
}
@Override
public void checkRow(Session session, Table t, Row oldRow, Row newRow) {
if (newRow == null) {
return;
}
filter.set(newRow);
Boolean b;
try {
b = expr.getValue(session).getBoolean();
} catch (DbException ex) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_INVALID, ex,
getShortDescription());
}
// Both TRUE and NULL are ok
if (Boolean.FALSE.equals(b)) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1,
getShortDescription());
}
}
@Override
public boolean usesIndex(Index index) {
return false;
}
@Override
public void setIndexOwner(Index index) {
DbException.throwInternalError();
}
@Override
public HashSet getReferencedColumns(Table table) {
HashSet columns = New.hashSet();
expr.isEverything(ExpressionVisitor.getColumnsVisitor(columns));
for (Iterator it = columns.iterator(); it.hasNext();) {
if (it.next().getTable() != table) {
it.remove();
}
}
return columns;
}
public Expression getExpression() {
return expr;
}
@Override
public boolean isBefore() {
return true;
}
@Override
public void checkExistingData(Session session) {
if (session.getDatabase().isStarting()) {
// don't check at startup
return;
}
String sql = "SELECT 1 FROM " + filter.getTable().getSQL() +
" WHERE NOT(" + expr.getSQL() + ")";
ResultInterface r = session.prepare(sql).query(1);
if (r.next()) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, getName());
}
}
@Override
public Index getUniqueIndex() {
return null;
}
@Override
public void rebuild() {
// nothing to do
}
@Override
public boolean isEverything(ExpressionVisitor visitor) {
return expr.isEverything(visitor);
}
}