use of org.apache.derby.iapi.types.DataValueFactory in project derby by apache.
the class ConsistencyChecker method checkTable.
/**
* Check the named table, ensuring that all of its indexes are consistent
* with the base table.
* Use this
* method only within an SQL-J statement; do not call it directly.
* <P>When tables are consistent, the method returns true. Otherwise, the method throws an exception.
* <p>To check the consistency of a single table:
* <p><code>
* VALUES ConsistencyChecker::checkTable(<i>SchemaName</i>, <i>TableName</i>)</code></p>
* <P>For example, to check the consistency of the table <i>APP.Flights</i>:
* <p><code>
* VALUES ConsistencyChecker::checkTable('APP', 'FLIGHTS')</code></p>
* <p>To check the consistency of all of the tables in the 'APP' schema,
* stopping at the first failure:
*
* <P><code>SELECT tablename, ConsistencyChecker::checkTable(<br>
* 'APP', tablename)<br>
* FROM sys.sysschemas s, sys.systables t
* WHERE s.schemaname = 'APP' AND s.schemaid = t.schemaid</code>
*
* <p> To check the consistency of an entire database, stopping at the first failure:
*
* <p><code>SELECT schemaname, tablename,<br>
* ConsistencyChecker::checkTable(schemaname, tablename)<br>
* FROM sys.sysschemas s, sys.systables t<br>
* WHERE s.schemaid = t.schemaid</code>
*
* @param schemaName The schema name of the table.
* @param tableName The name of the table
*
* @return true, if the table is consistent, exception thrown if inconsistent
*
* @exception SQLException Thrown if some inconsistency
* is found, or if some unexpected
* exception is thrown..
*/
public static boolean checkTable(String schemaName, String tableName) throws SQLException {
DataDictionary dd;
TableDescriptor td;
long baseRowCount = -1;
TransactionController tc;
ConglomerateDescriptor heapCD;
ConglomerateDescriptor indexCD;
ExecRow baseRow;
ExecRow indexRow;
RowLocation rl = null;
RowLocation scanRL = null;
ScanController scan = null;
int[] baseColumnPositions;
int baseColumns = 0;
DataValueFactory dvf;
long indexRows;
ConglomerateController baseCC = null;
ConglomerateController indexCC = null;
SchemaDescriptor sd;
ConstraintDescriptor constraintDesc;
LanguageConnectionContext lcc = ConnectionUtil.getCurrentLCC();
tc = lcc.getTransactionExecute();
try {
// make sure that application code doesn't bypass security checks
// by calling this public entry point
SecurityUtil.authorize(Securable.CHECK_TABLE);
dd = lcc.getDataDictionary();
dvf = lcc.getDataValueFactory();
ExecutionFactory ef = lcc.getLanguageConnectionFactory().getExecutionFactory();
sd = dd.getSchemaDescriptor(schemaName, tc, true);
td = dd.getTableDescriptor(tableName, sd, tc);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, schemaName + "." + tableName);
}
/* Skip views */
if (td.getTableType() == TableDescriptor.VIEW_TYPE) {
return true;
}
/* Open the heap for reading */
baseCC = tc.openConglomerate(td.getHeapConglomerateId(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
/* Check the consistency of the heap */
baseCC.checkConsistency();
heapCD = td.getConglomerateDescriptor(td.getHeapConglomerateId());
/* Get a row template for the base table */
baseRow = ef.getValueRow(td.getNumberOfColumns());
/* Fill the row with nulls of the correct type */
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++) {
ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
baseRow.setColumn(cd.getPosition(), cd.getType().getNull());
}
/* Look at all the indexes on the table */
ConglomerateDescriptor[] cds = td.getConglomerateDescriptors();
for (int index = 0; index < cds.length; index++) {
indexCD = cds[index];
/* Skip the heap */
if (!indexCD.isIndex())
continue;
/* Check the internal consistency of the index */
indexCC = tc.openConglomerate(indexCD.getConglomerateNumber(), false, 0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
indexCC.checkConsistency();
indexCC.close();
indexCC = null;
if (indexCD.isConstraint()) {
constraintDesc = dd.getConstraintDescriptor(td, indexCD.getUUID());
if (constraintDesc == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "CONSTRAINT for INDEX", indexCD.getConglomerateName());
}
}
/*
** Set the base row count when we get to the first index.
** We do this here, rather than outside the index loop, so
** we won't do the work of counting the rows in the base table
** if there are no indexes to check.
*/
if (baseRowCount < 0) {
scan = tc.openScan(heapCD.getConglomerateNumber(), // hold
false, // not forUpdate
0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, RowUtil.EMPTY_ROW_BITSET, // startKeyValue
null, // not used with null start posn.
0, // qualifier
null, // stopKeyValue
null, // not used with null stop posn.
0);
/* Also, get the row location template for index rows */
rl = scan.newRowLocationTemplate();
scanRL = scan.newRowLocationTemplate();
for (baseRowCount = 0; scan.next(); baseRowCount++) ;
/* Empty statement */
scan.close();
scan = null;
}
baseColumnPositions = indexCD.getIndexDescriptor().baseColumnPositions();
baseColumns = baseColumnPositions.length;
FormatableBitSet indexColsBitSet = new FormatableBitSet();
for (int i = 0; i < baseColumns; i++) {
indexColsBitSet.grow(baseColumnPositions[i]);
indexColsBitSet.set(baseColumnPositions[i] - 1);
}
/* Get one row template for the index scan, and one for the fetch */
indexRow = ef.getValueRow(baseColumns + 1);
/* Fill the row with nulls of the correct type */
for (int column = 0; column < baseColumns; column++) {
/* Column positions in the data dictionary are one-based */
ColumnDescriptor cd = td.getColumnDescriptor(baseColumnPositions[column]);
indexRow.setColumn(column + 1, cd.getType().getNull());
}
/* Set the row location in the last column of the index row */
indexRow.setColumn(baseColumns + 1, rl);
/* Do a full scan of the index */
scan = tc.openScan(indexCD.getConglomerateNumber(), // hold
false, // not forUpdate
0, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE, (FormatableBitSet) null, // startKeyValue
null, // not used with null start posn.
0, // qualifier
null, // stopKeyValue
null, // not used with null stop posn.
0);
DataValueDescriptor[] baseRowIndexOrder = new DataValueDescriptor[baseColumns];
DataValueDescriptor[] baseObjectArray = baseRow.getRowArray();
for (int i = 0; i < baseColumns; i++) {
baseRowIndexOrder[i] = baseObjectArray[baseColumnPositions[i] - 1];
}
/* Get the index rows and count them */
for (indexRows = 0; scan.fetchNext(indexRow.getRowArray()); indexRows++) {
/*
** Get the base row using the RowLocation in the index row,
** which is in the last column.
*/
RowLocation baseRL = (RowLocation) indexRow.getColumn(baseColumns + 1);
boolean base_row_exists = baseCC.fetch(baseRL, baseObjectArray, indexColsBitSet);
/* Throw exception if fetch() returns false */
if (!base_row_exists) {
String indexName = indexCD.getConglomerateName();
throw StandardException.newException(SQLState.LANG_INCONSISTENT_ROW_LOCATION, (schemaName + "." + tableName), indexName, baseRL.toString(), indexRow.toString());
}
/* Compare all the column values */
for (int column = 0; column < baseColumns; column++) {
DataValueDescriptor indexColumn = indexRow.getColumn(column + 1);
DataValueDescriptor baseColumn = baseRowIndexOrder[column];
/*
** With this form of compare(), null is considered equal
** to null.
*/
if (indexColumn.compare(baseColumn) != 0) {
ColumnDescriptor cd = td.getColumnDescriptor(baseColumnPositions[column]);
throw StandardException.newException(SQLState.LANG_INDEX_COLUMN_NOT_EQUAL, indexCD.getConglomerateName(), td.getSchemaName(), td.getName(), baseRL.toString(), cd.getColumnName(), indexColumn.toString(), baseColumn.toString(), indexRow.toString());
}
}
}
/* Clean up after the index scan */
scan.close();
scan = null;
/*
** The index is supposed to have the same number of rows as the
** base conglomerate.
*/
if (indexRows != baseRowCount) {
throw StandardException.newException(SQLState.LANG_INDEX_ROW_COUNT_MISMATCH, indexCD.getConglomerateName(), td.getSchemaName(), td.getName(), Long.toString(indexRows), Long.toString(baseRowCount));
}
}
/* check that all constraints have backing index */
ConstraintDescriptorList constraintDescList = dd.getConstraintDescriptors(td);
for (int index = 0; index < constraintDescList.size(); index++) {
constraintDesc = constraintDescList.elementAt(index);
if (constraintDesc.hasBackingIndex()) {
ConglomerateDescriptor conglomDesc;
conglomDesc = td.getConglomerateDescriptor(constraintDesc.getConglomerateId());
if (conglomDesc == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "INDEX for CONSTRAINT", constraintDesc.getConstraintName());
}
}
}
} catch (StandardException se) {
throw PublicAPI.wrapStandardException(se);
} finally {
try {
/* Clean up before we leave */
if (baseCC != null) {
baseCC.close();
baseCC = null;
}
if (indexCC != null) {
indexCC.close();
indexCC = null;
}
if (scan != null) {
scan.close();
scan = null;
}
} catch (StandardException se) {
throw PublicAPI.wrapStandardException(se);
}
}
return true;
}
use of org.apache.derby.iapi.types.DataValueFactory in project derby by apache.
the class UnaryDateTimestampOperatorNode method bindExpression.
/**
* Called by UnaryOperatorNode.bindExpression.
*
* If the operand is a constant then evaluate the function at compile time. Otherwise,
* if the operand input type is the same as the output type then discard this node altogether.
* If the function is "date" and the input is a timestamp then change this node to a cast.
*
* @param fromList The FROM list for the query this
* expression is in, for binding columns.
* @param subqueryList The subquery list being built as we find SubqueryNodes
* @param aggregates The aggregate list being built as we find AggregateNodes
*
* @return The new top of the expression tree.
*
* @exception StandardException Thrown on error
*/
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
// Is this function the identity operator?
boolean isIdentity = false;
boolean operandIsNumber = false;
bindOperand(fromList, subqueryList, aggregates);
DataTypeDescriptor operandType = operand.getTypeServices();
switch(operandType.getJDBCTypeId()) {
case Types.BIGINT:
case Types.INTEGER:
case Types.SMALLINT:
case Types.TINYINT:
case Types.DECIMAL:
case Types.NUMERIC:
case Types.DOUBLE:
case Types.FLOAT:
if (TIMESTAMP_METHOD_NAME.equals(methodName))
invalidOperandType();
operandIsNumber = true;
break;
case Types.CHAR:
case Types.VARCHAR:
break;
case Types.DATE:
if (TIMESTAMP_METHOD_NAME.equals(methodName))
invalidOperandType();
isIdentity = true;
break;
case Types.NULL:
break;
case Types.TIMESTAMP:
if (TIMESTAMP_METHOD_NAME.equals(methodName))
isIdentity = true;
break;
default:
invalidOperandType();
}
if (operand instanceof ConstantNode) {
DataValueFactory dvf = getLanguageConnectionContext().getDataValueFactory();
DataValueDescriptor sourceValue = ((ConstantNode) operand).getValue();
DataValueDescriptor destValue;
if (sourceValue.isNull()) {
destValue = (TIMESTAMP_METHOD_NAME.equals(methodName)) ? dvf.getNullTimestamp((DateTimeDataValue) null) : dvf.getNullDate((DateTimeDataValue) null);
} else {
destValue = (TIMESTAMP_METHOD_NAME.equals(methodName)) ? dvf.getTimestamp(sourceValue) : dvf.getDate(sourceValue);
}
return new UserTypeConstantNode(destValue, getContextManager());
}
if (isIdentity)
return operand;
return this;
}
use of org.apache.derby.iapi.types.DataValueFactory in project derby by apache.
the class BasicDatabase method boot.
public void boot(boolean create, Properties startParams) throws StandardException {
ModuleFactory monitor = getMonitor();
if (create) {
if (startParams.getProperty(Property.CREATE_WITH_NO_LOG) == null)
startParams.put(Property.CREATE_WITH_NO_LOG, "true");
String localeID = startParams.getProperty(org.apache.derby.shared.common.reference.Attribute.TERRITORY);
if (localeID == null) {
localeID = Locale.getDefault().toString();
}
databaseLocale = monitor.setLocale(startParams, localeID);
} else {
databaseLocale = monitor.getLocale(this);
}
setLocale(databaseLocale);
// boot the validation needed to do property validation, now property
// validation is separated from AccessFactory, therefore from store
bootValidation(create, startParams);
// boot the type factory before store to ensure any dynamically
// registered types (DECIMAL) are there before logical undo recovery
// might need them.
DataValueFactory dvf = (DataValueFactory) bootServiceModule(create, this, org.apache.derby.shared.common.reference.ClassName.DataValueFactory, startParams);
bootStore(create, startParams);
// create a database ID if one doesn't already exist
myUUID = makeDatabaseID(create, startParams);
// Add the database properties read from disk (not stored
// in service.properties) into the set seen by booting modules.
Properties allParams = new DoubleProperties(getAllDatabaseProperties(), startParams);
if (pf != null)
pf.addPropertySetNotification(this);
// Boot the ClassFactory, will be per-database or per-system.
// reget the tc in case someone inadverdently destroyed it
bootClassFactory(create, allParams);
dd = (DataDictionary) bootServiceModule(create, this, DataDictionary.MODULE, allParams);
lcf = (LanguageConnectionFactory) bootServiceModule(create, this, LanguageConnectionFactory.MODULE, allParams);
lf = (LanguageFactory) bootServiceModule(create, this, LanguageFactory.MODULE, allParams);
bootResourceAdapter(create, allParams);
// may also want to set up a check that we are a singleton,
// or that there isn't already a database object in the system
// for the same database?
//
// We boot the authentication service. There should at least be one
// per database (even if authentication is turned off) .
//
authenticationService = bootAuthenticationService(create, allParams);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(authenticationService != null, "Failed to set the Authentication service for the database");
}
// on logging
if (create && lastToBoot && (startParams.getProperty(Property.CREATE_WITH_NO_LOG) != null)) {
createFinished();
}
active = true;
// Create an index statistics update daemon.
if (dd.doCreateIndexStatsRefresher()) {
dd.createIndexStatsRefresher(this, allParams.getProperty(Property.PROPERTY_RUNTIME_PREFIX + "serviceDirectory"));
}
}
use of org.apache.derby.iapi.types.DataValueFactory in project derby by apache.
the class ResultColumn method columnTypeAndLengthMatch.
boolean columnTypeAndLengthMatch(ResultColumn otherColumn) throws StandardException {
ValueNode otherExpression = otherColumn.getExpression();
DataTypeDescriptor resultColumnType = getTypeServices();
DataTypeDescriptor otherResultColumnType = otherColumn.getTypeServices();
if (SanityManager.DEBUG) {
SanityManager.ASSERT(resultColumnType != null, "Type is null for column " + this);
SanityManager.ASSERT(otherResultColumnType != null, "Type is null for column " + otherColumn);
}
/*
** We can never make any assumptions about
** parameters. So don't even bother in this
** case.
*/
if ((otherExpression != null) && (otherExpression.requiresTypeFromContext()) || (_expression.requiresTypeFromContext())) {
return false;
}
// method in org.apache.derby.iapi.types.XML for more.
if (resultColumnType.getTypeId().isXMLTypeId())
return false;
/* Are they the same type? */
if (!resultColumnType.getTypeId().equals(otherResultColumnType.getTypeId())) {
/* If the source is a constant of a different type then
* we try to convert that constant to a constant of our
* type. (The initial implementation only does the conversion
* to string types because the most common problem is a char
* constant with a varchar column.)
* NOTE: We do not attempt any conversion here if the source
* is a string type and the target is not or vice versa in
* order to avoid problems with implicit varchar conversions.
* Anyway, we will check if the "converted" constant has the
* same type as the original constant. If not, then the conversion
* happened. In that case, we will reuse the ConstantNode, for simplicity,
* and reset the type to match the desired type.
*/
if (otherExpression instanceof ConstantNode) {
ConstantNode constant = (ConstantNode) otherColumn.getExpression();
DataValueDescriptor oldValue = constant.getValue();
DataValueDescriptor newValue = convertConstant(resultColumnType.getTypeId(), resultColumnType.getMaximumWidth(), oldValue);
if ((oldValue != newValue) && (oldValue instanceof StringDataValue == newValue instanceof StringDataValue)) {
constant.setValue(newValue);
constant.setType(getTypeServices());
otherColumn.bindResultColumnToExpression();
otherResultColumnType = otherColumn.getType();
}
// depending on the collation type.
if (newValue instanceof StringDataValue) {
constant.setCollationInfo(resultColumnType);
DataValueFactory dvf = getDataValueFactory();
newValue = ((StringDataValue) newValue).getValue(dvf.getCharacterCollator(constant.getTypeServices().getCollationType()));
constant.setValue(newValue);
}
}
if (!resultColumnType.getTypeId().equals(otherResultColumnType.getTypeId())) {
return false;
}
}
/* Are they the same precision? */
if (resultColumnType.getPrecision() != otherResultColumnType.getPrecision()) {
return false;
}
/* Are they the same scale? */
if (resultColumnType.getScale() != otherResultColumnType.getScale()) {
return false;
}
/* Are they the same width? */
if (resultColumnType.getMaximumWidth() != otherResultColumnType.getMaximumWidth()) {
return false;
}
/* Is the source nullable and the target non-nullable?
* The source is nullable if it is nullable or if the target is generated
* for an unmatched column in an insert with a column list.
* This additional check is needed because when we generate any additional
* source RCs for an insert with a column list the generated RCs for any
* non-specified columns get the type info from the column. Thus,
* for t1(non_nullable, nullable)
* insert into t2 (nullable) values 1;
* RCType.isNullable() returns false for the generated source RC for
* non_nullable. In this case, we want to see it as
*/
if ((!resultColumnType.isNullable()) && (otherResultColumnType.isNullable() || otherColumn.isGeneratedForUnmatchedColumnInInsert())) {
return false;
}
return true;
}
use of org.apache.derby.iapi.types.DataValueFactory in project derby by apache.
the class ResultColumn method convertConstant.
/**
* @exception StandardException Thrown on error
*/
@SuppressWarnings("fallthrough")
private DataValueDescriptor convertConstant(TypeId toTypeId, int maxWidth, DataValueDescriptor constantValue) throws StandardException {
int formatId = toTypeId.getTypeFormatId();
DataValueFactory dvf = getDataValueFactory();
switch(formatId) {
default:
case StoredFormatIds.CHAR_TYPE_ID:
return constantValue;
case StoredFormatIds.VARCHAR_TYPE_ID:
String sourceValue = constantValue.getString();
int sourceWidth = sourceValue.length();
int posn;
if (sourceWidth <= maxWidth) {
if (formatId == StoredFormatIds.VARCHAR_TYPE_ID)
return dvf.getVarcharDataValue(sourceValue);
}
/*
** Check whether any non-blank characters will be truncated.
*/
for (posn = maxWidth; posn < sourceWidth; posn++) {
if (sourceValue.charAt(posn) != ' ') {
String typeName = null;
if (formatId == StoredFormatIds.VARCHAR_TYPE_ID)
typeName = TypeId.VARCHAR_NAME;
throw StandardException.newException(SQLState.LANG_STRING_TRUNCATION, typeName, StringUtil.formatForPrint(sourceValue), String.valueOf(maxWidth));
}
}
if (formatId == StoredFormatIds.VARCHAR_TYPE_ID)
return dvf.getVarcharDataValue(sourceValue.substring(0, maxWidth));
case StoredFormatIds.LONGVARCHAR_TYPE_ID:
// No need to check widths here (unlike varchar), since no max width
return dvf.getLongvarcharDataValue(constantValue.getString());
}
}
Aggregations