use of org.apache.derby.catalog.UUID in project derby by apache.
the class ConstraintConstantAction method validateConstraint.
/**
* Evaluate a check constraint or not null column constraint.
* Generate a query of the
* form SELECT COUNT(*) FROM t where NOT(<check constraint>)
* and run it by compiling and executing it. Will
* work ok if the table is empty and query returns null.
*
* @param constraintName constraint name
* @param constraintText constraint text
* @param constraintId constraint id
* @param td referenced table
* @param lcc the language connection context
* @param isCheckConstraint the constraint is a check constraint
* @param isInitiallyDeferred {@code true} if the constraint is
* initially deferred
*
* @return true if null constraint passes, false otherwise
*
* @exception StandardException if check constraint fails
*/
static boolean validateConstraint(String constraintName, String constraintText, UUID constraintId, TableDescriptor td, LanguageConnectionContext lcc, boolean isCheckConstraint, boolean isInitiallyDeferred) throws StandardException {
StringBuilder checkStmt = new StringBuilder();
/* should not use select sum(not(<check-predicate>) ? 1: 0) because
* that would generate much more complicated code and may exceed Java
* limits if we have a large number of check constraints, beetle 4347
*/
checkStmt.append("SELECT COUNT(*) FROM ");
checkStmt.append(td.getQualifiedName());
checkStmt.append(" WHERE NOT(");
checkStmt.append(constraintText);
checkStmt.append(")");
ResultSet rs = null;
try {
PreparedStatement ps = lcc.prepareInternalStatement(checkStmt.toString());
// This is a substatement; for now, we do not set any timeout
// for it. We might change this behaviour later, by linking
// timeout to its parent statement's timeout settings.
rs = ps.executeSubStatement(lcc, false, 0L);
ExecRow row = rs.getNextRow();
if (SanityManager.DEBUG) {
if (row == null) {
SanityManager.THROWASSERT("did not get any rows back from query: " + checkStmt.toString());
}
}
Number value = ((Number) ((NumberDataValue) row.getRowArray()[0]).getObject());
/*
** Value may be null if there are no rows in the
** table.
*/
if ((value != null) && (value.longValue() != 0)) {
// check constraint is violated.
if (isCheckConstraint) {
if (isInitiallyDeferred) {
// Remember the violation
List<UUID> violatingConstraints = new ArrayList<UUID>();
violatingConstraints.add(constraintId);
// FIXME: We don't know the row locations of the
// violating rows, so for now, just pretend we know one,
// then invalidate the row location information forcing
// full table check at validation time
CheckInfo[] newCi = new CheckInfo[1];
DeferredConstraintsMemory.rememberCheckViolations(lcc, td.getObjectID(), td.getSchemaName(), td.getName(), null, violatingConstraints, new HeapRowLocation(), /* dummy */
newCi);
newCi[0].setInvalidatedRowLocations();
} else {
throw StandardException.newException(SQLState.LANG_ADD_CHECK_CONSTRAINT_FAILED, constraintName, td.getQualifiedName(), value.toString());
}
}
/*
* for not null constraint violations exception will be thrown in caller
* check constraint will not get here since exception is thrown
* above
*/
return false;
}
} finally {
if (rs != null) {
rs.close();
}
}
return true;
}
use of org.apache.derby.catalog.UUID in project derby by apache.
the class IndexChanger method insertAndCheckDups.
/**
* Insert the given row into the given conglomerate and check for duplicate
* key error.
*
* @param row The row to insert
*
* @exception StandardException Thrown on duplicate key error unless
* we have a deferred constraint. In that
* index rows are saved for checking
* on commit.
*/
private void insertAndCheckDups(ExecIndexRow row) throws StandardException {
openIndexCC();
int insertStatus;
final DataValueDescriptor[] rowArray = row.getRowArray();
if (deferrable) {
insertStatus = indexCC.insert(row.getRowArray());
if (SanityManager.DEBUG) {
// deferrable: we use a non-unique index
SanityManager.ASSERT(insertStatus != ConglomerateController.ROWISDUPLICATE);
}
final DataValueDescriptor[] key = new DataValueDescriptor[rowArray.length - 1];
System.arraycopy(rowArray, 0, key, 0, key.length);
// If the constraint mode is deferred, perform the check without
// waiting for any locks; we will just presume any lock conflicts
// constitute duplicates (not always the case), and check those keys
// again at commit time.
final boolean deferred = lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(activation), getUniqueConstraintId());
// TODO add assert getUniqueConstraintId() != null
ScanController idxScan = tc.openScan(indexCID, false, (deferred ? TransactionController.OPENMODE_LOCK_ROW_NOWAIT : 0), TransactionController.MODE_RECORD, TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK, // retrieve all fields
(FormatableBitSet) null, key, // startSearchOp
ScanController.GE, null, key, ScanController.GT);
boolean duplicate = false;
try {
final boolean foundOne = idxScan.next();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(foundOne, "IndexChanger: inserted row gone?");
}
duplicate = foundOne && idxScan.next();
} catch (StandardException e) {
if ((e.getSQLState().equals(SQLState.LOCK_TIMEOUT) || e.getSQLState().equals(SQLState.DEADLOCK)) && deferred) {
// Assume there is a duplicate, so we'll check again at
// commit time.
duplicate = true;
} else {
throw e;
}
}
if (duplicate && irg.isUniqueWithDuplicateNulls()) {
int keyParts = rowArray.length - 1;
for (int i = 0; i < keyParts; i++) {
// Keys with null in it are always unique
if (rowArray[i].isNull()) {
duplicate = false;
break;
}
}
}
if (duplicate) {
if (deferred) {
// Save duplicate row so we can check at commit time there is
// no longer any duplicate.
deferredDuplicates = DeferredConstraintsMemory.rememberDuplicate(lcc, deferredDuplicates, getUniqueConstraintId(), row.getRowArray());
} else {
// the constraint is not deferred, so throw
insertStatus = ConglomerateController.ROWISDUPLICATE;
}
}
} else {
// not a deferred constraint
insertStatus = indexCC.insert(row.getRowArray());
}
if (insertStatus == ConglomerateController.ROWISDUPLICATE) {
/*
** We have a duplicate key error.
*/
String indexOrConstraintName = indexName;
// now get table name, and constraint name if needed
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
// get the descriptors
ConglomerateDescriptor cd = dd.getConglomerateDescriptor(indexCID);
UUID tableID = cd.getTableID();
TableDescriptor td = dd.getTableDescriptor(tableID);
String tableName = td.getName();
if (// no index name passed in
indexOrConstraintName == null) {
ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td, cd.getUUID());
indexOrConstraintName = conDesc.getConstraintName();
}
StandardException se = StandardException.newException(SQLState.LANG_DUPLICATE_KEY_CONSTRAINT, indexOrConstraintName, tableName);
throw se;
} else {
if (SanityManager.DEBUG) {
if (insertStatus != 0) {
SanityManager.THROWASSERT("Unknown insert status " + insertStatus);
}
}
}
}
use of org.apache.derby.catalog.UUID in project derby by apache.
the class DropConstraintConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for DROP CONSTRAINT.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
ConstraintDescriptor conDesc = null;
TableDescriptor td;
UUID indexId = null;
String indexUUIDString;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
/*
** Inform the data dictionary that we are about to write to it.
** There are several calls to data dictionary "get" methods here
** that might be done in "read" mode in the data dictionary, but
** it seemed safer to do this whole operation in "write" mode.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
td = dd.getTableDescriptor(tableId);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
}
/* Table gets locked in AlterTableConstantAction */
/*
** If the schema descriptor is null, then
** we must have just read ourselves in.
** So we will get the corresponding schema
** descriptor from the data dictionary.
*/
SchemaDescriptor tdSd = td.getSchemaDescriptor();
SchemaDescriptor constraintSd = constraintSchemaName == null ? tdSd : dd.getSchemaDescriptor(constraintSchemaName, tc, true);
/* Get the constraint descriptor for the index, along
* with an exclusive row lock on the row in sys.sysconstraints
* in order to ensure that no one else compiles against the
* index.
*/
if (// this means "alter table drop primary key"
constraintName == null)
conDesc = dd.getConstraintDescriptors(td).getPrimaryKey();
else
conDesc = dd.getConstraintDescriptorByName(td, constraintSd, constraintName, true);
// Error if constraint doesn't exist
if (conDesc == null) {
String errorName = constraintName == null ? "PRIMARY KEY" : (constraintSd.getSchemaName() + "." + constraintName);
throw StandardException.newException(SQLState.LANG_DROP_OR_ALTER_NON_EXISTING_CONSTRAINT, errorName, td.getQualifiedName());
}
switch(verifyType) {
case DataDictionary.UNIQUE_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "UNIQUE");
break;
case DataDictionary.CHECK_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "CHECK");
break;
case DataDictionary.FOREIGNKEY_CONSTRAINT:
if (conDesc.getConstraintType() != verifyType)
throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE, constraintName, "FOREIGN KEY");
break;
}
boolean cascadeOnRefKey = (cascade && conDesc instanceof ReferencedKeyConstraintDescriptor);
if (!cascadeOnRefKey) {
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
}
/*
** If we had a primary/unique key and it is drop cascade,
** drop all the referencing keys now. We MUST do this AFTER
** dropping the referenced key because otherwise we would
** be repeatedly changing the reference count of the referenced
** key and generating unnecessary I/O.
*/
dropConstraint(conDesc, activation, lcc, !cascadeOnRefKey);
if (cascadeOnRefKey) {
ForeignKeyConstraintDescriptor fkcd;
ReferencedKeyConstraintDescriptor cd;
ConstraintDescriptorList cdl;
cd = (ReferencedKeyConstraintDescriptor) conDesc;
cdl = cd.getForeignKeyConstraints(ReferencedKeyConstraintDescriptor.ALL);
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
fkcd = (ForeignKeyConstraintDescriptor) cdl.elementAt(index);
dm.invalidateFor(fkcd, DependencyManager.DROP_CONSTRAINT, lcc);
dropConstraint(fkcd, activation, lcc, true);
}
/*
** We told dropConstraintAndIndex not to
** remove our dependencies, so send an invalidate,
** and drop the dependencies.
*/
dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
dm.clearDependencies(lcc, conDesc);
}
}
use of org.apache.derby.catalog.UUID in project derby by apache.
the class T_UUIDFactory method testUUIDConversions.
private void testUUIDConversions(HeaderPrintWriter out, String uuidstring) {
UUID uuid = factory.recreateUUID(uuidstring);
if (!uuidstring.equalsIgnoreCase(uuid.toString())) {
// Resolve: format this with a message factory
String message = "Couldn't recreate UUID String: " + uuidstring + " != " + uuid.toString();
out.printlnWithHeader(message);
resultSoFar = false;
}
}
use of org.apache.derby.catalog.UUID in project derby by apache.
the class T_UUIDFactory method testUUID.
/*
** Tests
*/
protected boolean testUUID() {
resultSoFar = true;
UUID uuid1 = factory.createUUID();
UUID uuid2 = factory.createUUID();
if (uuid1.equals(uuid2)) {
// Resolve: format this with a message factory
String message = "UUID factory created matching UUIDS '%0' and '%1'";
out.printlnWithHeader(message);
resultSoFar = false;
}
if (!uuid1.equals(uuid1)) {
// Resolve: format this with a message factory
String message = "UUID '%0' does not equal itself";
resultSoFar = false;
}
if (uuid1.hashCode() != uuid1.hashCode()) {
// Resolve: format this with a message factory
String message = "UUID '%0' does not hash to the same thing twice.";
out.printlnWithHeader(message);
resultSoFar = false;
}
// Check that we can go from UUID to string and back.
String suuid1 = uuid1.toString();
UUID uuid3 = factory.recreateUUID(suuid1);
if (!uuid3.equals(uuid1)) {
// Resolve: format this with a message factory
String message = "Couldn't recreate UUID: " + uuid3.toString() + " != " + uuid1.toString();
out.printlnWithHeader(message);
resultSoFar = false;
}
// Check that we can transform from string to UUID and back
// for a few "interesting" UUIDs.
// This one came from GUIDGEN.EXE.
testUUIDConversions(out, "7878FCD0-DA09-11d0-BAFE-0060973F0942");
// Interesting bit patterns.
testUUIDConversions(out, "80706050-4030-2010-8070-605040302010");
testUUIDConversions(out, "f0e0d0c0-b0a0-9080-7060-504030201000");
testUUIDConversions(out, "00000000-0000-0000-0000-000000000000");
testUUIDConversions(out, "ffffffff-ffff-ffff-ffff-ffffffffffff");
// A couple self-generated ones for good measure.
testUUIDConversions(out, factory.createUUID().toString());
testUUIDConversions(out, factory.createUUID().toString());
return resultSoFar;
}
Aggregations