You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2014/03/11 15:46:17 UTC
svn commit: r1576367 [3/4] - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/error/ engine/org/apache/derby/iapi/sql/compile/
engine/org/apache/derby/iapi/sql/conn/
engine/org/apache/derby/iapi/sql/dictionary/
engine/org/apache/derby/iapi/sq...
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java Tue Mar 11 14:46:15 2014
@@ -82,7 +82,7 @@ class IndexChanger
private final boolean deferrable; // supports a deferrable constraint
private final LanguageConnectionContext lcc;
- private BackingStoreHashtable deferredRowsHashTable; // cached for speed
+ private BackingStoreHashtable deferredDuplicates; // cached for speed
/**
Create an IndexChanger
@@ -528,11 +528,11 @@ class IndexChanger
// Save duplicate row so we can check at commit time there is
// no longer any duplicate.
- deferredRowsHashTable = DeferredDuplicates.rememberDuplicate(
- tc,
- indexCID,
- deferredRowsHashTable,
+ deferredDuplicates =
+ DeferredConstraintsMemory.rememberDuplicate(
lcc,
+ deferredDuplicates,
+ indexCID,
row.getRowArray());
} else { // the constraint is not deferred, so throw
insertStatus = ConglomerateController.ROWISDUPLICATE;
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertConstantAction.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertConstantAction.java Tue Mar 11 14:46:15 2014
@@ -91,18 +91,23 @@ public class InsertConstantAction extend
/** Position of autogenerated column */
private transient int firstAutoGenColumn = -1;
-
+ final public boolean hasDeferrableChecks;
+
// CONSTRUCTORS
/**
* Public niladic constructor. Needed for Formatable interface to work.
*
*/
- public InsertConstantAction() { super(); }
+ public InsertConstantAction() {
+ super();
+ hasDeferrableChecks = false;
+ }
/**
* Make the ConstantAction for an INSERT statement.
*
+ * @param tableDescriptor
* @param conglomId Conglomerate ID.
* @param heapSCOCI StaticCompiledOpenConglomInfo for heap.
* @param irgs Index descriptors
@@ -110,6 +115,8 @@ public class InsertConstantAction extend
* @param indexSCOCIs StaticCompiledOpenConglomInfos for indexes.
* @param indexNames Names of indices on this table for error reporting.
* @param deferred True means process as a deferred insert.
+ * @param hasDeferrableChecks
+ * The target table has deferrable CHECK constraints
* @param targetProperties Properties on the target table.
* @param targetUUID UUID of target table
* @param lockMode The lockMode to use on the target table
@@ -132,6 +139,7 @@ public class InsertConstantAction extend
StaticCompiledOpenConglomInfo[] indexSCOCIs,
String[] indexNames,
boolean deferred,
+ boolean hasDeferrableChecks,
Properties targetProperties,
UUID targetUUID,
int lockMode,
@@ -168,6 +176,7 @@ public class InsertConstantAction extend
this.columnNames = tableDescriptor.getColumnNamesArray();
this.autoincIncrement = tableDescriptor.getAutoincIncrementArray();
this.indexNames = indexNames;
+ this.hasDeferrableChecks = hasDeferrableChecks;
}
// INTERFACE METHODS
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java Tue Mar 11 14:46:15 2014
@@ -21,13 +21,15 @@
package org.apache.derby.impl.sql.execute;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.List;
import java.util.Properties;
import java.util.Vector;
-
+import org.apache.derby.catalog.UUID;
import org.apache.derby.catalog.types.StatisticsImpl;
import org.apache.derby.iapi.db.TriggerExecutionContext;
import org.apache.derby.iapi.error.StandardException;
@@ -36,7 +38,6 @@ import org.apache.derby.iapi.services.co
import org.apache.derby.iapi.services.io.FormatableBitSet;
import org.apache.derby.iapi.services.io.StreamStorable;
import org.apache.derby.iapi.services.loader.GeneratedMethod;
-import org.apache.derby.shared.common.sanity.SanityManager;
import org.apache.derby.iapi.sql.Activation;
import org.apache.derby.iapi.sql.LanguageProperties;
import org.apache.derby.iapi.sql.ResultColumnDescriptor;
@@ -48,7 +49,6 @@ import org.apache.derby.iapi.sql.depend.
import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
-import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
import org.apache.derby.iapi.sql.dictionary.DataDictionary;
import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor;
@@ -62,6 +62,7 @@ import org.apache.derby.iapi.sql.execute
import org.apache.derby.iapi.sql.execute.RowChanger;
import org.apache.derby.iapi.sql.execute.TargetResultSet;
import org.apache.derby.iapi.store.access.AccessFactoryGlobals;
+import org.apache.derby.iapi.store.access.BackingStoreHashtable;
import org.apache.derby.iapi.store.access.ColumnOrdering;
import org.apache.derby.iapi.store.access.ConglomerateController;
import org.apache.derby.iapi.store.access.GroupFetchScanController;
@@ -71,11 +72,12 @@ import org.apache.derby.iapi.store.acces
import org.apache.derby.iapi.store.access.SortController;
import org.apache.derby.iapi.store.access.SortObserver;
import org.apache.derby.iapi.store.access.TransactionController;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
import org.apache.derby.iapi.types.DataValueDescriptor;
import org.apache.derby.iapi.types.NumberDataValue;
import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.iapi.types.SQLBoolean;
import org.apache.derby.iapi.util.StringUtil;
+import org.apache.derby.shared.common.sanity.SanityManager;
/**
* Insert the rows from the source into the specified
@@ -134,6 +136,8 @@ class InsertResultSet extends DMLWriteRe
private ExecIndexRow[] indexRows;
private final int fullTemplateId;
+ private final String schemaName;
+ private final String tableName;
private long[] sortIds;
private RowLocationRetRowSource[]
rowSources;
@@ -160,7 +164,8 @@ class InsertResultSet extends DMLWriteRe
* getSetAutoincrementValues.
*/
private NumberDataValue aiCache[];
-
+ private BackingStoreHashtable deferredChecks; // cached ref.
+ private List<UUID> violatingCheckConstraints;
/**
* If set to true, implies that this (rep)insertresultset has generated
* autoincrement values. During refresh for example, the autoincrement
@@ -257,7 +262,17 @@ class InsertResultSet extends DMLWriteRe
}
if (checkGM != null) {
- evaluateCheckConstraints();
+ boolean allOk = evaluateCheckConstraints();
+ if (!allOk) {
+ if (SanityManager.DEBUG) {
+ SanityManager.ASSERT(
+ violatingCheckConstraints != null &&
+ violatingCheckConstraints.size() > 0) ;
+ }
+
+ // We will do a callback to remember this by
+ // offendingRowLocation called from HeapController#load
+ }
}
// RESOLVE - optimize the cloning
if (constants.irgs.length > 0)
@@ -271,23 +286,44 @@ class InsertResultSet extends DMLWriteRe
}
}
- /**
- * Run the check constraints against the current row. Raise an error if
- * a check constraint is violated.
- *
- * @exception StandardException thrown on error
- */
- private void evaluateCheckConstraints()
- throws StandardException
- {
- if (checkGM != null)
- {
- // Evaluate the check constraints. The expression evaluation
- // will throw an exception if there is a violation, so there
- // is no need to check the result of the expression.
- checkGM.invoke(activation);
+ public void offendingRowLocation(RowLocation rl, long constainerId)
+ throws StandardException {
+ if (violatingCheckConstraints != null) {
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ schemaName,
+ tableName,
+ deferredChecks,
+ violatingCheckConstraints,
+ rl);
+ violatingCheckConstraints.clear();
+ }
+ }
+
+ /**
+ * Run the check constraints against the current row. Raise an error if
+ * a check constraint is violated, unless all the offending checks are
+ * deferred, in which case a false value will be returned. A NULL value
+ * will be interpreted as success (not violation).
+ *
+ * @exception StandardException thrown on error
+ */
+ private boolean evaluateCheckConstraints() throws StandardException {
+ boolean result = true;
+
+ if (checkGM != null) {
+ // Evaluate the check constraints. If all check constraint modes are
+ // immediate, a check error will throw rather than return a false
+ // value.
+ SQLBoolean allOk =
+ (SQLBoolean)checkGM.invoke(activation);
+ result = allOk.isNull() || allOk.getBoolean();
}
+
+ return result;
}
/*
@@ -302,6 +338,8 @@ class InsertResultSet extends DMLWriteRe
GeneratedMethod generationClauses,
GeneratedMethod checkGM,
int fullTemplate,
+ String schemaName,
+ String tableName,
Activation activation)
throws StandardException
{
@@ -311,6 +349,8 @@ class InsertResultSet extends DMLWriteRe
this.generationClauses = generationClauses;
this.checkGM = checkGM;
this.fullTemplateId = fullTemplate;
+ this.schemaName = schemaName;
+ this.tableName = tableName;
heapConglom = constants.conglomId;
tc = activation.getTransactionController();
@@ -360,8 +400,11 @@ class InsertResultSet extends DMLWriteRe
*/
if (triggerInfo != null)
{
- TriggerDescriptor td = triggerInfo.getTriggerArray()[0];
- throw StandardException.newException(SQLState.LANG_NO_BULK_INSERT_REPLACE_WITH_TRIGGER_DURING_EXECUTION, constants.getTableName(), td.getName());
+ TriggerDescriptor trD = triggerInfo.getTriggerArray()[0];
+ throw StandardException.newException(
+ SQLState.LANG_NO_BULK_INSERT_REPLACE_WITH_TRIGGER_DURING_EXECUTION,
+ constants.getTableName(),
+ trD.getName());
}
}
}
@@ -515,17 +558,17 @@ class InsertResultSet extends DMLWriteRe
throws StandardException
{
int size = columnIndexes.length;
- TableDescriptor td = dd.getTableDescriptor(constants.targetUUID);
+ TableDescriptor tabDesc = dd.getTableDescriptor(constants.targetUUID);
// all 1-based column ids.
for (int i = 0; i < size; i++)
{
- ColumnDescriptor cd = td.getColumnDescriptor(columnIndexes[i]);
+ ColumnDescriptor cd = tabDesc.getColumnDescriptor(columnIndexes[i]);
if (!verifyAutoGenColumn(cd))
{
throw StandardException.newException(
SQLState.LANG_INVALID_AUTOGEN_COLUMN_POSITION,
- new Integer(columnIndexes[i]), td.getName());
+ new Integer(columnIndexes[i]), tabDesc.getName());
}
}
}
@@ -538,16 +581,16 @@ class InsertResultSet extends DMLWriteRe
private int[] generatedColumnPositionsArray()
throws StandardException
{
- TableDescriptor td = dd.getTableDescriptor(constants.targetUUID);
+ TableDescriptor tabDesb = dd.getTableDescriptor(constants.targetUUID);
ColumnDescriptor cd;
- int size = td.getMaxColumnID();
+ int size = tabDesb.getMaxColumnID();
int[] generatedColumnPositionsArray = new int[size];
Arrays.fill(generatedColumnPositionsArray, -1);
int generatedColumnNumbers = 0;
for (int i=0; i<size; i++) {
- cd = td.getColumnDescriptor(i+1);
+ cd = tabDesb.getColumnDescriptor(i+1);
if (cd.isAutoincrement()) { //if the column has auto-increment value
generatedColumnNumbers++;
generatedColumnPositionsArray[i] = i+1;
@@ -574,11 +617,11 @@ class InsertResultSet extends DMLWriteRe
throws StandardException
{
int size = columnIndexes.length;
- TableDescriptor td = dd.getTableDescriptor(constants.targetUUID);
+ TableDescriptor tabDesc = dd.getTableDescriptor(constants.targetUUID);
//create an array of integer (the array size = number of columns in table)
// valid column positions are 1...getMaxColumnID()
- int[] uniqueColumnIndexes = new int[td.getMaxColumnID()];
+ int[] uniqueColumnIndexes = new int[tabDesc.getMaxColumnID()];
int uniqueColumnNumbers = 0;
@@ -618,7 +661,7 @@ class InsertResultSet extends DMLWriteRe
int size = columnNames.length;
int columnPositions[] = new int[size];
- TableDescriptor td = dd.getTableDescriptor(constants.targetUUID);
+ TableDescriptor tabDesc = dd.getTableDescriptor(constants.targetUUID);
ColumnDescriptor cd;
for (int i = 0; i < size; i++)
@@ -627,15 +670,15 @@ class InsertResultSet extends DMLWriteRe
{
throw StandardException.newException(
SQLState.LANG_INVALID_AUTOGEN_COLUMN_NAME,
- columnNames[i], td.getName());
+ columnNames[i], tabDesc.getName());
}
- cd = td.getColumnDescriptor(columnNames[i]);
+ cd = tabDesc.getColumnDescriptor(columnNames[i]);
if (!verifyAutoGenColumn(cd))
{
throw StandardException.newException(
SQLState.LANG_INVALID_AUTOGEN_COLUMN_NAME,
- columnNames[i], td.getName());
+ columnNames[i], tabDesc.getName());
}
columnPositions[i] = cd.getPosition();
@@ -659,9 +702,7 @@ class InsertResultSet extends DMLWriteRe
return ((cd != null) && cd.isAutoincrement());
}
- /**
- * @see ResultSet#getAutoGeneratedKeysResultset
- */
+ @Override
public ResultSet getAutoGeneratedKeysResultset()
{
return autoGeneratedKeysResultSet;
@@ -682,8 +723,7 @@ class InsertResultSet extends DMLWriteRe
getSetAutoincrementValue(int columnPosition, long increment)
throws StandardException
{
- long startValue = 0;
- NumberDataValue dvd;
+ NumberDataValue dvd;
int index = columnPosition - 1; // all our indices are 0 based.
/* As in DB2, only for single row insert: insert into t1(c1) values (..) do
@@ -706,6 +746,8 @@ class InsertResultSet extends DMLWriteRe
// System.out.println("in bulk insert");
if (aiCache[index].isNull())
{
+ long startValue;
+
if (bulkInsertReplace)
{
startValue = cd.getAutoincStart();
@@ -720,7 +762,7 @@ class InsertResultSet extends DMLWriteRe
lcc.autoincrementCreateCounter(td.getSchemaName(),
td.getName(),
cd.getColumnName(),
- new Long(startValue),
+ Long.valueOf(startValue),
increment,
columnPosition);
@@ -733,7 +775,8 @@ class InsertResultSet extends DMLWriteRe
else
{
NumberDataValue newValue;
- TransactionController nestedTC = null, tcToUse = tc;
+ TransactionController nestedTC = null;
+ TransactionController tcToUse;
try
{
@@ -854,8 +897,8 @@ class InsertResultSet extends DMLWriteRe
throws StandardException
{
boolean setUserIdentity = constants.hasAutoincrement() && isSingleRowResultSet();
- ExecRow deferredRowBuffer = null;
- long user_autoinc=0;
+ ExecRow deferredRowBuffer;
+ long user_autoinc=0;
/* Get or re-use the row changer.
*/
@@ -975,8 +1018,10 @@ class InsertResultSet extends DMLWriteRe
}
else
{
- // Evaluate any check constraints on the row
- evaluateCheckConstraints();
+ // Immediate mode violations will throw, so we only ever
+ // see false here with deferred constraint mode for one or more
+ // of the constraints being checked.
+ boolean allOk = evaluateCheckConstraints();
if (fkChecker != null)
{
@@ -1000,7 +1045,21 @@ class InsertResultSet extends DMLWriteRe
rowArray[i].getObject();
}
}
- rowChanger.insertRow(row);
+
+ if (allOk) {
+ rowChanger.insertRow(row, false);
+ } else {
+ RowLocation offendingRow = rowChanger.insertRow(row, true);
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ schemaName,
+ tableName,
+ deferredChecks,
+ violatingCheckConstraints,
+ offendingRow);
+ }
}
rowCount++;
@@ -1105,8 +1164,23 @@ class InsertResultSet extends DMLWriteRe
// we have to set the source row so the check constraint
// sees the correct row.
sourceResultSet.setCurrentRow(deferredRowBuffer);
- evaluateCheckConstraints();
- rowChanger.insertRow(deferredRowBuffer);
+ boolean allOk = evaluateCheckConstraints();
+
+ if (allOk) {
+ rowChanger.insertRow(deferredRowBuffer, false);
+ } else {
+ RowLocation offendingRow =
+ rowChanger.insertRow(deferredRowBuffer, true);
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ schemaName,
+ tableName,
+ deferredChecks,
+ violatingCheckConstraints,
+ offendingRow);
+ }
}
} finally
{
@@ -1172,11 +1246,13 @@ class InsertResultSet extends DMLWriteRe
protected ExecRow getNextRowCore( NoPutResultSet source )
throws StandardException
{
- ExecRow row = super.getNextRowCore( source );
+ ExecRow nextRow = super.getNextRowCore( source );
- if ( (row != null) && constants.underMerge() ) { row = processMergeRow( source, row ); }
+ if ( (nextRow != null) && constants.underMerge() ) {
+ nextRow = processMergeRow( source, nextRow );
+ }
- return row;
+ return nextRow;
}
/**
@@ -1315,6 +1391,11 @@ class InsertResultSet extends DMLWriteRe
sourceResultSet.setNeedsRowLocation(true);
}
+ if (constants.hasDeferrableChecks) {
+ sourceResultSet.setHasDeferrableChecks();
+ }
+
+
dd = lcc.getDataDictionary();
td = dd.getTableDescriptor(constants.targetUUID);
@@ -1418,8 +1499,6 @@ class InsertResultSet extends DMLWriteRe
TransactionController tc, ContextManager cm, ExecRow fullTemplate)
throws StandardException
{
- FKInfo fkInfo;
-
/*
** If there are no foreign keys, then nothing to worry
** about.
@@ -1433,9 +1512,8 @@ class InsertResultSet extends DMLWriteRe
return;
}
- for (int i = 0; i < fkInfoArray.length; i++)
+ for (FKInfo fkInfo : fkInfoArray)
{
- fkInfo = fkInfoArray[i];
/* With regular bulk insert, we only need to check the
* foreign keys in the table we inserted into. We need
@@ -1476,9 +1554,10 @@ class InsertResultSet extends DMLWriteRe
* #s have changed.
*/
pkConglom = (indexConversionTable.get(
- new Long(fkInfo.refConglomNumber))).longValue();
+ Long.valueOf(fkInfo.refConglomNumber))).longValue();
fkConglom = (indexConversionTable.get(
- new Long(fkInfo.fkConglomNumbers[index]))).longValue();
+ Long.valueOf(fkInfo.fkConglomNumbers[index]))).
+ longValue();
}
else
{
@@ -1491,9 +1570,10 @@ class InsertResultSet extends DMLWriteRe
* is very simple, though not very elegant.
*/
Long pkConglomLong = indexConversionTable.get(
- new Long(fkInfo.refConglomNumber));
+ Long.valueOf(fkInfo.refConglomNumber));
Long fkConglomLong = indexConversionTable.get(
- new Long(fkInfo.fkConglomNumbers[index]));
+ Long.valueOf(fkInfo.fkConglomNumbers[index]));
+
if (pkConglomLong == null)
{
pkConglom = fkInfo.refConglomNumber;
@@ -1512,7 +1592,7 @@ class InsertResultSet extends DMLWriteRe
}
}
bulkValidateForeignKeysCore(
- tc, cm, fkInfoArray[i], fkConglom, pkConglom,
+ tc, cm, fkInfo, fkConglom, pkConglom,
fkInfo.fkConstraintNames[index], fullTemplate);
}
}
@@ -1532,7 +1612,7 @@ class InsertResultSet extends DMLWriteRe
Long fkConglom = indexConversionTable.get(
new Long(fkInfo.fkConglomNumbers[0]));
bulkValidateForeignKeysCore(
- tc, cm, fkInfoArray[i], fkConglom.longValue(),
+ tc, cm, fkInfo, fkConglom.longValue(),
fkInfo.refConglomNumber, fkInfo.fkConstraintNames[0],
fullTemplate);
}
@@ -1655,12 +1735,10 @@ class InsertResultSet extends DMLWriteRe
if (fkScan != null)
{
fkScan.close();
- fkScan = null;
}
if (refScan != null)
{
refScan.close();
- refScan = null;
}
}
}
@@ -1749,7 +1827,7 @@ class InsertResultSet extends DMLWriteRe
boolean[] isAscending = constants.irgs[index].isAscending();
int numColumnOrderings;
- SortObserver sortObserver = null;
+ SortObserver sortObserver;
/* We can only reuse the wrappers when doing an
* external sort if there is only 1 index. Otherwise,
@@ -1782,8 +1860,6 @@ class InsertResultSet extends DMLWriteRe
indDes.isUnique() ? baseColumnPositions.length :
baseColumnPositions.length + 1;
- String[] columnNames = getColumnNames(baseColumnPositions);
-
sortObserver =
new UniqueIndexSortObserver(
tc,
@@ -2013,7 +2089,7 @@ class InsertResultSet extends DMLWriteRe
// We recreated the index, so any old deferred constraints
// information supported by the dropped index needs to be updated
// with the new index.
- DeferredDuplicates.updateIndexCID(
+ DeferredConstraintsMemory.updateIndexCID(
lcc, constants.indexCIDS[index], newIndexCongloms[index]);
indexConversionTable.put(new Long(constants.indexCIDS[index]),
@@ -2248,9 +2324,9 @@ class InsertResultSet extends DMLWriteRe
throws StandardException
{
int numIndexes = constants.irgs.length;
- ExecIndexRow[] indexRows = new ExecIndexRow[numIndexes];
- ExecRow baseRows = null;
- ColumnOrdering[][] ordering = new ColumnOrdering[numIndexes][];
+ ExecIndexRow[] idxRows = new ExecIndexRow[numIndexes];
+ ExecRow baseRows;
+ ColumnOrdering[][] order = new ColumnOrdering[numIndexes][];
int numColumns = td.getNumberOfColumns();
collation = new int[numIndexes][];
@@ -2298,14 +2374,14 @@ class InsertResultSet extends DMLWriteRe
for (int index = 0; index < numIndexes; index++)
{
// create a single index row template for each index
- indexRows[index] = constants.irgs[index].getIndexRowTemplate();
+ idxRows[index] = constants.irgs[index].getIndexRowTemplate();
// Get an index row based on the base row
// (This call is only necessary here because we need to pass a
// template to the sorter.)
constants.irgs[index].getIndexRow(baseRows,
rl,
- indexRows[index],
+ idxRows[index],
bitSet);
/* For non-unique indexes, we order by all columns + the RID.
@@ -2319,7 +2395,7 @@ class InsertResultSet extends DMLWriteRe
int[] baseColumnPositions = constants.irgs[index].baseColumnPositions();
boolean[] isAscending = constants.irgs[index].isAscending();
int numColumnOrderings;
- SortObserver sortObserver = null;
+ SortObserver sortObserver;
final IndexRowGenerator indDes = cd.getIndexDescriptor();
if (indDes.isUnique() || indDes.isUniqueDeferrable())
@@ -2328,8 +2404,6 @@ class InsertResultSet extends DMLWriteRe
indDes.isUnique() ? baseColumnPositions.length :
baseColumnPositions.length + 1;
- String[] columnNames = getColumnNames(baseColumnPositions);
-
String indexOrConstraintName = cd.getConglomerateName();
boolean deferred = false;
boolean uniqueDeferrable = false;
@@ -2353,7 +2427,7 @@ class InsertResultSet extends DMLWriteRe
uniqueDeferrable,
deferred,
indexOrConstraintName,
- indexRows[index],
+ idxRows[index],
true,
td.getName());
}
@@ -2361,17 +2435,17 @@ class InsertResultSet extends DMLWriteRe
{
numColumnOrderings = baseColumnPositions.length + 1;
sortObserver = new BasicSortObserver(false, false,
- indexRows[index],
+ idxRows[index],
true);
}
- ordering[index] = new ColumnOrdering[numColumnOrderings];
+ order[index] = new ColumnOrdering[numColumnOrderings];
for (int ii =0; ii < isAscending.length; ii++)
{
- ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
+ order[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
}
if (numColumnOrderings > isAscending.length)
{
- ordering[index][isAscending.length] =
+ order[index][isAscending.length] =
new IndexColumnOrder(isAscending.length);
}
@@ -2379,8 +2453,8 @@ class InsertResultSet extends DMLWriteRe
sortIds[index] =
tc.createSort(
(Properties)null,
- indexRows[index].getRowArrayClone(),
- ordering[index],
+ idxRows[index].getRowArrayClone(),
+ order[index],
sortObserver,
false, // not in order
rowCount, // est rows
@@ -2395,11 +2469,11 @@ class InsertResultSet extends DMLWriteRe
// are in the correct order.
rowSources = new RowLocationRetRowSource[numIndexes];
// Fill in the RowSources
- SortController[] sorters = new SortController[numIndexes];
+ SortController[] sorter = new SortController[numIndexes];
for (int index = 0; index < numIndexes; index++)
{
- sorters[index] = tc.openSort(sortIds[index]);
- sorters[index].completedInserts();
+ sorter[index] = tc.openSort(sortIds[index]);
+ sorter[index].completedInserts();
rowSources[index] = tc.openSortRowSource(sortIds[index]);
}
@@ -2430,7 +2504,7 @@ class InsertResultSet extends DMLWriteRe
/* Create the properties that language supplies when creating the
* the index. (The store doesn't preserve these.)
*/
- int indexRowLength = indexRows[index].nColumns();
+ int indexRowLength = idxRows[index].nColumns();
properties.put("baseConglomerateId", Long.toString(newHeapConglom));
if (cd.getIndexDescriptor().isUnique())
{
@@ -2464,7 +2538,7 @@ class InsertResultSet extends DMLWriteRe
newIndexCongloms[index] =
tc.createAndLoadConglomerate(
"BTREE",
- indexRows[index].getRowArray(),
+ idxRows[index].getRowArray(),
null, //default column sort order
collation[index],
properties,
@@ -2547,8 +2621,20 @@ class InsertResultSet extends DMLWriteRe
return columnNames;
}
+ @Override
public void finish() throws StandardException {
sourceResultSet.finish();
super.finish();
}
+
+ @Override
+ public void rememberConstraint(UUID cid) throws StandardException {
+ if (violatingCheckConstraints == null) {
+ violatingCheckConstraints = new ArrayList<UUID>();
+ }
+
+ if (!violatingCheckConstraints.contains(cid)) {
+ violatingCheckConstraints.add(cid);
+ }
+ }
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java Tue Mar 11 14:46:15 2014
@@ -71,7 +71,8 @@ extends BasicNoPutResultSetImpl
// fields used when being called as a RowSource
private boolean needsRowLocation;
- protected ExecRow clonedExecRow;
+ private boolean needsRowLocationForDeferredCheckConstraints;
+ protected ExecRow clonedExecRow;
protected TargetResultSet targetResultSet;
/* beetle 4464. compact flags into array of key column positions that we do check/skip nulls,
@@ -214,6 +215,10 @@ extends BasicNoPutResultSetImpl
this.needsRowLocation = needsRowLocation;
}
+ public void setHasDeferrableChecks() {
+ this.needsRowLocationForDeferredCheckConstraints = true;
+ }
+
// RowSource interface
/**
@@ -276,7 +281,12 @@ extends BasicNoPutResultSetImpl
return needsRowLocation;
}
- /**
+ public boolean needsRowLocationForDeferredCheckConstraints()
+ {
+ return needsRowLocationForDeferredCheckConstraints;
+ }
+
+ /**
* @see RowLocationRetRowSource#rowLocation
* @exception StandardException on error
*/
@@ -286,7 +296,11 @@ extends BasicNoPutResultSetImpl
targetResultSet.changedRow(clonedExecRow, rl);
}
+ public void offendingRowLocation(
+ RowLocation rl, long containdId) throws StandardException {
+ targetResultSet.offendingRowLocation(rl, containdId);
+ }
// class implementation
/**
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java Tue Mar 11 14:46:15 2014
@@ -45,6 +45,7 @@ import org.apache.derby.iapi.sql.execute
import org.apache.derby.iapi.sql.execute.ResultSetStatisticsFactory;
import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
import org.apache.derby.iapi.sql.execute.xplain.XPLAINVisitor;
+import org.apache.derby.iapi.types.BooleanDataValue;
import org.apache.derby.iapi.types.DataValueDescriptor;
/**
@@ -675,32 +676,6 @@ abstract class NoRowsResultSetImpl imple
}
/**
- * Run check constraints against the current row. Raise an error if
- * a check constraint is violated.
- *
- * @param checkGM Generated code to run the check constraint.
- * @param activation Class in which checkGM lives.
- *
- * @exception StandardException thrown on error
- */
- public static void evaluateCheckConstraints
- (
- GeneratedMethod checkGM,
- Activation activation
- )
- throws StandardException
- {
- if (checkGM != null)
- {
- // Evaluate the expression containing the check constraints.
- // This expression will throw an exception if there is a
- // violation, so there is no need to check the result.
- checkGM.invoke(activation);
- }
-
- }
-
- /**
* Does this ResultSet cause a commit or rollback.
*
* @return Whether or not this ResultSet cause a commit or rollback.
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java Tue Mar 11 14:46:15 2014
@@ -21,6 +21,7 @@
package org.apache.derby.impl.sql.execute;
+import java.util.Enumeration;
import org.apache.derby.shared.common.sanity.SanityManager;
import org.apache.derby.iapi.services.io.StreamStorable;
@@ -41,6 +42,7 @@ import org.apache.derby.iapi.types.RowLo
import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
import org.apache.derby.iapi.sql.execute.RowChanger;
+import org.apache.derby.iapi.types.SQLRef;
/**
@@ -77,8 +79,11 @@ class ProjectRestrictResultSet extends N
private boolean shortCircuitOpen;
private ExecRow projRow;
+ private boolean validatingCheckConstraint;
+ private long validatingBaseTableCID;
+ DeferredConstraintsMemory.CheckInfo ci;
+ Enumeration rowLocations;
- //
// class interface
//
ProjectRestrictResultSet(NoPutResultSet s,
@@ -91,6 +96,8 @@ class ProjectRestrictResultSet extends N
int cloneMapItem,
boolean reuseResult,
boolean doesProjection,
+ boolean validatingCheckConstraint,
+ long validatingBaseTableCID,
double optimizerEstimatedRowCount,
double optimizerEstimatedCost)
throws StandardException
@@ -110,6 +117,8 @@ class ProjectRestrictResultSet extends N
projectMapping = ((ReferencedColumnsDescriptorImpl) a.getPreparedStatement().getSavedObject(mapRefItem)).getReferencedColumnPositions();
this.reuseResult = reuseResult;
this.doesProjection = doesProjection;
+ this.validatingCheckConstraint = validatingCheckConstraint;
+ this.validatingBaseTableCID = validatingBaseTableCID;
// Allocate a result row if all of the columns are mapped from the source
if (projection == null)
@@ -169,6 +178,15 @@ class ProjectRestrictResultSet extends N
restrictBoolean.getBoolean());
}
+ if (validatingCheckConstraint) {
+ ci = (DeferredConstraintsMemory.CheckInfo)activation.
+ getLanguageConnectionContext().
+ getDeferredHashTables().get(
+ Long.valueOf(validatingBaseTableCID));
+ rowLocations = ci.infoRows.elements();
+ }
+
+
if (constantEval)
{
source.openCore();
@@ -260,7 +278,25 @@ class ProjectRestrictResultSet extends N
beginTime = getCurrentTimeMillis();
do
{
- candidateRow = source.getNextRowCore();
+
+ if (validatingCheckConstraint) {
+ candidateRow = null;
+
+ while (rowLocations.hasMoreElements() && candidateRow == null) {
+ DataValueDescriptor[] row =
+ (DataValueDescriptor[])rowLocations.nextElement();
+ RowLocation rl = (RowLocation)((SQLRef)row[0]).getObject();
+ ((ValidateCheckConstraintResultSet)source).
+ positionScanAtRowLocation(rl);
+ candidateRow = source.getNextRowCore();
+ // if null (deleted), we move to next
+ }
+
+
+ } else {
+ candidateRow = source.getNextRowCore();
+ }
+
if (candidateRow != null)
{
beginRT = getCurrentTimeMillis();
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java Tue Mar 11 14:46:15 2014
@@ -434,7 +434,7 @@ class RowChangerImpl implements RowChang
@param baseRow the row.
@exception StandardException Thrown on error
*/
- public void insertRow(ExecRow baseRow)
+ public RowLocation insertRow(ExecRow baseRow, boolean getRL)
throws StandardException
{
if (SanityManager.DEBUG)
@@ -447,16 +447,24 @@ class RowChangerImpl implements RowChang
}
else
{
- if (isc != null)
+ if (isc != null || getRL)
{
+ if (baseRowLocation == null) {
+ baseRowLocation = baseCC.newRowLocationTemplate();
+ }
baseCC.insertAndFetchLocation(baseRow.getRowArray(), baseRowLocation);
- isc.insert(baseRow, baseRowLocation);
+
+ if (isc != null) {
+ isc.insert(baseRow, baseRowLocation);
+ }
}
else
{
baseCC.insert(baseRow.getRowArray());
}
}
+
+ return getRL ? baseRowLocation : null;
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java Tue Mar 11 14:46:15 2014
@@ -21,11 +21,10 @@
package org.apache.derby.impl.sql.execute;
+import java.util.ArrayList;
import java.util.List;
-
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.reference.SQLState;
-import org.apache.derby.iapi.services.property.PropertyUtil;
import org.apache.derby.iapi.sql.Activation;
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
@@ -33,6 +32,7 @@ import org.apache.derby.iapi.sql.diction
import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
import org.apache.derby.iapi.sql.execute.ConstantAction;
+import org.apache.derby.iapi.util.IdUtil;
import org.apache.derby.impl.sql.compile.TableName;
/**
@@ -73,9 +73,11 @@ class SetConstraintsConstantAction exten
}
/**
- * This is the guts of the Execution-time logic for SET CONSTRAINT.
+ * This is the guts of the execution time logic for SET CONSTRAINT.
*
- * @see ConstantAction#executeConstantAction
+ * @param activation
+ *
+ * @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
@@ -86,15 +88,17 @@ class SetConstraintsConstantAction exten
activation.getLanguageConnectionContext();
final DataDictionary dd = lcc.getDataDictionary();
+ final List<String> boundConstraints = new ArrayList<String>();
if (constraints != null) {
for (TableName c : constraints) {
- SchemaDescriptor sd = dd.getSchemaDescriptor(
+
+ final SchemaDescriptor sd = dd.getSchemaDescriptor(
c.getSchemaName(),
lcc.getTransactionExecute(),
true);
- ConstraintDescriptor cd =
+ final ConstraintDescriptor cd =
dd.getConstraintDescriptor(c.getTableName(), sd.getUUID());
if (cd == null) {
@@ -104,6 +108,19 @@ class SetConstraintsConstantAction exten
c.getFullSQLName());
}
+ final String bound =
+ IdUtil.normalToDelimited(sd.getSchemaName()) + "." +
+ IdUtil.normalToDelimited(cd.getConstraintName());
+
+ if (boundConstraints.contains(bound)) {
+ throw StandardException.newException(
+ SQLState.LANG_DB2_DUPLICATE_NAMES,
+ cd.getConstraintName(),
+ bound);
+ } else {
+ boundConstraints.add(bound);
+ }
+
if (deferred && !cd.deferrable()) {
throw StandardException.newException(
SQLState.LANG_SET_CONSTRAINT_NOT_DEFERRABLE,
@@ -111,17 +128,20 @@ class SetConstraintsConstantAction exten
}
if (cd instanceof KeyConstraintDescriptor) {
- // Unique, primary key and foreign key
+ // Set unique, primary key and foreign key constraints
- lcc.setDeferred(activation,
+ lcc.setConstraintDeferred(activation,
((KeyConstraintDescriptor)cd).
getIndexConglomerateDescriptor(dd).
getConglomerateNumber(),
deferred);
} else {
- // Check constraints
- throw StandardException.newException(
- SQLState.NOT_IMPLEMENTED, "SET CONSTRAINT");
+ // Set check constraints
+ lcc.setConstraintDeferred(
+ activation,
+ cd.getTableDescriptor().getHeapConglomerateId(),
+ cd.getUUID(),
+ deferred);
}
}
} else {
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java Tue Mar 11 14:46:15 2014
@@ -78,7 +78,7 @@ class TableScanResultSet extends ScanRes
public int rowsPerRead;
public boolean forUpdate;
final boolean sameStartStopPosition;
- private boolean nextDone;
+ protected boolean nextDone;
private RowLocation rlTemplate;
// Run time statistics
@@ -105,17 +105,17 @@ class TableScanResultSet extends ScanRes
// For Scrollable insensitive updatable result sets, only qualify a row the
// first time it's been read, since an update can change a row so that it
// no longer qualifies
- private boolean qualify;
+ protected boolean qualify;
// currentRowIsValid is set to the result of positioning at a rowLocation.
// It will be true if the positioning was successful and false if the row
// was deleted under our feet. Whenenver currentRowIsValid is false it means
// that the row has been deleted.
- private boolean currentRowIsValid;
+ protected boolean currentRowIsValid;
// Indicates whether the scan has been positioned back to a previously read
// row, or it is accessing a row for the first time.
- private boolean scanRepositioned;
+ protected boolean scanRepositioned;
//
// class interface
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TemporaryRowHolderResultSet.java Tue Mar 11 14:46:15 2014
@@ -1231,6 +1231,18 @@ class TemporaryRowHolderResultSet implem
return false;
}
+ public void setHasDeferrableChecks() {
+ if (SanityManager.DEBUG) {
+ SanityManager.NOTREACHED();
+ }
+ }
+
+ public boolean needsRowLocationForDeferredCheckConstraints()
+ {
+ return false;
+ }
+
+
/**
rowLocation is a callback for the drainer of the row source to return
the rowLocation of the current row, i.e, the row that is being returned
@@ -1270,6 +1282,13 @@ class TemporaryRowHolderResultSet implem
public void rowLocation(RowLocation rl) throws StandardException
{ }
+ public void offendingRowLocation(
+ RowLocation rl, long containdId) throws StandardException {
+ if (SanityManager.DEBUG) {
+ SanityManager.NOTREACHED();
+ }
+ }
+
/**
* @see NoPutResultSet#positionScanAtRowLocation
*
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueIndexSortObserver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueIndexSortObserver.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueIndexSortObserver.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueIndexSortObserver.java Tue Mar 11 14:46:15 2014
@@ -43,7 +43,7 @@ class UniqueIndexSortObserver extends Ba
private final TransactionController tc;
private final LanguageConnectionContext lcc;
private final long indexCID;
- private BackingStoreHashtable deferredRowsHashTable;
+ private BackingStoreHashtable deferredDuplicates;
public UniqueIndexSortObserver(
TransactionController tc,
@@ -92,12 +92,11 @@ class UniqueIndexSortObserver extends Ba
@Override
public void rememberDuplicate(DataValueDescriptor[] row)
throws StandardException {
- deferredRowsHashTable = DeferredDuplicates.rememberDuplicate(
- tc,
- indexCID,
- deferredRowsHashTable,
- lcc,
- row);
+ deferredDuplicates = DeferredConstraintsMemory.rememberDuplicate(
+ lcc,
+ deferredDuplicates,
+ indexCID,
+ row);
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueWithDuplicateNullsIndexSortObserver.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueWithDuplicateNullsIndexSortObserver.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueWithDuplicateNullsIndexSortObserver.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueWithDuplicateNullsIndexSortObserver.java Tue Mar 11 14:46:15 2014
@@ -43,7 +43,7 @@ public class UniqueWithDuplicateNullsInd
private final TransactionController tc;
private final LanguageConnectionContext lcc;
private final long indexCID;
- private BackingStoreHashtable deferredRowsHashTable;
+ private BackingStoreHashtable deferredDuplicates;
/**
* Constructs an object of UniqueWithDuplicateNullsIndexSortObserver
*
@@ -118,12 +118,11 @@ public class UniqueWithDuplicateNullsInd
@Override
public void rememberDuplicate(DataValueDescriptor[] row)
throws StandardException {
- deferredRowsHashTable = DeferredDuplicates.rememberDuplicate(
- tc,
- indexCID,
- deferredRowsHashTable,
- lcc,
- row);
+ deferredDuplicates = DeferredConstraintsMemory.rememberDuplicate(
+ lcc,
+ deferredDuplicates,
+ indexCID,
+ row);
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateConstantAction.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateConstantAction.java Tue Mar 11 14:46:15 2014
@@ -37,6 +37,8 @@ import java.io.ObjectInput;
import java.io.IOException;
import java.util.Properties;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
/**
* This class describes compiled constants that are passed into
@@ -65,6 +67,9 @@ public class UpdateConstantAction extend
int numColumns;
+ private String schemaName;
+ private String tableName;
+
// CONSTRUCTORS
/**
@@ -76,7 +81,7 @@ public class UpdateConstantAction extend
/**
* Make the ConstantAction for an UPDATE statement.
*
- * @param conglomId Conglomerate ID.
+ * @param targetTableDesc descriptor for the table to be updated
* @param heapSCOCI StaticCompiledOpenConglomInfo for heap.
* @param irgs Index descriptors
* @param indexCIDS Conglomerate IDs of indices
@@ -100,7 +105,7 @@ public class UpdateConstantAction extend
* @param underMerge True if this is an action of a MERGE statement.
*/
UpdateConstantAction(
- long conglomId,
+ TableDescriptor targetTableDesc,
StaticCompiledOpenConglomInfo heapSCOCI,
IndexRowGenerator[] irgs,
long[] indexCIDS,
@@ -118,10 +123,11 @@ public class UpdateConstantAction extend
int numColumns,
boolean positionedUpdate,
boolean singleRowSource,
- boolean underMerge)
+ boolean underMerge)
+ throws StandardException
{
super(
- conglomId,
+ targetTableDesc.getHeapConglomerateId(),
heapSCOCI,
irgs,
indexCIDS,
@@ -143,6 +149,8 @@ public class UpdateConstantAction extend
this.changedColumnIds = changedColumnIds;
this.positionedUpdate = positionedUpdate;
this.numColumns = numColumns;
+ this.schemaName = targetTableDesc.getSchemaName();
+ this.tableName = targetTableDesc.getName();
}
// INTERFACE METHODS
@@ -186,4 +194,11 @@ public class UpdateConstantAction extend
public int getTypeFormatId() { return StoredFormatIds.UPDATE_CONSTANT_ACTION_V01_ID; }
// CLASS METHODS
+ public String getSchemaName() {
+ return schemaName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java Tue Mar 11 14:46:15 2014
@@ -21,15 +21,16 @@
package org.apache.derby.impl.sql.execute;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
-
+import org.apache.derby.catalog.UUID;
import org.apache.derby.iapi.db.TriggerExecutionContext;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.services.io.FormatableBitSet;
import org.apache.derby.iapi.services.io.StreamStorable;
import org.apache.derby.iapi.services.loader.GeneratedMethod;
-import org.apache.derby.shared.common.sanity.SanityManager;
import org.apache.derby.iapi.sql.Activation;
import org.apache.derby.iapi.sql.ResultDescription;
import org.apache.derby.iapi.sql.ResultSet;
@@ -45,6 +46,9 @@ import org.apache.derby.iapi.store.acces
import org.apache.derby.iapi.types.BooleanDataValue;
import org.apache.derby.iapi.types.DataValueDescriptor;
import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.iapi.types.SQLBoolean;
+import org.apache.derby.iapi.types.SQLRef;
+import org.apache.derby.shared.common.sanity.SanityManager;
/**
* Update the rows from the specified
@@ -98,6 +102,8 @@ class UpdateResultSet extends DMLWriteRe
boolean deferred;
boolean beforeUpdateCopyRequired = false;
+ private List<UUID> violatingCheckConstraints;
+ private BackingStoreHashtable deferredChecks; // cached ref.
/*
* class interface
*
@@ -422,6 +428,31 @@ class UpdateResultSet extends DMLWriteRe
}
}
+
+ /**
+ * Run check constraints against the current row. Raise an error if
+ * a check constraint is violated, unless all the offending checks are
+ * deferred, in which case a false value will be returned. A NULL value
+ * will be interpreted as success (not violation).
+ *
+ * @exception StandardException thrown on error
+ */
+ private boolean evaluateCheckConstraints() throws StandardException {
+ boolean result = true;
+
+ if (checkGM != null) {
+ // Evaluate the check constraints. If all check constraint modes are
+ // immediate, a check error will throw rather than return a false
+ // value.
+ SQLBoolean allOk =
+ (SQLBoolean)checkGM.invoke(activation);
+ result = allOk.isNull() || allOk.getBoolean();
+ }
+
+ return result;
+ }
+
+
public boolean collectAffectedRows() throws StandardException
{
@@ -471,7 +502,23 @@ class UpdateResultSet extends DMLWriteRe
*/
if (triggerInfo == null)
{
- evaluateCheckConstraints( checkGM, activation );
+ boolean allOk = evaluateCheckConstraints();
+ if (!allOk) {
+ DataValueDescriptor[] rw = row.getRowArray();
+ SQLRef r = (SQLRef)rw[rw.length - 1];
+ RowLocation baseRowLocation =
+ (RowLocation)r.getObject();
+
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ constants.getSchemaName(),
+ constants.getTableName(),
+ deferredChecks,
+ violatingCheckConstraints,
+ baseRowLocation);
+ }
}
/*
@@ -529,14 +576,26 @@ class UpdateResultSet extends DMLWriteRe
}
else
{
- evaluateCheckConstraints( checkGM, activation );
+ boolean allOk = evaluateCheckConstraints();
- /* Get the RowLocation to update
+ /* Get the RowLocation to update
* NOTE - Column #s in the Row are 1 based.
*/
RowLocation baseRowLocation = (RowLocation)
(row.getColumn(resultWidth)).getObject();
+ if (!allOk) {
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ constants.getSchemaName(),
+ constants.getTableName(),
+ deferredChecks,
+ violatingCheckConstraints,
+ baseRowLocation);
+ }
+
RowUtil.copyRefColumns(newBaseRow,
row,
numberOfBaseColumns,
@@ -801,10 +860,12 @@ class UpdateResultSet extends DMLWriteRe
** Otherwise we evaluated them as we read the
** rows in from the source.
*/
+ boolean allOk = true;
+
if (triggerInfo != null)
{
source.setCurrentRow(deferredTempRow);
- evaluateCheckConstraints(checkGM, activation);
+ allOk = evaluateCheckConstraints();
}
/*
@@ -814,7 +875,19 @@ class UpdateResultSet extends DMLWriteRe
DataValueDescriptor rlColumn = deferredTempRow2.getColumn(numberOfBaseColumns + 1);
RowLocation baseRowLocation =
(RowLocation) (rlColumn).getObject();
-
+
+ if (!allOk) {
+ deferredChecks =
+ DeferredConstraintsMemory.rememberCheckViolations(
+ lcc,
+ heapConglom,
+ constants.getSchemaName(),
+ constants.getTableName(),
+ deferredChecks,
+ violatingCheckConstraints,
+ baseRowLocation);
+ }
+
/* Get the base row at the given RowLocation */
boolean row_exists =
deferredBaseCC.fetch(
@@ -1056,4 +1129,12 @@ class UpdateResultSet extends DMLWriteRe
rowChanger.finish();
}
+ @Override
+ public void rememberConstraint(UUID cid) throws StandardException {
+ if (violatingCheckConstraints == null) {
+ violatingCheckConstraints = new ArrayList<UUID>();
+ }
+
+ violatingCheckConstraints.add(cid);
+ }
}
Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValidateCheckConstraintResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValidateCheckConstraintResultSet.java?rev=1576367&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValidateCheckConstraintResultSet.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValidateCheckConstraintResultSet.java Tue Mar 11 14:46:15 2014
@@ -0,0 +1,216 @@
+/*
+
+ Derby - Class org.apache.derby.impl.sql.execute.ValidateCheckConstraintResultSet
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derby.impl.sql.execute;
+
+import org.apache.derby.iapi.error.ExceptionUtil;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.loader.GeneratedMethod;
+import org.apache.derby.iapi.sql.Activation;
+import org.apache.derby.iapi.sql.execute.CursorResultSet;
+import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.store.access.Qualifier;
+import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
+import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.shared.common.sanity.SanityManager;
+
+/**
+ * Special result set used when checking deferred CHECK constraints. Activated
+ * by a special {@code --DERBY_PROPERTY validateCheckConstraint=<conglomId>}
+ * override on a SELECT query, cf DeferredConstraintsMemory#validateCheck. It
+ * relies on having a correct row location set prior to invoking {@code
+ * getNewtRowCore}, cf. the special code path in
+ * {@code ProjectRestrictResultSet#getNextRowCore} activated by
+ * {@code #validatingCheckConstraint}.
+ *
+ */
+final class ValidateCheckConstraintResultSet extends TableScanResultSet
+ implements CursorResultSet, Cloneable
+{
+
+ ValidateCheckConstraintResultSet(long conglomId,
+ StaticCompiledOpenConglomInfo scoci,
+ Activation activation,
+ int resultRowTemplate,
+ int resultSetNumber,
+ GeneratedMethod startKeyGetter, int startSearchOperator,
+ GeneratedMethod stopKeyGetter, int stopSearchOperator,
+ boolean sameStartStopPosition,
+ Qualifier[][] qualifiers,
+ String tableName,
+ String userSuppliedOptimizerOverrides,
+ String indexName,
+ boolean isConstraint,
+ boolean forUpdate,
+ int colRefItem,
+ int indexColItem,
+ int lockMode,
+ boolean tableLocked,
+ int isolationLevel,
+ int rowsPerRead,
+ boolean oneRowScan,
+ double optimizerEstimatedRowCount,
+ double optimizerEstimatedCost)
+ throws StandardException
+ {
+ super(conglomId,
+ scoci,
+ activation,
+ resultRowTemplate,
+ resultSetNumber,
+ startKeyGetter, startSearchOperator,
+ stopKeyGetter, stopSearchOperator,
+ sameStartStopPosition,
+ qualifiers,
+ tableName,
+ userSuppliedOptimizerOverrides,
+ indexName,
+ isConstraint,
+ forUpdate,
+ colRefItem,
+ indexColItem,
+ lockMode,
+ tableLocked,
+ isolationLevel,
+ rowsPerRead,
+ oneRowScan,
+ optimizerEstimatedRowCount,
+ optimizerEstimatedCost);
+ }
+
+ /**
+ * Return the current row (if any) from the base table scan, positioned
+ * correctly by our caller (ProjectRestrictNode). It overrides
+ * getNextRowCore from TableSCanResultSet, by using "fetch" instead of
+ * "fetchNext" on the underlying controller, otherwise it's identical.
+ * (This means it's probably over-general for the usage we have of it,
+ * but it felt safer to keep the code as similar as possible.)
+ * @return the row retrieved
+ * @exception StandardException thrown on failure to get next row
+ */
+ @Override
+ public ExecRow getNextRowCore() throws StandardException {
+ if (isXplainOnlyMode()) {
+ return null;
+ }
+
+ checkCancellationFlag();
+
+ if (SanityManager.DEBUG) {
+ SanityManager.ASSERT(scanRepositioned);
+ }
+
+ if (currentRow == null || scanRepositioned) {
+ currentRow = getCompactRow(candidate, accessedCols, isKeyed);
+ }
+
+ beginTime = getCurrentTimeMillis();
+
+ ExecRow result = null;
+
+ if (isOpen && !nextDone) {
+ // Only need to do 1 next per scan for 1 row scans.
+ nextDone = oneRowScan;
+
+ if (scanControllerOpened) {
+ boolean moreRows = true;
+
+ while (moreRows) {
+ try {
+ scanController.fetch(candidate.getRowArray());
+ } catch (StandardException e) {
+ // Offending rows may have been deleted in the
+ // transaction. As for compress, we won't even get here
+ // since we use a normal SELECT query then.
+ if (e.getSQLState().equals(
+ ExceptionUtil.getSQLStateFromIdentifier(
+ SQLState.AM_RECORD_NOT_FOUND))) {
+ moreRows = false;
+ break;
+ } else {
+ throw e;
+ }
+ }
+
+ rowsSeen++;
+ rowsThisScan++;
+
+ /*
+ ** Skip rows where there are start or stop positioners
+ ** that do not implement ordered null semantics and
+ ** there are columns in those positions that contain
+ ** null.
+ ** No need to check if start and stop positions are the
+ ** same, since all predicates in both will be ='s,
+ ** and hence evaluated in the store.
+ */
+ if ((! sameStartStopPosition) && skipRow(candidate)) {
+ rowsFiltered++;
+ continue;
+ }
+
+ /* beetle 3865, updateable cursor use index. If we have a
+ * hash table that holds updated records, and we hit it
+ * again, skip it, and remove it from hash since we can't
+ * hit it again, and we have a space in hash, so can stop
+ * scanning forward.
+ */
+ if (past2FutureTbl != null) {
+ RowLocation rowLoc = (RowLocation)currentRow.getColumn(
+ currentRow.nColumns());
+ if (past2FutureTbl.remove(rowLoc) != null) {
+ continue;
+ }
+ }
+
+ result = currentRow;
+ break;
+ }
+
+ /*
+ ** If we just finished a full scan of the heap, update
+ ** the number of rows in the scan controller.
+ **
+ ** NOTE: It would be more efficient to only update the
+ ** scan controller if the optimizer's estimated number of
+ ** rows were wrong by more than some threshold (like 10%).
+ ** This would require a little more work than I have the
+ ** time for now, however, as the row estimate that is given
+ ** to this result set is the total number of rows for all
+ ** scans, not the number of rows per scan.
+ */
+ if (! moreRows) {
+ setRowCountIfPossible(rowsThisScan);
+ currentRow = null;
+ }
+ }
+ }
+
+ setCurrentRow(result);
+ currentRowIsValid = true;
+ scanRepositioned = false;
+ qualify = true;
+
+ nextTime += getElapsedMillis(beginTime);
+ return result;
+ }
+}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/heap/HeapController.java Tue Mar 11 14:46:15 2014
@@ -21,6 +21,8 @@
package org.apache.derby.impl.store.access.heap;
+import java.util.List;
+import org.apache.derby.catalog.UUID;
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.shared.common.sanity.SanityManager;
@@ -50,6 +52,7 @@ import org.apache.derby.impl.store.acces
import org.apache.derby.impl.store.access.conglomerate.RowPosition;
import org.apache.derby.iapi.services.io.FormatableBitSet;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory;
/**
@@ -382,7 +385,8 @@ public class HeapController
RecordHandle rh;
HeapRowLocation rowlocation;
- if (callbackWithRowLocation)
+ if (callbackWithRowLocation ||
+ rowSource.needsRowLocationForDeferredCheckConstraints())
rowlocation = new HeapRowLocation();
else
rowlocation = null;
@@ -449,6 +453,12 @@ public class HeapController
rowlocation.setFrom(rh);
rowSource.rowLocation(rowlocation);
}
+
+ if (rowSource.needsRowLocationForDeferredCheckConstraints()) {
+ rowlocation.setFrom(rh);
+ rowSource.offendingRowLocation(rowlocation,
+ heap.getContainerid());
+ }
}
page.unlatch();
page = null;
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/MergeScanRowSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/MergeScanRowSource.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/MergeScanRowSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/MergeScanRowSource.java Tue Mar 11 14:46:15 2014
@@ -101,7 +101,12 @@ public class MergeScanRowSource extends
return false;
}
- /**
+ public boolean needsRowLocationForDeferredCheckConstraints()
+ {
+ return false;
+ }
+
+/**
* @see org.apache.derby.iapi.store.access.RowSource#needsToClone
*/
public boolean needsToClone()
@@ -119,6 +124,12 @@ public class MergeScanRowSource extends
SanityManager.THROWASSERT("unexpected call to RowSource.rowLocation");
}
+ public void offendingRowLocation(
+ RowLocation rl, long containdId) throws StandardException {
+ if (SanityManager.DEBUG) {
+ SanityManager.NOTREACHED();
+ }
+ }
/**
All columns are always set from a sorter
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/SortBufferRowSource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/SortBufferRowSource.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/SortBufferRowSource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/SortBufferRowSource.java Tue Mar 11 14:46:15 2014
@@ -102,6 +102,12 @@ public class SortBufferRowSource extends
return false;
}
+ public boolean needsRowLocationForDeferredCheckConstraints()
+ {
+ return false;
+ }
+
+
/**
* @see org.apache.derby.iapi.store.access.RowSource#needsToClone
*/
@@ -116,6 +122,12 @@ public class SortBufferRowSource extends
SanityManager.THROWASSERT("unexpected call to RowSource.rowLocation");
}
+ public void offendingRowLocation(
+ RowLocation rl, long containdId) throws StandardException {
+ if (SanityManager.DEBUG) {
+ SanityManager.NOTREACHED();
+ }
+ }
/**
All columns are always set from a sorter
Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAResource.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAResource.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAResource.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/EmbedXAResource.java Tue Mar 11 14:46:15 2014
@@ -307,9 +307,8 @@ class EmbedXAResource implements XAResou
} catch (SQLException sqle) {
XAException xe = wrapInXAException(sqle);
- if (sqle.getSQLState().equals(
- ExceptionUtil.getSQLStateFromIdentifier(
- SQLState.LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_T))) {
+ if (ExceptionUtil.
+ isDeferredConstraintViolation(sqle.getSQLState())) {
// We are rolling back
returnConnectionToResource(tranState, xid_im);
}
@@ -831,10 +830,11 @@ class EmbedXAResource implements XAResou
xaErrorCode = XAException.XA_RBTIMEOUT;
else if (seErrorCode >= ExceptionSeverity.SESSION_SEVERITY)
xaErrorCode = XAException.XAER_RMFAIL;
- else if (sqlstate.equals(StandardException.getSQLStateFromIdentifier(SQLState.LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_T)))
+ else if (ExceptionUtil.isDeferredConstraintViolation(sqlstate)) {
xaErrorCode = XAException.XA_RBINTEGRITY;
- else
+ } else {
xaErrorCode = XAException.XAER_RMERR;
+ }
xae = new XAException(message);
xae.errorCode = xaErrorCode;
Modified: db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/jdbc/XATransactionState.java Tue Mar 11 14:46:15 2014
@@ -365,9 +365,7 @@ final class XATransactionState extends C
try {
retVal = conn.xa_prepare();
} catch (SQLException e) {
- if (e.getSQLState().equals(
- ExceptionUtil.getSQLStateFromIdentifier(
- SQLState.LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_T))) {
+ if (ExceptionUtil.isDeferredConstraintViolation(e.getSQLState())) {
// we are rolling back
xa_finalize();
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Tue Mar 11 14:46:15 2014
@@ -898,6 +898,22 @@ Guide.
<arg>constraintName</arg>
</msg>
+ <msg>
+ <name>23514.T.1</name>
+ <text>The transaction was aborted because of a deferred constraint violation: Check constraint identified by '{0}' defined on '{1}' as '{2}'.</text>
+ <arg>indexOrConstraintName</arg>
+ <arg>tableName</arg>
+ <arg>constraintText</arg>
+ </msg>
+
+ <msg>
+ <name>23515.S.1</name>
+ <text>Deferred constraint violation: Check constraint identified by '{0}' defined on '{1}' as '{2}'.</text>
+ <arg>indexOrConstraintName</arg>
+ <arg>tableName</arg>
+ <arg>constraintText</arg>
+ </msg>
+
</family>
Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Tue Mar 11 14:46:15 2014
@@ -744,6 +744,8 @@ public interface SQLState {
String LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_S = "23507.S.1";
String LANG_FK_VIOLATION = "23503";
String LANG_CHECK_CONSTRAINT_VIOLATED = "23513";
+ String LANG_DEFERRED_CHECK_CONSTRAINT_T = "23514.T.1";
+ String LANG_DEFERRED_CHECK_CONSTRAINT_S = "23515.S.1";
// From SQL/XML[2006] spec; there are others, but
// these are the ones we actually use with our