* invalid value for hashLoadFactor
* invalid value for hashMaxCapacity
*/
boolean indexSpecified = false;
boolean constraintSpecified = false;
ConstraintDescriptor consDesc = null;
Enumeration e = tableProperties.keys();
StringUtil.SQLEqualsIgnoreCase(tableDescriptor.getSchemaName(),
"SYS");
while (e.hasMoreElements())
{
String key = (String) e.nextElement();
String value = (String) tableProperties.get(key);
if (key.equals("index"))
{
// User only allowed to specify 1 of index and constraint, not both
if (constraintSpecified)
{
throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED,
getBaseTableName());
}
indexSpecified = true;
/* Validate index name - NULL means table scan */
if (! StringUtil.SQLToUpperCase(value).equals("NULL"))
{
ConglomerateDescriptor cd = null;
ConglomerateDescriptor[] cds = tableDescriptor.getConglomerateDescriptors();
for (int index = 0; index < cds.length; index++)
{
cd = cds[index];
String conglomerateName = cd.getConglomerateName();
if (conglomerateName != null)
{
if (conglomerateName.equals(value))
{
break;
}
}
// Not a match, clear cd
cd = null;
}
// Throw exception if user specified index not found
if (cd == null)
{
throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX1,
value, getBaseTableName());
}
/* Query is dependent on the ConglomerateDescriptor */
getCompilerContext().createDependency(cd);
}
}
else if (key.equals("constraint"))
{
// User only allowed to specify 1 of index and constraint, not both
if (indexSpecified)
{
throw StandardException.newException(SQLState.LANG_BOTH_FORCE_INDEX_AND_CONSTRAINT_SPECIFIED,
getBaseTableName());
}
constraintSpecified = true;
if (! StringUtil.SQLToUpperCase(value).equals("NULL"))
{
consDesc =
dDictionary.getConstraintDescriptorByName(
tableDescriptor, (SchemaDescriptor)null, value,
false);
/* Throw exception if user specified constraint not found
* or if it does not have a backing index.
*/
if ((consDesc == null) || ! consDesc.hasBackingIndex())
{
throw StandardException.newException(SQLState.LANG_INVALID_FORCED_INDEX2,
value, getBaseTableName());
}
/* Query is dependent on the ConstraintDescriptor */
getCompilerContext().createDependency(consDesc);
}
}
else if (key.equals("joinStrategy"))
{
userSpecifiedJoinStrategy = StringUtil.SQLToUpperCase(value);
}
else if (key.equals("hashInitialCapacity"))
{
initialCapacity = getIntProperty(value, key);
// verify that the specified value is valid
if (initialCapacity <= 0)
{
throw StandardException.newException(SQLState.LANG_INVALID_HASH_INITIAL_CAPACITY,
String.valueOf(initialCapacity));
}
}
else if (key.equals("hashLoadFactor"))
{
try
{
loadFactor = Float.parseFloat(value);
}
catch (NumberFormatException nfe)
{
throw StandardException.newException(SQLState.LANG_INVALID_NUMBER_FORMAT_FOR_OVERRIDE,
value, key);
}
// verify that the specified value is valid
if (loadFactor <= 0.0 || loadFactor > 1.0)
{
throw StandardException.newException(SQLState.LANG_INVALID_HASH_LOAD_FACTOR,
value);
}
}
else if (key.equals("hashMaxCapacity"))
{
maxCapacity = getIntProperty(value, key);
// verify that the specified value is valid
if (maxCapacity <= 0)
{
throw StandardException.newException(SQLState.LANG_INVALID_HASH_MAX_CAPACITY,
String.valueOf(maxCapacity));
}
}
else if (key.equals("bulkFetch"))
{
bulkFetch = getIntProperty(value, key);
// verify that the specified value is valid
if (bulkFetch <= 0)
{
throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_VALUE,
String.valueOf(bulkFetch));
}
// no bulk fetch on updatable scans
if (forUpdate())
{
throw StandardException.newException(SQLState.LANG_INVALID_BULK_FETCH_UPDATEABLE);
}
}
else
{
// No other "legal" values at this time
throw StandardException.newException(SQLState.LANG_INVALID_FROM_TABLE_PROPERTY, key,
"index, constraint, joinStrategy");
}
}
/* If user specified a non-null constraint name(DERBY-1707), then
* replace it in the properties list with the underlying index name to
* simplify the code in the optimizer.
* NOTE: The code to get from the constraint name, for a constraint
* with a backing index, to the index name is convoluted. Given
* the constraint name, we can get the conglomerate id from the
* ConstraintDescriptor. We then use the conglomerate id to get
* the ConglomerateDescriptor from the DataDictionary and, finally,
* we get the index name (conglomerate name) from the ConglomerateDescriptor.
*/
if (constraintSpecified && consDesc != null)
{
ConglomerateDescriptor cd =
dDictionary.getConglomerateDescriptor(
consDesc.getConglomerateId());
String indexName = cd.getConglomerateName();
tableProperties.remove("constraint");
tableProperties.put("index", indexName);
}