use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class StaticMethodCallNode method resolveRoutine.
/**
* Resolve a routine. Obtain a list of routines from the data dictionary
* of the correct type (functions or procedures) and name.
* Pick the best routine from the list. Currently only a single routine
* with a given type and name is allowed, thus if changes are made to
* support overloaded routines, careful code inspection and testing will
* be required.
*/
private void resolveRoutine(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates, SchemaDescriptor sd, boolean noSchema) throws StandardException {
if (sd.getUUID() != null) {
List<AliasDescriptor> list = getDataDictionary().getRoutineList(sd.getUUID().toString(), methodName, forCallStatement ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR);
for (int i = list.size() - 1; i >= 0; i--) {
AliasDescriptor proc = list.get(i);
RoutineAliasInfo rai = (RoutineAliasInfo) proc.getAliasInfo();
int parameterCount = rai.getParameterCount();
boolean hasVarargs = rai.hasVarargs();
if (hasVarargs) {
// for the trailing varargs argument
if (methodParms.length < (parameterCount - 1)) {
continue;
}
} else if (parameterCount != methodParms.length) {
continue;
}
// pre-form the method signature. If it is a dynamic result set procedure
// then we need to add in the ResultSet array
TypeDescriptor[] parameterTypes = rai.getParameterTypes();
int sigParameterCount = parameterCount;
if (rai.getMaxDynamicResultSets() > 0) {
sigParameterCount++;
}
signature = new JSQLType[sigParameterCount];
for (int p = 0; p < parameterCount; p++) {
// find the declared type.
TypeDescriptor td = parameterTypes[p];
TypeId typeId = TypeId.getTypeId(td);
TypeId parameterTypeId = typeId;
// if it's an OUT or INOUT parameter we need an array.
int parameterMode = rai.getParameterModes()[getRoutineArgIdx(rai, p)];
if (parameterMode != (ParameterMetaData.parameterModeIn)) {
String arrayType;
switch(typeId.getJDBCTypeId()) {
case java.sql.Types.BOOLEAN:
case java.sql.Types.SMALLINT:
case java.sql.Types.INTEGER:
case java.sql.Types.BIGINT:
case java.sql.Types.REAL:
case java.sql.Types.DOUBLE:
arrayType = getTypeCompiler(typeId).getCorrespondingPrimitiveTypeName().concat("[]");
break;
default:
arrayType = typeId.getCorrespondingJavaTypeName().concat("[]");
break;
}
typeId = TypeId.getUserDefinedTypeId(arrayType);
}
// this is the type descriptor of the require method parameter
DataTypeDescriptor methoddtd = new DataTypeDescriptor(typeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
signature[p] = new JSQLType(methoddtd);
// this is the SQL type of the procedure parameter.
DataTypeDescriptor paramdtd = new DataTypeDescriptor(parameterTypeId, td.getPrecision(), td.getScale(), td.isNullable(), td.getMaximumWidth());
// if this is the last argument of a varargs routine...
if (hasVarargs && (p == parameterCount - 1)) {
//
for (int idx = p; idx < methodParms.length; idx++) {
coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, idx);
}
} else // NOT the last argument of a varargs routine
{
coerceMethodParameter(fromList, subqueryList, aggregates, rai, methodParms.length, paramdtd, parameterTypeId, parameterMode, p);
}
}
if (sigParameterCount != parameterCount) {
DataTypeDescriptor dtd = new DataTypeDescriptor(TypeId.getUserDefinedTypeId("java.sql.ResultSet[]"), 0, 0, false, -1);
signature[parameterCount] = new JSQLType(dtd);
}
this.routineInfo = rai;
ad = proc;
// SQL, note that we are in system code.
if (sd.isSystemSchema() && (routineInfo.getReturnType() == null) && routineInfo.getSQLAllowed() != RoutineAliasInfo.NO_SQL) {
isSystemCode = true;
}
routineDefiner = sd.getAuthorizationId();
break;
}
}
if ((ad == null) && (methodParms.length == 1)) {
ad = AggregateNode.resolveAggregate(getDataDictionary(), sd, methodName, noSchema);
}
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class StaticMethodCallNode method coerceMethodParameter.
/**
* <p>
* Coerce an actual method parameter to the declared type of the corresponding
* routine argument.
* </p>
*/
private void coerceMethodParameter(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates, RoutineAliasInfo rai, // number of declared routine args
int parameterCount, // declared type of routine arg
DataTypeDescriptor paramdtd, // declared type id of routine arg
TypeId parameterTypeId, int parameterMode, // index of actual method parameter in array of parameters
int p) throws StandardException {
// check parameter is a ? node for INOUT and OUT parameters.
ValueNode sqlParamNode = null;
if (methodParms[p] instanceof SQLToJavaValueNode) {
SQLToJavaValueNode sql2j = (SQLToJavaValueNode) methodParms[p];
sqlParamNode = sql2j.getSQLValueNode();
}
boolean isParameterMarker = true;
if ((sqlParamNode == null) || !sqlParamNode.requiresTypeFromContext()) {
if (parameterMode != (ParameterMetaData.parameterModeIn)) {
throw StandardException.newException(SQLState.LANG_DB2_PARAMETER_NEEDS_MARKER, RoutineAliasInfo.parameterMode(parameterMode), rai.getParameterNames()[p]);
}
isParameterMarker = false;
} else {
if (applicationParameterNumbers == null) {
applicationParameterNumbers = new int[parameterCount];
}
if (sqlParamNode instanceof UnaryOperatorNode) {
ParameterNode pn = ((UnaryOperatorNode) sqlParamNode).getParameterOperand();
applicationParameterNumbers[p] = pn.getParameterNumber();
} else {
applicationParameterNumbers[p] = ((ParameterNode) sqlParamNode).getParameterNumber();
}
}
boolean needCast = false;
if (!isParameterMarker) {
// type of the procedure parameter.
if (sqlParamNode instanceof UntypedNullConstantNode) {
sqlParamNode.setType(paramdtd);
} else {
DataTypeDescriptor dts;
TypeId argumentTypeId;
if (sqlParamNode != null) {
// a node from the SQL world
argumentTypeId = sqlParamNode.getTypeId();
dts = sqlParamNode.getTypeServices();
} else {
// a node from the Java world
dts = DataTypeDescriptor.getSQLDataTypeDescriptor(methodParms[p].getJavaTypeName());
if (dts == null) {
throw StandardException.newException(SQLState.LANG_NO_CORRESPONDING_S_Q_L_TYPE, methodParms[p].getJavaTypeName());
}
argumentTypeId = dts.getTypeId();
}
if (!getTypeCompiler(parameterTypeId).storable(argumentTypeId, getClassFactory())) {
throw StandardException.newException(SQLState.LANG_NOT_STORABLE, parameterTypeId.getSQLTypeName(), argumentTypeId.getSQLTypeName());
}
// if it's not an exact length match then some cast will be needed.
if (!paramdtd.isExactTypeAndLengthMatch(dts)) {
needCast = true;
}
}
} else {
// correctly as 10 characters long.
if (parameterTypeId.variableLength()) {
if (parameterMode != (ParameterMetaData.parameterModeOut)) {
needCast = true;
}
}
}
if (needCast) {
if (sqlParamNode == null) {
sqlParamNode = new JavaToSQLValueNode(methodParms[p], getContextManager());
}
ValueNode castNode = makeCast(sqlParamNode, paramdtd, getContextManager());
methodParms[p] = new SQLToJavaValueNode(castNode, getContextManager());
methodParms[p] = methodParms[p].bindExpression(fromList, subqueryList, aggregates);
}
// in parameter meta data
if (isParameterMarker) {
sqlParamNode.setType(paramdtd);
}
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class SubqueryNode method setDataTypeServices.
private void setDataTypeServices(ResultColumnList resultColumns) throws StandardException {
DataTypeDescriptor dts;
/* Set the result type for this subquery (must be nullable).
* Quantified predicates will return boolean.
* However, the return type of the subquery's result list will
* probably not be boolean at this point, because we do not
* transform the subquery (other than EXISTS) into
* (select true/false ...) until preprocess(). So, we force
* the return type to boolean.
*/
if (subqueryType == EXPRESSION_SUBQUERY) {
dts = resultColumns.elementAt(0).getTypeServices();
} else {
dts = getTrueNode().getTypeServices();
}
setType(dts.getNullabilityType(true));
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class SumAvgAggregateDefinition 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 plus(). In which
* case avg() would need 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) {
try {
TypeId compType = inputType.getTypeId();
CompilerContext cc = (CompilerContext) QueryTreeNode.getContext(CompilerContext.CONTEXT_ID);
TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
TypeCompiler tc = tcf.getTypeCompiler(compType);
/*
** If the class implements NumberDataValue, then we
** are in business. Return type is same as input
** type.
*/
if (compType.isNumericTypeId()) {
aggregatorClass.append(getAggregatorClassName());
DataTypeDescriptor outDts = tc.resolveArithmeticOperation(inputType, inputType, getOperator());
/*
** SUM and AVG may return null
*/
return outDts.getNullabilityType(true);
}
} catch (StandardException e) {
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("Unexpected exception", e);
}
}
return null;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class TableElementList method checkIndexPageSizeProperty.
/**
* Checks if the index should use a larger page size.
*
* If the columns in the index are large, and if the user hasn't already
* specified a page size to use, then we may need to default to the
* large page size in order to get an index with sufficiently large pages.
* For example, this DDL should use a larger page size for the index
* that backs the PRIMARY KEY constraint:
*
* create table t (x varchar(1000) primary key)
*
* @param cdn Constraint node
*
* @return properties to use for creating the index
*/
private Properties checkIndexPageSizeProperty(ConstraintDefinitionNode cdn) throws StandardException {
Properties result = cdn.getProperties();
if (result == null)
result = new Properties();
if (result.get(Property.PAGE_SIZE_PARAMETER) != null || PropertyUtil.getServiceProperty(getLanguageConnectionContext().getTransactionCompile(), Property.PAGE_SIZE_PARAMETER) != null) {
// is set for the whole database or just set on this statement.
return result;
}
int approxLength = 0;
for (ResultColumn rc : cdn.getColumnList()) {
String colName = rc.getName();
DataTypeDescriptor dtd;
if (td == null)
dtd = getColumnDataTypeDescriptor(colName);
else
dtd = getColumnDataTypeDescriptor(colName, td);
// skip the length checking if the column doesn't exist.
if (dtd != null)
approxLength += dtd.getTypeId().getApproximateLengthInBytes(dtd);
}
if (approxLength > Property.IDX_PAGE_SIZE_BUMP_THRESHOLD) {
result.put(Property.PAGE_SIZE_PARAMETER, Property.PAGE_SIZE_DEFAULT_LONG);
}
return result;
}
Aggregations