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 mi...@apache.org on 2007/05/07 09:47:35 UTC
svn commit: r535770 - in /db/derby/code/trunk/java/engine/org/apache/derby:
iapi/sql/dictionary/ impl/sql/execute/
Author: mikem
Date: Mon May 7 00:47:34 2007
New Revision: 535770
URL: http://svn.apache.org/viewvc?view=rev&rev=535770
Log:
DERBY-2537
This checkin fixes create index, alter table, and bulk insert to correctly
set the collation in the persistent tables and indexes that they create.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java?view=diff&rev=535770&r1=535769&r2=535770
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java Mon May 7 00:47:34 2007
@@ -22,6 +22,7 @@
package org.apache.derby.iapi.sql.dictionary;
import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
+
import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
import org.apache.derby.iapi.sql.execute.ExecutionContext;
@@ -29,8 +30,9 @@
import org.apache.derby.iapi.sql.execute.ExecRow;
import org.apache.derby.iapi.sql.execute.ExecutionFactory;
-import org.apache.derby.iapi.types.RowLocation;
import org.apache.derby.iapi.types.DataTypeDescriptor;
+import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.iapi.types.StringDataValue;
import org.apache.derby.iapi.services.io.Formatable;
import org.apache.derby.iapi.services.io.FormatIdUtil;
@@ -241,6 +243,41 @@
}
return false;
}
+
+ /**
+ * Return an array of collation ids for this table.
+ * <p>
+ * Return an array of collation ids, one for each column in the
+ * columnDescriptorList. This is useful for passing collation id info
+ * down to store, for instance in createConglomerate() to create
+ * the index.
+ *
+ * This is only expected to get called during ddl, so object allocation
+ * is ok.
+ *
+ * @param columnList ColumnDescriptors describing the base table.
+ *
+ * @exception StandardException Standard exception policy.
+ **/
+ public int[] getColumnCollationIds(ColumnDescriptorList columnList)
+ throws StandardException
+ {
+ int[] base_cols = id.baseColumnPositions();
+ int[] collation_ids = new int[base_cols.length + 1];
+
+ for (int i = 0; i < base_cols.length; i++)
+ {
+ collation_ids[i] =
+ columnList.elementAt(
+ base_cols[i] - 1).getType().getCollationType();
+ }
+
+ // row location column at end is always basic collation type.
+ collation_ids[collation_ids.length - 1] =
+ StringDataValue.COLLATION_TYPE_UCS_BASIC;
+
+ return(collation_ids);
+ }
/**
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java?view=diff&rev=535770&r1=535769&r2=535770
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TableDescriptor.java Mon May 7 00:47:34 2007
@@ -503,11 +503,14 @@
}
/**
- * Return an array of collation ids.
+ * Return an array of collation ids for this table.
* <p>
* Return an array of collation ids, one for each column in the
* columnDescriptorList. This is useful for passing collation id info
* down to store, for instance in createConglomerate().
+ *
+ * This is only expected to get called during ddl, so object allocation
+ * is ok.
*
* @exception StandardException Standard exception policy.
**/
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java?view=diff&rev=535770&r1=535769&r2=535770
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java Mon May 7 00:47:34 2007
@@ -90,98 +90,101 @@
implements RowLocationRetRowSource
{
- protected SchemaDescriptor sd;
- protected String tableName;
- protected UUID schemaId;
- protected int tableType;
- protected long tableConglomerateId;
- protected ColumnInfo[] columnInfo;
- protected ConstraintConstantAction[] constraintActions;
- protected char lockGranularity;
- private boolean compressTable;
- private boolean sequential;
- private int behavior;
-
- // Alter table compress and Drop column
- private boolean doneScan;
- private boolean[] needToDropSort;
- private boolean[] validRow;
- private int bulkFetchSize = 16;
- private int currentCompressRow;
- private int numIndexes;
- private int rowCount;
- private long estimatedRowCount;
- private long[] indexConglomerateNumbers;
- private long[] sortIds;
- private FormatableBitSet indexedCols;
- private ConglomerateController compressHeapCC;
- private ExecIndexRow[] indexRows;
- private ExecRow[] baseRow;
- private ExecRow currentRow;
- private GroupFetchScanController compressHeapGSC;
- private IndexRowGenerator[] compressIRGs;
- private DataValueDescriptor[][] baseRowArray;
- private RowLocation[] compressRL;
- private SortController[] sorters;
- private int columnPosition;
- private ColumnOrdering[][] ordering;
- private int[][] collation;
-
- private TableDescriptor td;
-
-
- //truncate table
- private boolean truncateTable;
-
- // CONSTRUCTORS
- private LanguageConnectionContext lcc;
- private DataDictionary dd;
- private DependencyManager dm;
- private TransactionController tc;
- private Activation activation;
+ // copied from constructor args and stored locally.
+ private SchemaDescriptor sd;
+ private String tableName;
+ private UUID schemaId;
+ private int tableType;
+ private ColumnInfo[] columnInfo;
+ private ConstraintConstantAction[] constraintActions;
+ private char lockGranularity;
+ private long tableConglomerateId;
+ private boolean compressTable;
+ private int behavior;
+ private boolean sequential;
+ private boolean truncateTable;
+
+
+
+ // Alter table compress and Drop column
+ private boolean doneScan;
+ private boolean[] needToDropSort;
+ private boolean[] validRow;
+ private int bulkFetchSize = 16;
+ private int currentCompressRow;
+ private int numIndexes;
+ private int rowCount;
+ private long estimatedRowCount;
+ private long[] indexConglomerateNumbers;
+ private long[] sortIds;
+ private FormatableBitSet indexedCols;
+ private ConglomerateController compressHeapCC;
+ private ExecIndexRow[] indexRows;
+ private ExecRow[] baseRow;
+ private ExecRow currentRow;
+ private GroupFetchScanController compressHeapGSC;
+ private IndexRowGenerator[] compressIRGs;
+ private DataValueDescriptor[][] baseRowArray;
+ private RowLocation[] compressRL;
+ private SortController[] sorters;
+ private int droppedColumnPosition;
+ private ColumnOrdering[][] ordering;
+ private int[][] collation;
+
+ private TableDescriptor td;
+
+
+
+ // CONSTRUCTORS
+ private LanguageConnectionContext lcc;
+ private DataDictionary dd;
+ private DependencyManager dm;
+ private TransactionController tc;
+ private Activation activation;
/**
* Make the AlterAction for an ALTER TABLE statement.
*
- * @param sd descriptor for the schema that table lives in.
- * @param tableName Name of table.
- * @param tableId UUID of table
+ * @param sd descriptor for the table's schema.
+ * @param tableName Name of table.
+ * @param tableId UUID of table
* @param tableConglomerateId heap conglomerate number of table
- * @param tableType Type of table (e.g., BASE).
- * @param columnInfo Information on all the columns in the table.
+ * @param tableType Type of table (e.g., BASE).
+ * @param columnInfo Information on all the columns in the table.
* @param constraintActions ConstraintConstantAction[] for constraints
- * @param lockGranularity The lock granularity.
- * @param compressTable Whether or not this is a compress table
- * @param behavior drop behavior for dropping column
- * @param sequential If compress table/drop column, whether or not sequential
- * @param truncateTable Whether or not this is a truncate table
+ * @param lockGranularity The lock granularity.
+ * @param compressTable Whether or not this is a compress table
+ * @param behavior drop behavior for dropping column
+ * @param sequential If compress table/drop column,
+ * whether or not sequential
+ * @param truncateTable Whether or not this is a truncate table
*/
AlterTableConstantAction(
- SchemaDescriptor sd,
- String tableName,
- UUID tableId,
- long tableConglomerateId,
- int tableType,
- ColumnInfo[] columnInfo,
- ConstraintConstantAction[] constraintActions,
- char lockGranularity,
- boolean compressTable,
- int behavior,
- boolean sequential,
- boolean truncateTable)
+ SchemaDescriptor sd,
+ String tableName,
+ UUID tableId,
+ long tableConglomerateId,
+ int tableType,
+ ColumnInfo[] columnInfo,
+ ConstraintConstantAction[] constraintActions,
+ char lockGranularity,
+ boolean compressTable,
+ int behavior,
+ boolean sequential,
+ boolean truncateTable)
{
super(tableId);
- this.sd = sd;
- this.tableName = tableName;
- this.tableConglomerateId = tableConglomerateId;
- this.tableType = tableType;
- this.columnInfo = columnInfo;
- this.constraintActions = constraintActions;
- this.lockGranularity = lockGranularity;
- this.compressTable = compressTable;
- this.behavior = behavior;
- this.sequential = sequential;
- this.truncateTable = truncateTable;
+ this.sd = sd;
+ this.tableName = tableName;
+ this.tableConglomerateId = tableConglomerateId;
+ this.tableType = tableType;
+ this.columnInfo = columnInfo;
+ this.constraintActions = constraintActions;
+ this.lockGranularity = lockGranularity;
+ this.compressTable = compressTable;
+ this.behavior = behavior;
+ this.sequential = sequential;
+ this.truncateTable = truncateTable;
if (SanityManager.DEBUG)
{
@@ -213,13 +216,18 @@
*
* @exception StandardException Thrown on failure
*/
- public void executeConstantAction( Activation activation )
- throws StandardException
+ public void executeConstantAction(
+ Activation activation)
+ throws StandardException
{
- LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
- DataDictionary dd = lcc.getDataDictionary();
- DependencyManager dm = dd.getDependencyManager();
- TransactionController tc = lcc.getTransactionExecute();
+ LanguageConnectionContext lcc =
+ activation.getLanguageConnectionContext();
+ DataDictionary dd = lcc.getDataDictionary();
+ DependencyManager dm = dd.getDependencyManager();
+ TransactionController tc = lcc.getTransactionExecute();
+
+ int numRows = 0;
+ boolean tableScanned = false;
/*
** Inform the data dictionary that we are about to write to it.
@@ -235,9 +243,9 @@
// now do the real work
// get an exclusive lock of the heap, to avoid deadlock on rows of
- // SYSCOLUMNS etc datadictionary tables (track 879) and phantom table
+ // SYSCOLUMNS etc datadictionary tables and phantom table
// descriptor, in which case table shape could be changed by a
- // concurrent thread doing add/drop column (track 3804 and 3825)
+ // concurrent thread doing add/drop column.
// older version (or at target) has to get td first, potential deadlock
if (tableConglomerateId == 0)
@@ -260,50 +268,24 @@
SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
}
- if(truncateTable)
+ if (truncateTable)
dm.invalidateFor(td, DependencyManager.TRUNCATE_TABLE, lcc);
else
dm.invalidateFor(td, DependencyManager.ALTER_TABLE, lcc);
- execGuts( activation );
- }
-
-
- /**
- * Wrapper for this DDL action. Factored out so that our child,
- * RepAlterTableConstantAction
- * could enjoy the benefits of the startWriting() method above.
- *
- *
- * @exception StandardException Thrown on failure
- */
- public void execGuts( Activation activation)
- throws StandardException
- {
- ColumnDescriptor columnDescriptor;
- int numRows = 0;
- boolean tableNeedsScanning = false;
- boolean tableScanned = false;
-
- LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
- DataDictionary dd = lcc.getDataDictionary();
- DependencyManager dm = dd.getDependencyManager();
- TransactionController tc = lcc.getTransactionExecute();
// Save the TableDescriptor off in the Activation
activation.setDDLTableDescriptor(td);
/*
- ** 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.
+ ** 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.
*/
if (sd == null)
{
sd = getAndCheckSchemaDescriptor(dd, schemaId, "ALTER TABLE");
}
-
/* Prepare all dependents to invalidate. (This is there chance
* to say that they can't be invalidated. For example, an open
* cursor referencing a table/view that the user is attempting to
@@ -317,6 +299,8 @@
// Are we working on columns?
if (columnInfo != null)
{
+ boolean tableNeedsScanning = false;
+
/* NOTE: We only allow a single column to be added within
* each ALTER TABLE command at the language level. However,
* this may change some day, so we will try to plan for it.
@@ -347,11 +331,12 @@
if (tableNeedsScanning)
{
numRows = getSemiRowCount(tc);
- // Don't allow user to add non-nullable column to non-empty table
+ // Don't allow add of non-nullable column to non-empty table
if (numRows > 0)
{
- throw StandardException.newException(SQLState.LANG_ADDING_NON_NULL_COLUMN_TO_NON_EMPTY_TABLE,
- td.getQualifiedName());
+ throw StandardException.newException(
+ SQLState.LANG_ADDING_NON_NULL_COLUMN_TO_NON_EMPTY_TABLE,
+ td.getQualifiedName());
}
tableScanned = true;
}
@@ -367,7 +352,7 @@
if (columnInfo[ix].action == ColumnInfo.CREATE)
{
- addNewColumnToTable(activation, ix);
+ addNewColumnToTable(activation, lcc, dd, tc, ix);
}
else if (columnInfo[ix].action ==
ColumnInfo.MODIFY_COLUMN_DEFAULT_RESTART ||
@@ -386,32 +371,36 @@
else if (columnInfo[ix].action ==
ColumnInfo.MODIFY_COLUMN_CONSTRAINT)
{
- modifyColumnConstraint(activation, columnInfo[ix].name, true);
+ modifyColumnConstraint(
+ activation, columnInfo[ix].name, true);
}
else if (columnInfo[ix].action ==
ColumnInfo.MODIFY_COLUMN_CONSTRAINT_NOT_NULL)
{
- if (! tableScanned)
+ if (!tableScanned)
{
tableScanned = true;
numRows = getSemiRowCount(tc);
}
+
// check that the data in the column is not null
- String colNames[] = new String[1];
- colNames[0] = columnInfo[ix].name;
+ String colNames[] = new String[1];
+ colNames[0] = columnInfo[ix].name;
boolean nullCols[] = new boolean[1];
/* note validateNotNullConstraint returns true if the
* column is nullable
*/
- if (validateNotNullConstraint(colNames, nullCols,
- numRows, lcc, SQLState.LANG_NULL_DATA_IN_NON_NULL_COLUMN))
+ if (validateNotNullConstraint(
+ colNames, nullCols, numRows, lcc,
+ SQLState.LANG_NULL_DATA_IN_NON_NULL_COLUMN))
{
/* nullable column - modify it to be not null
* This is O.K. at this point since we would have
* thrown an exception if any data was null
*/
- modifyColumnConstraint(activation, columnInfo[ix].name, false);
+ modifyColumnConstraint(
+ activation, columnInfo[ix].name, false);
}
}
else if (columnInfo[ix].action == ColumnInfo.DROP)
@@ -429,7 +418,9 @@
/* Create/Drop any constraints */
if (constraintActions != null)
{
- for (int conIndex = 0; conIndex < constraintActions.length; conIndex++)
+ for (int conIndex = 0;
+ conIndex < constraintActions.length;
+ conIndex++)
{
ConstraintConstantAction cca = constraintActions[conIndex];
@@ -438,28 +429,36 @@
int constraintType = cca.getConstraintType();
/* Some constraint types require special checking:
- * Check - table must be empty, for now
- * Primary Key - table cannot already have a primary key
+ * Check - table must be empty, for now
+ * Primary Key - table cannot already have a primary key
*/
switch (constraintType)
{
case DataDictionary.PRIMARYKEY_CONSTRAINT:
- // Check to see if a constraint of the same type already exists
- ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
+
+ // Check to see if a constraint of the same type
+ // already exists
+ ConstraintDescriptorList cdl =
+ dd.getConstraintDescriptors(td);
+
if (cdl.getPrimaryKey() != null)
{
- throw StandardException.newException(SQLState.LANG_ADD_PRIMARY_KEY_FAILED1,
- td.getQualifiedName());
+ throw StandardException.newException(
+ SQLState.LANG_ADD_PRIMARY_KEY_FAILED1,
+ td.getQualifiedName());
}
- if (! tableScanned)
+
+ if (!tableScanned)
{
tableScanned = true;
numRows = getSemiRowCount(tc);
}
break;
+
case DataDictionary.CHECK_CONSTRAINT:
- if (! tableScanned)
+
+ if (!tableScanned)
{
tableScanned = true;
numRows = getSemiRowCount(tc);
@@ -473,10 +472,10 @@
** to lump together several checks.
*/
ConstraintConstantAction.validateConstraint(
- cca.getConstraintName(),
- ((CreateConstraintConstantAction)cca).getConstraintText(),
- td,
- lcc, true);
+ cca.getConstraintName(),
+ ((CreateConstraintConstantAction)cca).getConstraintText(),
+ td,
+ lcc, true);
}
break;
}
@@ -487,12 +486,15 @@
{
if (!(cca instanceof DropConstraintConstantAction))
{
- SanityManager.THROWASSERT("constraintActions[" + conIndex +
- "] expected to be instanceof DropConstraintConstantAction not " +
- cca.getClass().getName());
+ SanityManager.THROWASSERT(
+ "constraintActions[" + conIndex +
+ "] expected to be instanceof " +
+ "DropConstraintConstantAction not " +
+ cca.getClass().getName());
}
}
}
+
constraintActions[conIndex].executeConstantAction(activation);
}
}
@@ -506,7 +508,8 @@
lockGranularity != 'R')
{
SanityManager.THROWASSERT(
- "lockGranularity expected to be 'T'or 'R', not " + lockGranularity);
+ "lockGranularity expected to be 'T'or 'R', not " +
+ lockGranularity);
}
}
@@ -527,8 +530,6 @@
{
truncateTable(activation);
}
-
-
}
/**
@@ -538,20 +539,19 @@
* statement-- currently we allow only one.
* @exception StandardException thrown on failure.
*/
- private void addNewColumnToTable(Activation activation,
- int ix)
+ private void addNewColumnToTable(
+ Activation activation,
+ LanguageConnectionContext lcc,
+ DataDictionary dd,
+ TransactionController tc,
+ int ix)
throws StandardException
{
- LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
- DataDictionary dd = lcc.getDataDictionary();
- DependencyManager dm = dd.getDependencyManager();
- TransactionController tc = lcc.getTransactionExecute();
-
- ColumnDescriptor columnDescriptor =
+ ColumnDescriptor columnDescriptor =
td.getColumnDescriptor(columnInfo[ix].name);
DataValueDescriptor storableDV;
- int colNumber = td.getMaxColumnID() + ix;
- DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
+ int colNumber = td.getMaxColumnID() + ix;
+ DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
/* We need to verify that the table does not have an existing
* column with the same name before we try to add the new
@@ -561,11 +561,11 @@
{
throw
StandardException.newException(
- SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
- columnDescriptor.getDescriptorType(),
- columnInfo[ix].name,
- td.getDescriptorType(),
- td.getQualifiedName());
+ SQLState.LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT,
+ columnDescriptor.getDescriptorType(),
+ columnInfo[ix].name,
+ td.getDescriptorType(),
+ td.getQualifiedName());
}
if (columnInfo[ix].defaultValue != null)
@@ -593,17 +593,18 @@
// Add the column to syscolumns.
// Column ids in system tables are 1-based
- columnDescriptor = new ColumnDescriptor(
- columnInfo[ix].name,
- colNumber + 1,
- columnInfo[ix].dataType,
- columnInfo[ix].defaultValue,
- columnInfo[ix].defaultInfo,
- td,
- defaultUUID,
- columnInfo[ix].autoincStart,
- columnInfo[ix].autoincInc
- );
+ columnDescriptor =
+ new ColumnDescriptor(
+ columnInfo[ix].name,
+ colNumber + 1,
+ columnInfo[ix].dataType,
+ columnInfo[ix].defaultValue,
+ columnInfo[ix].defaultInfo,
+ td,
+ defaultUUID,
+ columnInfo[ix].autoincStart,
+ columnInfo[ix].autoincInc
+ );
dd.addDescriptor(columnDescriptor, td,
DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
@@ -713,9 +714,9 @@
{
throw
StandardException.newException(
- SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
- columnInfo[ix].name,
- td.getQualifiedName());
+ SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
+ columnInfo[ix].name,
+ td.getQualifiedName());
}
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
@@ -725,18 +726,19 @@
// can NOT drop a column if it is the only one in the table
if (size == 1)
{
- throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
- dm.getActionString(DependencyManager.DROP_COLUMN),
- "THE *LAST* COLUMN " + columnInfo[ix].name,
- "TABLE",
- td.getQualifiedName() );
+ throw StandardException.newException(
+ SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
+ dm.getActionString(DependencyManager.DROP_COLUMN),
+ "THE *LAST* COLUMN " + columnInfo[ix].name,
+ "TABLE",
+ td.getQualifiedName() );
}
- columnPosition = columnDescriptor.getPosition();
+ droppedColumnPosition = columnDescriptor.getPosition();
boolean cascade = (behavior == StatementType.DROP_CASCADE);
FormatableBitSet toDrop = new FormatableBitSet(size + 1);
- toDrop.set(columnPosition);
+ toDrop.set(droppedColumnPosition);
td.setReferencedColumnMap(toDrop);
dm.invalidateFor(td,
@@ -747,8 +749,8 @@
// If column has a default we drop the default and any dependencies
if (columnDescriptor.getDefaultInfo() != null)
{
- DefaultDescriptor defaultDesc = columnDescriptor.getDefaultDescriptor(dd);
- dm.clearDependencies(lcc, defaultDesc);
+ dm.clearDependencies(
+ lcc, columnDescriptor.getDefaultDescriptor(dd));
}
// need to deal with triggers if has referencedColumns
@@ -764,24 +766,28 @@
boolean changed = false;
for (j = 0; j < refColLen; j++)
{
- if (referencedCols[j] > columnPosition)
+ if (referencedCols[j] > droppedColumnPosition)
+ {
changed = true;
- else if (referencedCols[j] == columnPosition)
+ }
+ else if (referencedCols[j] == droppedColumnPosition)
{
if (cascade)
{
trd.drop(lcc);
activation.addWarning(
- StandardException.newWarning(SQLState.LANG_TRIGGER_DROPPED,
- trd.getName(), td.getName()));
+ StandardException.newWarning(
+ SQLState.LANG_TRIGGER_DROPPED,
+ trd.getName(), td.getName()));
}
else
{ // we'd better give an error if don't drop it,
// otherwsie there would be unexpected behaviors
- throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
- dm.getActionString(DependencyManager.DROP_COLUMN),
- columnInfo[ix].name, "TRIGGER",
- trd.getName() );
+ throw StandardException.newException(
+ SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
+ dm.getActionString(DependencyManager.DROP_COLUMN),
+ columnInfo[ix].name, "TRIGGER",
+ trd.getName() );
}
break;
}
@@ -793,7 +799,7 @@
dd.dropTriggerDescriptor(trd, tc);
for (j = 0; j < refColLen; j++)
{
- if (referencedCols[j] > columnPosition)
+ if (referencedCols[j] > droppedColumnPosition)
referencedCols[j]--;
}
dd.addDescriptor(trd, sd,
@@ -809,7 +815,8 @@
// round. This will ensure that self-referential constraints will
// work OK.
int tbr_size = 0;
- ConstraintDescriptor[] toBeRemoved = new ConstraintDescriptor[csdl_size];
+ ConstraintDescriptor[] toBeRemoved =
+ new ConstraintDescriptor[csdl_size];
// let's go downwards, don't want to get messed up while removing
for (int i = csdl_size - 1; i >= 0; i--)
@@ -820,9 +827,9 @@
boolean changed = false;
for (j = 0; j < numRefCols; j++)
{
- if (referencedColumns[j] > columnPosition)
+ if (referencedColumns[j] > droppedColumnPosition)
changed = true;
- if (referencedColumns[j] == columnPosition)
+ if (referencedColumns[j] == droppedColumnPosition)
break;
}
if (j == numRefCols) // column not referenced
@@ -832,7 +839,7 @@
dd.dropConstraintDescriptor(td, cd, tc);
for (j = 0; j < numRefCols; j++)
{
- if (referencedColumns[j] > columnPosition)
+ if (referencedColumns[j] > droppedColumnPosition)
referencedColumns[j]--;
}
((CheckConstraintDescriptor) cd).setReferencedColumnsDescriptor(new ReferencedColumnsDescriptorImpl(referencedColumns));
@@ -846,15 +853,16 @@
// Reject the DROP COLUMN, because there exists a constraint
// which references this column.
//
- throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
- dm.getActionString(DependencyManager.DROP_COLUMN),
- columnInfo[ix].name, "CONSTRAINT",
- cd.getConstraintName() );
+ throw StandardException.newException(
+ SQLState.LANG_PROVIDER_HAS_DEPENDENT_OBJECT,
+ dm.getActionString(DependencyManager.DROP_COLUMN),
+ columnInfo[ix].name, "CONSTRAINT",
+ cd.getConstraintName() );
}
if (cd instanceof ReferencedKeyConstraintDescriptor)
{
- // restrict will raise an error in invalidate if really referenced
+ // restrict will raise an error in invalidate if referenced
toBeRemoved[tbr_size++] = cd;
continue;
}
@@ -864,32 +872,42 @@
lcc);
DropConstraintConstantAction.dropConstraintAndIndex(dm, td, dd,
cd, tc, lcc, true);
- activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED,
+
+ activation.addWarning(
+ StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED,
cd.getConstraintName(), td.getName()));
}
for (int i = tbr_size - 1; i >= 0; i--)
{
ConstraintDescriptor cd = toBeRemoved[i];
- DropConstraintConstantAction.dropConstraintAndIndex(dm, td, dd, cd,
- tc, lcc, false);
- activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED,
- cd.getConstraintName(), td.getName()));
+ DropConstraintConstantAction.dropConstraintAndIndex(
+ dm, td, dd, cd, tc, lcc, false);
+
+ activation.addWarning(
+ StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED,
+ cd.getConstraintName(), td.getName()));
if (cascade)
{
ConstraintDescriptorList fkcdl = dd.getForeignKeys(cd.getUUID());
for (int j = 0; j < fkcdl.size(); j++)
{
- ConstraintDescriptor fkcd = (ConstraintDescriptor) fkcdl.elementAt(j);
+ ConstraintDescriptor fkcd =
+ (ConstraintDescriptor) fkcdl.elementAt(j);
+
dm.invalidateFor(fkcd,
DependencyManager.DROP_CONSTRAINT,
lcc);
DropConstraintConstantAction.dropConstraintAndIndex(
dm, fkcd.getTableDescriptor(), dd, fkcd, tc, lcc, true);
- activation.addWarning(StandardException.newWarning(SQLState.LANG_CONSTRAINT_DROPPED,
- fkcd.getConstraintName(), fkcd.getTableDescriptor().getName()));
+
+ activation.addWarning(
+ StandardException.newWarning(
+ SQLState.LANG_CONSTRAINT_DROPPED,
+ fkcd.getConstraintName(),
+ fkcd.getTableDescriptor().getName()));
}
}
@@ -897,23 +915,24 @@
dm.clearDependencies(lcc, cd);
}
- /*
- * The work we've done above, specifically the possible
- * dropping of primary key, foreign key, and unique constraints
- * and their underlying indexes, may have affected the table
- * descriptor. By re-reading the table descriptor here, we
- * ensure that the compressTable code is working with an
- * accurate table descriptor. Without this line, we may get
- * conglomerate-not-found errors and the like due to our
- * stale table descriptor.
- */
+ /*
+ * The work we've done above, specifically the possible
+ * dropping of primary key, foreign key, and unique constraints
+ * and their underlying indexes, may have affected the table
+ * descriptor. By re-reading the table descriptor here, we
+ * ensure that the compressTable code is working with an
+ * accurate table descriptor. Without this line, we may get
+ * conglomerate-not-found errors and the like due to our
+ * stale table descriptor.
+ */
td = dd.getTableDescriptor(tableId);
compressTable(activation);
// drop the column from syscolumns
dd.dropColumnDescriptor(td.getUUID(), columnInfo[ix].name, tc);
- ColumnDescriptor[] cdlArray = new ColumnDescriptor[size - columnDescriptor.getPosition()];
+ ColumnDescriptor[] cdlArray =
+ new ColumnDescriptor[size - columnDescriptor.getPosition()];
for (int i = columnDescriptor.getPosition(), j = 0; i < size; i++, j++)
{
@@ -926,22 +945,28 @@
DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
List deps = dd.getProvidersDescriptorList(td.getObjectID().toString());
- for (Iterator depsIterator = deps.listIterator(); depsIterator.hasNext();)
+ for (Iterator depsIterator = deps.listIterator();
+ depsIterator.hasNext();)
{
- DependencyDescriptor depDesc = (DependencyDescriptor) depsIterator.next();
+ DependencyDescriptor depDesc =
+ (DependencyDescriptor) depsIterator.next();
+
DependableFinder finder = depDesc.getProviderFinder();
if (finder instanceof DDColumnDependableFinder)
{
- DDColumnDependableFinder colFinder = (DDColumnDependableFinder) finder;
- FormatableBitSet oldColumnBitMap = new FormatableBitSet(colFinder.getColumnBitMap());
- FormatableBitSet newColumnBitMap = new FormatableBitSet(oldColumnBitMap);
+ DDColumnDependableFinder colFinder =
+ (DDColumnDependableFinder) finder;
+ FormatableBitSet oldColumnBitMap =
+ new FormatableBitSet(colFinder.getColumnBitMap());
+ FormatableBitSet newColumnBitMap =
+ new FormatableBitSet(oldColumnBitMap);
newColumnBitMap.clear();
int bitLen = oldColumnBitMap.getLength();
for (int i = 0; i < bitLen; i++)
{
- if (i < columnPosition && oldColumnBitMap.isSet(i))
+ if (i < droppedColumnPosition && oldColumnBitMap.isSet(i))
newColumnBitMap.set(i);
- if (i > columnPosition && oldColumnBitMap.isSet(i))
+ if (i > droppedColumnPosition && oldColumnBitMap.isSet(i))
newColumnBitMap.set(i - 1);
}
if (newColumnBitMap.equals(oldColumnBitMap))
@@ -1114,22 +1139,28 @@
// else we are simply changing the default value
}
-
- /* NOTE: compressTable can also be called for
- * ALTER TABLE <t> DROP COLUMN <c>;
- */
+ /**
+ * routine to process compress table or ALTER TABLE <t> DROP COLUMN <c>;
+ * <p>
+ * Uses class level variable "compressTable" to determine if processing
+ * compress table or drop column:
+ * if (!compressTable)
+ * must be drop column.
+ * <p>
+ * Handles rebuilding of base conglomerate and all necessary indexes.
+ **/
private void compressTable(
Activation activation)
throws StandardException
{
- ExecRow emptyHeapRow;
long newHeapConglom;
Properties properties = new Properties();
RowLocation rl;
- this.lcc = activation.getLanguageConnectionContext();
- this.dd = lcc.getDataDictionary();
- this.dm = dd.getDependencyManager();
- this.tc = lcc.getTransactionExecute();
+
+ this.lcc = activation.getLanguageConnectionContext();
+ this.dd = lcc.getDataDictionary();
+ this.dm = dd.getDependencyManager();
+ this.tc = lcc.getTransactionExecute();
this.activation = activation;
if (SanityManager.DEBUG)
@@ -1145,13 +1176,17 @@
SanityManager.ASSERT(constraintActions == null,
"constraintActions expected to be null");
}
- emptyHeapRow = td.getEmptyExecRow(lcc.getContextManager());
- compressHeapCC = tc.openConglomerate(
- td.getHeapConglomerateId(),
- false,
- TransactionController.OPENMODE_FORUPDATE,
- TransactionController.MODE_TABLE,
- TransactionController.ISOLATION_SERIALIZABLE);
+
+ ExecRow emptyHeapRow = td.getEmptyExecRow(lcc.getContextManager());
+ int[] collation_ids = td.getColumnCollationIds();
+
+ compressHeapCC =
+ tc.openConglomerate(
+ td.getHeapConglomerateId(),
+ false,
+ TransactionController.OPENMODE_FORUPDATE,
+ TransactionController.MODE_TABLE,
+ TransactionController.ISOLATION_SERIALIZABLE);
// invalidate any prepared statements that depended on this table
// (including this one), this fixes problem with threads that start up
@@ -1161,7 +1196,6 @@
//
dm.invalidateFor(td, DependencyManager.COMPRESS_TABLE, lcc);
-
rl = compressHeapCC.newRowLocationTemplate();
// Get the properties on the old heap
@@ -1176,22 +1210,35 @@
/* Set up index info */
getAffectedIndexes(activation);
+
// Get an array of RowLocation template
compressRL = new RowLocation[bulkFetchSize];
- indexRows = new ExecIndexRow[numIndexes];
- if (! compressTable)
+ indexRows = new ExecIndexRow[numIndexes];
+ if (!compressTable)
{
+ // must be a drop column, thus the number of columns in the
+ // new template row and the collation template is one less.
ExecRow newRow =
activation.getExecutionFactory().getValueRow(
emptyHeapRow.nColumns() - 1);
+ int[] new_collation_ids = new int[collation_ids.length - 1];
+
for (int i = 0; i < newRow.nColumns(); i++)
{
- newRow.setColumn(i + 1, i < columnPosition - 1 ?
- emptyHeapRow.getColumn(i + 1) :
- emptyHeapRow.getColumn(i + 1 + 1));
+ newRow.setColumn(
+ i + 1,
+ i < droppedColumnPosition - 1 ?
+ emptyHeapRow.getColumn(i + 1) :
+ emptyHeapRow.getColumn(i + 1 + 1));
+
+ new_collation_ids[i] =
+ collation_ids[
+ (i < droppedColumnPosition - 1) ? i : (i + 1)];
}
+
emptyHeapRow = newRow;
+ collation_ids = new_collation_ids;
}
setUpAllSorts(emptyHeapRow, rl);
@@ -1216,13 +1263,7 @@
"heap",
emptyHeapRow.getRowArray(),
null, //column sort order - not required for heap
- (int[]) null, // TODO-COLLATION - implement correct setting of
- // collation ids. This is made more tricky as
- // this routine could be called by either compress
- // table where the heap ids are same as old heap
- // or drop table where the collation ids need
- // to be shuffled about. Setting default
- // collation for now.
+ collation_ids,
properties,
TransactionController.IS_DEFAULT,
this,
@@ -1271,17 +1312,17 @@
* back the same conglomerate number
*/
// Get the ConglomerateDescriptor for the heap
- long oldHeapConglom = td.getHeapConglomerateId();
- ConglomerateDescriptor cd = td.getConglomerateDescriptor(oldHeapConglom);
+ long oldHeapConglom = td.getHeapConglomerateId();
+ ConglomerateDescriptor cd =
+ td.getConglomerateDescriptor(oldHeapConglom);
// Update sys.sysconglomerates with new conglomerate #
dd.updateConglomerateDescriptor(cd, newHeapConglom, tc);
+
// Drop the old conglomerate
tc.dropConglomerate(oldHeapConglom);
cleanUp();
}
-
-
/*
* TRUNCATE TABLE TABLENAME; (quickly removes all the rows from table and
@@ -1508,23 +1549,27 @@
}
}
- private void updateIndex(long newHeapConglom, DataDictionary dd,
- int index, long[] newIndexCongloms)
+ private void updateIndex(
+ long newHeapConglom,
+ DataDictionary dd,
+ int index,
+ long[] newIndexCongloms)
throws StandardException
{
- ConglomerateController indexCC;
Properties properties = new Properties();
- ConglomerateDescriptor cd;
+
// Get the ConglomerateDescriptor for the index
- cd = td.getConglomerateDescriptor(indexConglomerateNumbers[index]);
+ ConglomerateDescriptor cd =
+ td.getConglomerateDescriptor(indexConglomerateNumbers[index]);
// Build the properties list for the new conglomerate
- indexCC = tc.openConglomerate(
- indexConglomerateNumbers[index],
- false,
- TransactionController.OPENMODE_FORUPDATE,
- TransactionController.MODE_TABLE,
- TransactionController.ISOLATION_SERIALIZABLE);
+ ConglomerateController indexCC =
+ tc.openConglomerate(
+ indexConglomerateNumbers[index],
+ false,
+ TransactionController.OPENMODE_FORUPDATE,
+ TransactionController.MODE_TABLE,
+ TransactionController.ISOLATION_SERIALIZABLE);
// Get the properties on the old index
indexCC.getInternalTablePropertySet(properties);
@@ -1536,62 +1581,67 @@
properties.put("baseConglomerateId", Long.toString(newHeapConglom));
if (cd.getIndexDescriptor().isUnique())
{
- properties.put("nUniqueColumns",
- Integer.toString(indexRowLength - 1));
+ properties.put(
+ "nUniqueColumns", Integer.toString(indexRowLength - 1));
}
else
{
- properties.put("nUniqueColumns",
- Integer.toString(indexRowLength));
+ properties.put(
+ "nUniqueColumns", Integer.toString(indexRowLength));
}
- properties.put("rowLocationColumn",
- Integer.toString(indexRowLength - 1));
- properties.put("nKeyFields", Integer.toString(indexRowLength));
+ properties.put(
+ "rowLocationColumn", Integer.toString(indexRowLength - 1));
+ properties.put(
+ "nKeyFields", Integer.toString(indexRowLength));
indexCC.close();
// We can finally drain the sorter and rebuild the index
- // RESOLVE - all indexes are btrees right now
// Populate the index.
- RowLocationRetRowSource cCount = null;
- boolean updateStatistics = false;
- if(!truncateTable)
+ RowLocationRetRowSource cCount = null;
+ boolean statisticsExist = false;
+
+ if (!truncateTable)
{
sorters[index].completedInserts();
sorters[index] = null;
if (td.statisticsExist(cd))
{
- cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
- updateStatistics = true;
+ cCount =
+ new CardinalityCounter(
+ tc.openSortRowSource(sortIds[index]));
+
+ statisticsExist = true;
}
else
- cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
+ {
+ cCount =
+ new CardinalityCounter(
+ tc.openSortRowSource(sortIds[index]));
+ }
- newIndexCongloms[index] = tc.createAndLoadConglomerate(
- "BTREE",
- indexRows[index].getRowArray(),
- ordering[index],
- (int[]) null, // TODO-COLLATION, implement
- // collation support for alter
- // table. Currently only
- // supports default collation
- // columns.
- properties,
- TransactionController.IS_DEFAULT,
- cCount,
- (long[]) null);
+ newIndexCongloms[index] =
+ tc.createAndLoadConglomerate(
+ "BTREE",
+ indexRows[index].getRowArray(),
+ ordering[index],
+ collation[index],
+ properties,
+ TransactionController.IS_DEFAULT,
+ cCount,
+ (long[]) null);
//For an index, if the statistics already exist, then drop them.
//The statistics might not exist for an index if the index was
//created when the table was empty.
- //At ALTER TABLE COMPRESS time, for both kinds of indexes
- //(ie one with preexisting statistics and with no statistics),
- //create statistics for them if the table is not empty.
- //DERBY-737 "SYSCS_UTIL.SYSCS_COMPRESS_TABLE should create
- //statistics if they do not exist"
- if (updateStatistics)
+ //
+ //For all alter table actions, including ALTER TABLE COMPRESS,
+ //for both kinds of indexes (ie. one with preexisting statistics
+ //and with no statistics), create statistics for them if the table
+ //is not empty.
+ if (statisticsExist)
dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc);
long numRows;
@@ -1601,12 +1651,21 @@
for (int i = 0; i < c.length; i++)
{
StatisticsDescriptor statDesc =
- new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(),
- cd.getUUID(), td.getUUID(), "I", new StatisticsImpl(numRows, c[i]),
- i + 1);
- dd.addDescriptor(statDesc, null, // no parent descriptor
+ new StatisticsDescriptor(
+ dd,
+ dd.getUUIDFactory().createUUID(),
+ cd.getUUID(),
+ td.getUUID(),
+ "I",
+ new StatisticsImpl(numRows, c[i]),
+ i + 1);
+
+ dd.addDescriptor(
+ statDesc,
+ null, // no parent descriptor
DataDictionary.SYSSTATISTICS_CATALOG_NUM,
- true, tc); // no error on duplicate.
+ true, // no error on duplicate.
+ tc);
}
}
}
@@ -1617,9 +1676,7 @@
"BTREE",
indexRows[index].getRowArray(),
ordering[index],
- (int[]) null, // TODO-COLLATION, implement alter table
- // collation passing,
- // currently only supports default collation.
+ collation[index],
properties,
TransactionController.IS_DEFAULT);
@@ -1631,16 +1688,15 @@
}
/* Update the DataDictionary
- * RESOLVE - this will change in 1.4 because we will get
- * back the same conglomerate number
*
* Update sys.sysconglomerates with new conglomerate #, we need to
* update all (if any) duplicate index entries sharing this same
* conglomerate.
*/
dd.updateConglomerateDescriptor(
- td.getConglomerateDescriptors(indexConglomerateNumbers[index]),
- newIndexCongloms[index], tc);
+ td.getConglomerateDescriptors(indexConglomerateNumbers[index]),
+ newIndexCongloms[index],
+ tc);
// Drop the old conglomerate
tc.dropConglomerate(indexConglomerateNumbers[index]);
@@ -1673,7 +1729,7 @@
int[] baseColumnPositions = compressIRGs[i].baseColumnPositions();
int j;
for (j = 0; j < baseColumnPositions.length; j++)
- if (baseColumnPositions[j] == columnPosition) break;
+ if (baseColumnPositions[j] == droppedColumnPosition) break;
if (j == baseColumnPositions.length) // not related
continue;
@@ -1721,9 +1777,9 @@
int size = baseColumnPositions.length;
for (int k = 0; k < size; k++)
{
- if (baseColumnPositions[k] > columnPosition)
+ if (baseColumnPositions[k] > droppedColumnPosition)
baseColumnPositions[k]--;
- else if (baseColumnPositions[k] == columnPosition)
+ else if (baseColumnPositions[k] == droppedColumnPosition)
{
baseColumnPositions[k] = 0; // mark it
reMakeArrays = true;
@@ -1789,10 +1845,12 @@
RowLocation rl)
throws StandardException
{
- ordering = new ColumnOrdering[numIndexes][];
+ ordering = new ColumnOrdering[numIndexes][];
+ collation = new int[numIndexes][];
+ needToDropSort = new boolean[numIndexes];
+ sortIds = new long[numIndexes];
- needToDropSort = new boolean[numIndexes];
- sortIds = new long[numIndexes];
+ int[] base_table_collation_ids = td.getColumnCollationIds();
/* For each index, build a single index row and a sorter. */
for (int index = 0; index < numIndexes; index++)
@@ -1800,52 +1858,64 @@
// create a single index row template for each index
indexRows[index] = compressIRGs[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.)
- compressIRGs[index].getIndexRow(sourceRow,
- rl,
- indexRows[index],
- (FormatableBitSet) null);
+ // (This call is only necessary here because we need to pass a
+ // template to the sorter.)
+ compressIRGs[index].getIndexRow(
+ sourceRow, rl, indexRows[index], (FormatableBitSet) null);
+
+ // Setup collation id array to be passed in on call to create index.
+ collation[index] =
+ compressIRGs[index].getColumnCollationIds(
+ td.getColumnDescriptorList());
/* For non-unique indexes, we order by all columns + the RID.
* For unique indexes, we just order by the columns.
* No need to try to enforce uniqueness here as
* index should be valid.
*/
- int[] baseColumnPositions = compressIRGs[index].baseColumnPositions();
- boolean[] isAscending = compressIRGs[index].isAscending();
- int numColumnOrderings;
- SortObserver sortObserver = null;
+ int[] baseColumnPositions =
+ compressIRGs[index].baseColumnPositions();
+ boolean[] isAscending =
+ compressIRGs[index].isAscending();
+ int numColumnOrderings =
+ baseColumnPositions.length + 1;
+
/* We can only reuse the wrappers when doing an
* external sort if there is only 1 index. Otherwise,
* we could get in a situation where 1 sort reuses a
* wrapper that is still in use in another sort.
*/
boolean reuseWrappers = (numIndexes == 1);
- numColumnOrderings = baseColumnPositions.length + 1;
- sortObserver = new BasicSortObserver(false, false,
- indexRows[index],
- reuseWrappers);
+
+ SortObserver sortObserver =
+ new BasicSortObserver(
+ false, false, indexRows[index], reuseWrappers);
+
ordering[index] = new ColumnOrdering[numColumnOrderings];
for (int ii =0; ii < numColumnOrderings - 1; ii++)
{
ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
}
- ordering[index][numColumnOrderings - 1] = new IndexColumnOrder(numColumnOrderings - 1);
+ ordering[index][numColumnOrderings - 1] =
+ new IndexColumnOrder(numColumnOrderings - 1);
// create the sorters
- sortIds[index] = tc.createSort(
- (Properties)null,
- indexRows[index].getRowArrayClone(),
- ordering[index],
- sortObserver,
- false, // not in order
- estimatedRowCount, // est rows
- -1 // est row size, -1 means no idea
- );
+ sortIds[index] =
+ tc.createSort(
+ (Properties)null,
+ indexRows[index].getRowArrayClone(),
+ ordering[index],
+ sortObserver,
+ false, // not in order
+ estimatedRowCount, // est rows
+ -1 // est row size, -1 means no idea
+ );
}
sorters = new SortController[numIndexes];
+
// Open the sorts
for (int index = 0; index < numIndexes; index++)
{
@@ -1897,16 +1967,25 @@
if (validRow[currentCompressRow])
{
if (compressTable)
+ {
currentRow = baseRow[currentCompressRow];
+ }
else
{
if (currentRow == null)
- currentRow = activation.getExecutionFactory().getValueRow(baseRowArray[currentCompressRow].length - 1);
+ {
+ currentRow =
+ activation.getExecutionFactory().getValueRow(
+ baseRowArray[currentCompressRow].length - 1);
+ }
+
for (int i = 0; i < currentRow.nColumns(); i++)
{
- currentRow.setColumn(i + 1, i < columnPosition - 1 ?
- baseRow[currentCompressRow].getColumn(i+1) :
- baseRow[currentCompressRow].getColumn(i+1+1));
+ currentRow.setColumn(
+ i + 1,
+ i < droppedColumnPosition - 1 ?
+ baseRow[currentCompressRow].getColumn(i+1) :
+ baseRow[currentCompressRow].getColumn(i+1+1));
}
}
currentCompressRow++;
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java?view=diff&rev=535770&r1=535769&r2=535770
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java Mon May 7 00:47:34 2007
@@ -599,7 +599,8 @@
indexType,
indexTemplateRow.getRowArray(), // index row template
order, //colums sort order
- null, // TODO-COLLATION, implement non-default collation
+ indexRowGenerator.getColumnCollationIds(
+ td.getColumnDescriptorList()),
indexProperties,
TransactionController.IS_DEFAULT, // not temporary
rowSource,
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?view=diff&rev=535770&r1=535769&r2=535770
==============================================================================
--- 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 Mon May 7 00:47:34 2007
@@ -133,6 +133,7 @@
rowSources;
private ScanController bulkHeapSC;
private ColumnOrdering[][] ordering;
+ private int[][] collation;
private SortController[] sorters;
private TemporaryRowHolderImpl rowHolder;
private RowLocation rl;
@@ -1635,15 +1636,18 @@
int numIndexes = constants.irgs.length;
int numColumns = td.getNumberOfColumns();
- ordering = new ColumnOrdering[numIndexes][];
- needToDropSort = new boolean[numIndexes];
- sortIds = new long[numIndexes];
- rowSources = new RowLocationRetRowSource[numIndexes];
+ ordering = new ColumnOrdering[numIndexes][];
+ collation = new int[numIndexes][];
+ needToDropSort = new boolean[numIndexes];
+ sortIds = new long[numIndexes];
+ rowSources = new RowLocationRetRowSource[numIndexes];
// indexedCols is 1-based
- indexedCols = new FormatableBitSet(numColumns + 1);
+ indexedCols = new FormatableBitSet(numColumns + 1);
- /* For each index, build a single index row and a sorter. */
+ /* For each index, build a single index row, collation templage,
+ * and a sorter.
+ */
for (int index = 0; index < numIndexes; index++)
{
// Update the bit map of indexed columns
@@ -1658,7 +1662,8 @@
indexRows[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.)
+ // (This call is only necessary here because we need to
+ // pass a template to the sorter.)
constants.irgs[index].getIndexRow(sourceRow,
rl,
indexRows[index],
@@ -1669,13 +1674,18 @@
* We create a unique index observer for unique indexes
* so that we can catch duplicate key
*/
- ConglomerateDescriptor cd;
+
// Get the ConglomerateDescriptor for the index
- cd = td.getConglomerateDescriptor(constants.indexCIDS[index]);
- int[] baseColumnPositions = constants.irgs[index].baseColumnPositions();
- boolean[] isAscending = constants.irgs[index].isAscending();
+ ConglomerateDescriptor cd =
+ td.getConglomerateDescriptor(constants.indexCIDS[index]);
+
+ int[] baseColumnPositions =
+ constants.irgs[index].baseColumnPositions();
+ boolean[] isAscending = constants.irgs[index].isAscending();
+
int numColumnOrderings;
SortObserver sortObserver = null;
+
/* We can only reuse the wrappers when doing an
* external sort if there is only 1 index. Otherwise,
* we could get in a situation where 1 sort reuses a
@@ -1688,24 +1698,28 @@
String[] columnNames = getColumnNames(baseColumnPositions);
String indexOrConstraintName = cd.getConglomerateName();
- if (cd.isConstraint()) // so, the index is backing up a constraint
+ if (cd.isConstraint())
{
- ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td,
- cd.getUUID());
+ // so, the index is backing up a constraint
+
+ ConstraintDescriptor conDesc =
+ dd.getConstraintDescriptor(td, cd.getUUID());
+
indexOrConstraintName = conDesc.getConstraintName();
}
- sortObserver = new UniqueIndexSortObserver(
- false, // don't clone rows
- cd.isConstraint(),
- indexOrConstraintName,
- indexRows[index],
- reuseWrappers,
- td.getName());
+ sortObserver =
+ new UniqueIndexSortObserver(
+ false, // don't clone rows
+ cd.isConstraint(),
+ indexOrConstraintName,
+ indexRows[index],
+ reuseWrappers,
+ td.getName());
}
else
{
numColumnOrderings = baseColumnPositions.length + 1;
- sortObserver = new BasicSortObserver(false, false,
+ sortObserver = new BasicSortObserver(false, false,
indexRows[index],
reuseWrappers);
}
@@ -1715,18 +1729,29 @@
ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
}
if (numColumnOrderings > isAscending.length)
- ordering[index][isAscending.length] = new IndexColumnOrder(isAscending.length);
+ {
+ ordering[index][isAscending.length] =
+ new IndexColumnOrder(isAscending.length);
+ }
+
+ // set collation templates for later index creation
+ // call (createAndLoadConglomerate())
+ collation[index] =
+ constants.irgs[index].getColumnCollationIds(
+ td.getColumnDescriptorList());
// create the sorters
- sortIds[index] = tc.createSort(
- (Properties)null,
- indexRows[index].getRowArrayClone(),
- ordering[index],
- sortObserver,
- false, // not in order
- (int) sourceResultSet.getEstimatedRowCount(), // est rows
- -1 // est row size, -1 means no idea
- );
+ sortIds[index] =
+ tc.createSort(
+ (Properties)null,
+ indexRows[index].getRowArrayClone(),
+ ordering[index],
+ sortObserver,
+ false, // not in order
+ (int) sourceResultSet.getEstimatedRowCount(), // est rows
+ -1 // est row size, -1 means no idea
+ );
+
needToDropSort[index] = true;
}
@@ -1735,7 +1760,7 @@
// Open the sorts
for (int index = 0; index < numIndexes; index++)
{
- sorters[index] = tc.openSort(sortIds[index]);
+ sorters[index] = tc.openSort(sortIds[index]);
needToDropSort[index] = true;
}
}
@@ -1821,13 +1846,15 @@
// Populate the index.
sorters[index].completedInserts();
sorters[index] = null;
- rowSources[index] = new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
+ rowSources[index] =
+ new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
+
newIndexCongloms[index] =
tc.createAndLoadConglomerate(
"BTREE",
indexRows[index].getRowArray(),
ordering[index],
- (int[]) null, // TODO-COLLATION, set non default collation if necessary
+ collation[index],
properties,
TransactionController.IS_DEFAULT,
rowSources[index],
@@ -2126,7 +2153,8 @@
}
// We can finally create the partial base row
- baseRows = activation.getExecutionFactory().getValueRow(numReferencedColumns);
+ baseRows =
+ activation.getExecutionFactory().getValueRow(numReferencedColumns);
// Fill in each base row with nulls of the correct data type
int colNumber = 0;
@@ -2154,7 +2182,8 @@
indexRows[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.)
+ // (This call is only necessary here because we need to pass a
+ // template to the sorter.)
constants.irgs[index].getIndexRow(baseRows,
rl,
indexRows[index],
@@ -2178,24 +2207,26 @@
String[] columnNames = getColumnNames(baseColumnPositions);
String indexOrConstraintName = cd.getConglomerateName();
- if (cd.isConstraint()) // so, the index is backing up a constraint
+ if (cd.isConstraint())
{
- ConstraintDescriptor conDesc = dd.getConstraintDescriptor(td,
- cd.getUUID());
+ // so, the index is backing up a constraint
+ ConstraintDescriptor conDesc =
+ dd.getConstraintDescriptor(td, cd.getUUID());
indexOrConstraintName = conDesc.getConstraintName();
}
- sortObserver = new UniqueIndexSortObserver(
- false, // don't clone rows
- cd.isConstraint(),
- indexOrConstraintName,
- indexRows[index],
- true,
- td.getName());
+ sortObserver =
+ new UniqueIndexSortObserver(
+ false, // don't clone rows
+ cd.isConstraint(),
+ indexOrConstraintName,
+ indexRows[index],
+ true,
+ td.getName());
}
else
{
numColumnOrderings = baseColumnPositions.length + 1;
- sortObserver = new BasicSortObserver(false, false,
+ sortObserver = new BasicSortObserver(false, false,
indexRows[index],
true);
}
@@ -2205,18 +2236,23 @@
ordering[index][ii] = new IndexColumnOrder(ii, isAscending[ii]);
}
if (numColumnOrderings > isAscending.length)
- ordering[index][isAscending.length] = new IndexColumnOrder(isAscending.length);
+ {
+ ordering[index][isAscending.length] =
+ new IndexColumnOrder(isAscending.length);
+ }
// create the sorters
- sortIds[index] = tc.createSort(
- (Properties)null,
- indexRows[index].getRowArrayClone(),
- ordering[index],
- sortObserver,
- false, // not in order
- rowCount, // est rows
- -1 // est row size, -1 means no idea
- );
+ sortIds[index] =
+ tc.createSort(
+ (Properties)null,
+ indexRows[index].getRowArrayClone(),
+ ordering[index],
+ sortObserver,
+ false, // not in order
+ rowCount, // est rows
+ -1 // est row size, -1 means no idea
+ );
+
needToDropSort[index] = true;
}
@@ -2279,14 +2315,13 @@
indexCC.close();
// We can finally drain the sorter and rebuild the index
- // RESOLVE - all indexes are btrees right now
// Populate the index.
newIndexCongloms[index] =
tc.createAndLoadConglomerate(
"BTREE",
indexRows[index].getRowArray(),
null, //default column sort order
- (int[]) null, // TODO-COLLATION - set collation based on collation of original index.
+ collation[index],
properties,
TransactionController.IS_DEFAULT,
rowSources[index],
@@ -2299,8 +2334,8 @@
* for those indexes need to be updated with the new number.
*/
dd.updateConglomerateDescriptor(
- td.getConglomerateDescriptors(constants.indexCIDS[index]),
- newIndexCongloms[index], tc);
+ td.getConglomerateDescriptors(constants.indexCIDS[index]),
+ newIndexCongloms[index], tc);
// Drop the old conglomerate
tc.dropConglomerate(constants.indexCIDS[index]);
@@ -2318,33 +2353,34 @@
{
if (tableScan == null)
{
- tableScan = new BulkTableScanResultSet(
- conglomId,
- tc.getStaticCompiledConglomInfo(conglomId),
- activation,
- new MyRowAllocator(fullTemplate), // result row allocator
- 0, // result set number
- (GeneratedMethod)null, // start key getter
- 0, // start search operator
- (GeneratedMethod)null, // stop key getter
- 0, // start search operator
- false,
- (Qualifier[][])null, // qualifiers
- "tableName",
- (String)null,
- (String)null, // index name
- false, // is constraint
- false, // for update
- -1, // saved object for referenced bitImpl
- -1,
- tc.MODE_TABLE,
- true, // table locked
- tc.ISOLATION_READ_COMMITTED,
- LanguageProperties.BULK_FETCH_DEFAULT_INT, // rows per read
- false, // not a 1 row per scan
- 0d, // estimated rows
- 0d // estimated cost
- );
+ tableScan =
+ new BulkTableScanResultSet(
+ conglomId,
+ tc.getStaticCompiledConglomInfo(conglomId),
+ activation,
+ new MyRowAllocator(fullTemplate), // result row allocator
+ 0, // result set number
+ (GeneratedMethod)null, // start key getter
+ 0, // start search operator
+ (GeneratedMethod)null, // stop key getter
+ 0, // start search operator
+ false,
+ (Qualifier[][])null, // qualifiers
+ "tableName",
+ (String)null,
+ (String)null, // index name
+ false, // is constraint
+ false, // for update
+ -1, // saved object for referenced bitImpl
+ -1,
+ tc.MODE_TABLE,
+ true, // table locked
+ tc.ISOLATION_READ_COMMITTED,
+ LanguageProperties.BULK_FETCH_DEFAULT_INT, // rows per read
+ false, // not a 1 row per scan
+ 0d, // estimated rows
+ 0d // estimated cost
+ );
tableScan.openCore();
}
else