use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class MethodCallNode method parseValidateSignature.
/**
* Parse the user supplied signature for a method and validate
* it, need to match the number of parameters passed in and match
* the valid types for the parameter.
* @param offset Character offset of first paren
* @param hasDynamicResultSets Can ResultSet[] parameters be specified.
* @return The valid array of types for resolution.
* @throws StandardException
*/
private String[] parseValidateSignature(String externalName, int offset, boolean hasDynamicResultSets) throws StandardException {
int siglen = externalName.length();
// character and that the last character is a close paren
if (((offset + 1) == siglen) || (externalName.charAt(siglen - 1) != ')'))
// invalid
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
StringTokenizer st = new StringTokenizer(externalName.substring(offset + 1, siglen - 1), ",", true);
String[] signatureTypes = new String[signature.length];
int count;
boolean seenClass = false;
for (count = 0; st.hasMoreTokens(); ) {
String type = st.nextToken().trim();
// check sequence is <class><comma>class> etc.
if (",".equals(type)) {
if (!seenClass)
// invalid
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
seenClass = false;
continue;
} else {
if (type.length() == 0)
// invalid
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
seenClass = true;
count++;
}
if (count > signature.length) {
if (hasDynamicResultSets) {
// Allow any number of dynamic result set holders
// but they must match the exact type.
String rsType = signature[signature.length - 1].getSQLType().getTypeId().getCorrespondingJavaTypeName();
if (!type.equals(rsType))
throw StandardException.newException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, type, rsType);
if (signatureTypes.length == signature.length) {
// expand once
String[] sigs = new String[st.countTokens()];
System.arraycopy(signatureTypes, 0, sigs, 0, signatureTypes.length);
signatureTypes = sigs;
}
signatureTypes[count - 1] = type;
continue;
}
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_PARAMETER_COUNT, Integer.toString(count), // too many types
Integer.toString(signature.length));
}
TypeId paramTypeId = signature[count - 1].getSQLType().getTypeId();
// Does it match the object name
if (type.equals(paramTypeId.getCorrespondingJavaTypeName())) {
signatureTypes[count - 1] = type;
continue;
}
// how about the primitive name
if ((paramTypeId.isNumericTypeId() && !paramTypeId.isDecimalTypeId()) || paramTypeId.isBooleanTypeId()) {
TypeCompiler tc = getTypeCompiler(paramTypeId);
if (type.equals(tc.getCorrespondingPrimitiveTypeName())) {
signatureTypes[count - 1] = type;
continue;
}
}
throw StandardException.newException(SQLState.LANG_DATA_TYPE_GET_MISMATCH, type, // type conversion error
paramTypeId.getSQLTypeName());
}
// Did signature end with trailing comma?
if (count != 0 && !seenClass)
// invalid
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_INVALID);
if (count < signatureTypes.length) {
if (hasDynamicResultSets) {
// dynamic results at runtime
if (count == (signature.length - 1)) {
String[] sigs = new String[count];
System.arraycopy(signatureTypes, 0, sigs, 0, count);
return sigs;
}
}
throw StandardException.newException(SQLState.SQLJ_SIGNATURE_PARAMETER_COUNT, Integer.toString(count), // too few types
Integer.toString(signature.length));
}
return signatureTypes;
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class JoinNode method deferredBindExpressions.
private void deferredBindExpressions(FromList fromListParam) throws StandardException {
ContextManager cm = getContextManager();
CompilerContext cc = getCompilerContext();
/* Bind the expressions in the join clause */
subqueryList = new SubqueryList(cm);
aggregates = new ArrayList<AggregateNode>();
/* ON clause */
if (joinClause != null) {
joinClause = bindExpression(joinClause, true, true, "ON");
} else /* USING clause */
if (usingClause != null) {
/* Build a join clause from the usingClause, using the
* exposed names in the left and right RSNs.
* For each column in the list, we generate 2 ColumnReferences,
* 1 for the left and 1 for the right. We bind each of these
* to the appropriate side and build an equality predicate
* between the 2. We bind the = and AND nodes by hand because
* we have to bind the ColumnReferences a side at a time.
* We need to bind the CRs a side at a time to ensure that
* we don't find an bogus ambiguous column reference. (Bug 377)
*/
joinClause = new BooleanConstantNode(true, cm);
for (ResultColumn rc : usingClause) {
BinaryComparisonOperatorNode equalsNode;
ColumnReference leftCR;
ColumnReference rightCR;
/* Create and bind the left CR */
fromListParam.insertElementAt(leftResultSet, 0);
leftCR = new ColumnReference(rc.getName(), ((FromTable) leftResultSet).getTableName(), cm);
leftCR = (ColumnReference) leftCR.bindExpression(fromListParam, subqueryList, aggregates);
fromListParam.removeElementAt(0);
/* Create and bind the right CR */
fromListParam.insertElementAt(rightResultSet, 0);
rightCR = new ColumnReference(rc.getName(), ((FromTable) rightResultSet).getTableName(), cm);
rightCR = (ColumnReference) rightCR.bindExpression(fromListParam, subqueryList, aggregates);
fromListParam.removeElementAt(0);
/* Create and insert the new = condition */
equalsNode = new BinaryRelationalOperatorNode(BinaryRelationalOperatorNode.K_EQUALS, leftCR, rightCR, false, cm);
equalsNode.bindComparisonOperator();
// Create a new join clause by ANDing the new = condition and
// the old join clause.
AndNode newJoinClause = new AndNode(equalsNode, joinClause, cm);
newJoinClause.postBindFixup();
joinClause = newJoinClause;
}
}
if (joinClause != null) {
/* If joinClause is a parameter, (where ?), then we assume
* it will be a nullable boolean.
*/
if (joinClause.requiresTypeFromContext()) {
joinClause.setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, true));
}
/*
** Is the datatype of the JOIN clause BOOLEAN?
**
** NOTE: This test is not necessary in SQL92 entry level, because
** it is syntactically impossible to have a non-Boolean JOIN clause
** in that level of the standard. But we intend to extend the
** language to allow Boolean user functions in the JOIN clause,
** so we need to test for the error condition.
*/
TypeId joinTypeId = joinClause.getTypeId();
/* If the where clause is not a built-in type, then generate a bound
* conversion tree to a built-in type.
*/
if (joinTypeId.userType()) {
joinClause = joinClause.genSQLJavaSQLTree();
}
if (!joinClause.getTypeServices().getTypeId().equals(TypeId.BOOLEAN_ID)) {
throw StandardException.newException(SQLState.LANG_NON_BOOLEAN_JOIN_CLAUSE, joinClause.getTypeServices().getTypeId().getSQLTypeName());
}
}
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class MaxMinAggregateDefinition method getAggregator.
/**
* Determines the result datatype. Accept NumberDataValues
* only.
* <P>
* <I>Note</I>: In the future you should be able to do
* a sum user data types. One option would be to run
* sum on anything that implements divide().
*
* @param inputType the input type, either a user type or a java.lang object
*
* @return the output Class (null if cannot operate on
* value expression of this type.
*/
public final DataTypeDescriptor getAggregator(DataTypeDescriptor inputType, StringBuffer aggregatorClass) {
LanguageConnectionContext lcc = (LanguageConnectionContext) QueryTreeNode.getContext(LanguageConnectionContext.CONTEXT_ID);
/*
** MIN and MAX may return null
*/
DataTypeDescriptor dts = inputType.getNullabilityType(true);
TypeId compType = dts.getTypeId();
/*
** If the class implements NumberDataValue, then we
** are in business. Return type is same as input
** type.
*/
if (compType.orderable(lcc.getLanguageConnectionFactory().getClassFactory())) {
aggregatorClass.append(ClassName.MaxMinAggregator);
return dts;
}
return null;
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class ResultColumnList method setUnionResultExpression.
/**
* Set up the result expressions for a UNION, INTERSECT, or EXCEPT:
* o Verify union type compatiblity
* o Get dominant type for result (type + max length + nullability)
* o Create a new ColumnReference with dominant type and name of from this
* RCL and make that the new expression.
* o Set the type info for in the ResultColumn to the dominant type
*
* NOTE - We are assuming that caller has generated a new RCL for the UNION
* with the same names as the left side's RCL and copies of the expressions.
*
* @param otherRCL RCL from other side of the UNION.
* @param tableNumber The tableNumber for the UNION.
* @param level The nesting level for the UNION.
* @param operatorName "UNION", "INTERSECT", or "EXCEPT"
*
* @exception StandardException Thrown on error
*/
void setUnionResultExpression(ResultColumnList otherRCL, int tableNumber, int level, String operatorName) throws StandardException {
TableName dummyTN;
if (SanityManager.DEBUG) {
if (visibleSize() != otherRCL.visibleSize()) {
SanityManager.THROWASSERT("visibleSize() = (" + visibleSize() + ") is expected to equal otherRCL.visibleSize (" + otherRCL.visibleSize() + ")");
}
// Generated grouping columns and unselected ORDER BY columns
// should have been removed for the RCL of a SetOperatorNode, so
// that size and visible size are equal (DERBY-3764).
SanityManager.ASSERT(size() == visibleSize(), "size() and visibleSize() should be equal");
}
/* Make a dummy TableName to be shared by all new CRs */
dummyTN = new TableName(null, null, getContextManager());
int size = visibleSize();
for (int index = 0; index < size; index++) {
ColumnReference newCR;
ResultColumn thisRC = elementAt(index);
ResultColumn otherRC = otherRCL.elementAt(index);
ValueNode thisExpr = thisRC.getExpression();
ValueNode otherExpr = otherRC.getExpression();
// not be 'autoincrement'.
if (!otherRC.isAutoincrementGenerated() && thisRC.isAutoincrementGenerated()) {
thisRC.resetAutoincrementGenerated();
}
/*
** If there are ? parameters in the ResultColumnList of a row
** in a table constructor, their types will not be set. Just skip
** these - their types will be set later. Each ? parameter will
** get the type of the first non-? in its column, so it can't
** affect the final dominant type. It's possible that all the
** rows for a particular column will have ? parameters - this is
** an error condition that will be caught later.
*/
TypeId thisTypeId = thisExpr.getTypeId();
if (thisTypeId == null)
continue;
TypeId otherTypeId = otherExpr.getTypeId();
if (otherTypeId == null)
continue;
/*
** Check type compatability.
*/
ClassFactory cf = getClassFactory();
if (!unionCompatible(thisExpr, otherExpr)) {
throw StandardException.newException(SQLState.LANG_NOT_UNION_COMPATIBLE, thisTypeId.getSQLTypeName(), otherTypeId.getSQLTypeName(), operatorName);
}
DataTypeDescriptor resultType = thisExpr.getTypeServices().getDominantType(otherExpr.getTypeServices(), cf);
newCR = new ColumnReference(thisRC.getName(), dummyTN, getContextManager());
newCR.setType(resultType);
/* Set the tableNumber and nesting levels in newCR.
* If thisExpr is not a CR, then newCR cannot be
* correlated, hence source and nesting levels are
* the same.
*/
if (thisExpr instanceof ColumnReference) {
newCR.copyFields((ColumnReference) thisExpr);
} else {
newCR.setNestingLevel(level);
newCR.setSourceLevel(level);
}
newCR.setTableNumber(tableNumber);
thisRC.setExpression(newCR);
thisRC.setType(thisRC.getTypeServices().getDominantType(otherRC.getTypeServices(), cf));
/* DB2 requires both sides of union to have same name for the result to
* have that name. Otherwise, leave it or set it to a generated name */
if (thisRC.getName() != null && !thisRC.isNameGenerated() && otherRC.getName() != null) {
/* Result name needs to be changed */
if (otherRC.isNameGenerated()) {
thisRC.setName(otherRC.getName());
thisRC.setNameGenerated(true);
} else if (!thisRC.getName().equals(otherRC.getName())) {
/* Both sides have user specified names that don't match */
thisRC.setName(null);
thisRC.guaranteeColumnName();
thisRC.setNameGenerated(true);
}
}
}
}
use of org.apache.derby.iapi.types.TypeId in project derby by apache.
the class ColumnDefinitionNode method validateDefault.
/**
* Check the validity of the default for this node.
*
* @param td The TableDescriptor.
*
* @exception StandardException Thrown on error
*/
void validateDefault(DataDictionary dd, TableDescriptor td) throws StandardException {
if (defaultNode == null)
return;
// Examin whether default value is autoincrement.
if (isAutoincrement) {
defaultInfo = createDefaultInfoOfAutoInc();
return;
}
// Judged as default value is constant value.
CompilerContext cc = getCompilerContext();
ValueNode defaultTree = defaultNode.getDefaultTree();
/* bind the default.
* Verify that it does not contain any ColumnReferences or subqueries
* and that it is type compatable with the column.
*/
final int previousReliability = cc.getReliability();
try {
/*
Defaults cannot have dependencies as they
should just be constants. Code used to exist
to handle dependencies in defaults, now this
is under sanity to ensure no dependencies exist.
*/
ProviderList apl = null;
ProviderList prevAPL = null;
if (SanityManager.DEBUG) {
apl = new ProviderList();
prevAPL = cc.getCurrentAuxiliaryProviderList();
cc.setCurrentAuxiliaryProviderList(apl);
}
// Tell the compiler context to only allow deterministic nodes
cc.setReliability(CompilerContext.DEFAULT_RESTRICTION);
defaultTree = defaultTree.bindExpression(new FromList(getOptimizerFactory().doJoinOrderOptimization(), getContextManager()), (SubqueryList) null, (List<AggregateNode>) null);
TypeId columnTypeId = getType().getTypeId();
TypeId defaultTypeId = defaultTree.getTypeId();
// before checking for 'not storable' errors (42821).
if (!defaultTypeIsValid(columnTypeId, getType(), defaultTypeId, defaultTree, defaultNode.getDefaultText())) {
throw StandardException.newException(SQLState.LANG_DB2_INVALID_DEFAULT_VALUE, this.name);
}
// Now check 'not storable' errors.
if (!getTypeCompiler(columnTypeId).storable(defaultTypeId, getClassFactory())) {
throw StandardException.newException(SQLState.LANG_NOT_STORABLE, columnTypeId.getSQLTypeName(), defaultTypeId.getSQLTypeName());
}
// Save off the default text
// RESOLVEDEFAULT - Convert to constant if possible
defaultInfo = new DefaultInfoImpl(false, defaultNode.getDefaultText(), defaultValue);
if (SanityManager.DEBUG) {
/* Save the APL off in the constraint node */
if (apl.size() > 0) {
SanityManager.THROWASSERT("DEFAULT clause has unexpected dependencies");
}
// Restore the previous AuxiliaryProviderList
cc.setCurrentAuxiliaryProviderList(prevAPL);
}
} finally {
cc.setReliability(previousReliability);
}
}
Aggregations