use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class StaticMethodCallNode method bindExpressionMinion.
private JavaValueNode bindExpressionMinion(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
bindParameters(fromList, subqueryList, aggregates);
/* If javaClassName is null then we assume that the current methodName
* is an alias and we must go to sysmethods to
* get the real method and java class names for this alias.
*/
if (javaClassName == null) {
CompilerContext cc = getCompilerContext();
// look for a routine
String schemaName = procedureName.getSchemaName();
boolean noSchema = schemaName == null;
SchemaDescriptor sd = getSchemaDescriptor(schemaName, schemaName != null);
// The field methodName is used by resolveRoutine and
// is set to the name of the routine (procedureName.getTableName()).
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
if ((ad != null) && (ad.getAliasType() == AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR)) {
resolvedAggregate = new AggregateNode(((SQLToJavaValueNode) methodParms[0]).getSQLValueNode(), new UserAggregateDefinition(ad), procedureName, false, ad.getJavaClassName(), getContextManager());
// Propagate tags used to flag nodes which need privilege checks. See DERBY-6429.
resolvedAggregate.copyTagsFrom(this);
// GROUP BY clause. That is not allowed.
if (appearsInGroupBy) {
throw StandardException.newException(SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST);
}
return this;
}
SchemaDescriptor savedSd = sd;
if (ad == null && noSchema && !forCallStatement) {
// Resolve to a built-in SYSFUN function but only
// if this is a function call and the call
// was not qualified. E.g. COS(angle). The
// SYSFUN functions are not in SYSALIASES but
// an in-memory table, set up in DataDictioanryImpl.
sd = getSchemaDescriptor("SYSFUN", true);
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
}
if (ad == null) {
// DERBY-2927. Check if a procedure is being used as a
// function, or vice versa.
sd = savedSd;
if (!forCallStatement) {
// Procedure as function. We have JDBC escape syntax which
// may entice users to try that:
// "{? = CALL <proc>}"
//
// but we don't currently support it (it's not std SQL
// either). By resolving it as a procedure we can give a
// better error message.
//
// Note that with the above escape syntax one *can* CALL a
// function, though:
// "{? = CALL <func>}"
//
// but such cases have already been resolved above.
// temporarily: resolve
forCallStatement = true;
// as procedure
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
// restore it
forCallStatement = false;
if (ad != null) {
throw StandardException.newException(SQLState.LANG_PROC_USED_AS_FUNCTION, procedureName);
}
} else {
// Maybe a function is being CALLed ?
// temporarily: resolve
forCallStatement = false;
// as function
resolveRoutine(fromList, subqueryList, aggregates, sd, noSchema);
// restore it
forCallStatement = true;
if (ad != null) {
throw StandardException.newException(SQLState.LANG_FUNCTION_USED_AS_PROC, procedureName);
}
}
}
/* Throw exception if no routine found */
if (ad == null) {
throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, procedureName);
}
if (noSchema) {
// If no schema was specified, register where we found the
// routine.
procedureName.setSchemaName(sd.getSchemaName());
}
if (!routineInfo.isDeterministic()) {
checkReliability(getMethodName(), CompilerContext.NON_DETERMINISTIC_ILLEGAL);
}
if (permitsSQL(routineInfo)) {
checkReliability(getMethodName(), CompilerContext.SQL_IN_ROUTINES_ILLEGAL);
}
/* Query is dependent on the AliasDescriptor */
cc.createDependency(ad);
methodName = ad.getAliasInfo().getMethodName();
javaClassName = ad.getJavaClassName();
// A special exception is made for the optional tools methods.
if (javaClassName.startsWith("org.apache.derby.") && !javaClassName.startsWith("org.apache.derby.impl.tools.optional.") && !javaClassName.startsWith("org.apache.derby.optional.lucene.") && !javaClassName.startsWith("org.apache.derby.optional.json.") && !javaClassName.startsWith("org.apache.derby.optional.api.") && !javaClassName.startsWith("org.apache.derby.optional.dump.") && !javaClassName.startsWith("org.apache.derby.vti.")) {
if (!sd.isSystemSchema())
throw StandardException.newException(SQLState.LANG_TYPE_DOESNT_EXIST2, (Throwable) null, javaClassName);
}
}
verifyClassExist(javaClassName);
/* Resolve the method call */
resolveMethodCall(javaClassName, true);
if (isPrivilegeCollectionRequired())
getCompilerContext().addRequiredRoutinePriv(ad);
// return type, then we need to push a CAST node.
if (routineInfo != null) {
if (methodParms != null)
optimizeDomainValueConversion();
TypeDescriptor returnType = routineInfo.getReturnType();
// create type dependency if return type is an ANSI UDT
if (returnType != null) {
createTypeDependency(DataTypeDescriptor.getType(returnType));
}
if (returnType != null && !returnType.isRowMultiSet() && !returnType.isUserDefinedType()) {
TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
if (returnTypeId.variableLength()) {
// Cast the return using a cast node, but have to go
// into the SQL domain, and back to the Java domain.
DataTypeDescriptor returnValueDtd = new DataTypeDescriptor(returnTypeId, returnType.getPrecision(), returnType.getScale(), returnType.isNullable(), returnType.getMaximumWidth());
ValueNode returnValueToSQL = new JavaToSQLValueNode(this, getContextManager());
ValueNode returnValueCastNode = new CastNode(returnValueToSQL, returnValueDtd, getContextManager());
// DERBY-2972 Match the collation of the RoutineAliasInfo
returnValueCastNode.setCollationInfo(returnType.getCollationType(), StringDataValue.COLLATION_DERIVATION_IMPLICIT);
JavaValueNode returnValueToJava = new SQLToJavaValueNode(returnValueCastNode, getContextManager());
returnValueToJava.setCollationType(returnType.getCollationType());
return returnValueToJava.bindExpression(fromList, subqueryList, aggregates);
}
}
}
return this;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class TableElementList method areColumnsNullable.
/**
* Checks if any of the columns in the constraint can be null.
*
* @param cdn Constraint node
* @param td tabe descriptor of the target table
*
* @return true if any of the column can be null false other wise
*/
private boolean areColumnsNullable(ConstraintDefinitionNode cdn, TableDescriptor td) {
for (ResultColumn rc : cdn.getColumnList()) {
String colName = rc.getName();
DataTypeDescriptor dtd = (td == null) ? getColumnDataTypeDescriptor(colName) : getColumnDataTypeDescriptor(colName, td);
// todo dtd may be null if the column does not exist, we should check that first
if (dtd != null && dtd.isNullable()) {
return true;
}
}
return false;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class AlterTableConstantAction method modifyColumnConstraint.
/**
* Workhorse for modifying column level constraints.
* Right now it is restricted to modifying a null constraint to a not null
* constraint.
*/
private void modifyColumnConstraint(String colName, boolean nullability) throws StandardException {
ColumnDescriptor columnDescriptor = td.getColumnDescriptor(colName);
// Get the type and change the nullability
DataTypeDescriptor dataType = columnDescriptor.getType().getNullabilityType(nullability);
// check if there are any unique constraints to update
ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);
int columnPostion = columnDescriptor.getPosition();
for (int i = 0; i < cdl.size(); i++) {
ConstraintDescriptor cd = cdl.elementAt(i);
if (cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
ColumnDescriptorList columns = cd.getColumnDescriptors();
for (int count = 0; count < columns.size(); count++) {
if (columns.elementAt(count).getPosition() != columnPostion)
break;
// get backing index
ConglomerateDescriptor desc = td.getConglomerateDescriptor(cd.getConglomerateId());
// not null ie is backed by unique index
if (!(desc.getIndexDescriptor().isUnique() || desc.getIndexDescriptor().hasDeferrableChecking())) {
break;
}
// replace backing index with a unique when not null index.
recreateUniqueConstraintBackingIndexAsUniqueWhenNotNull(desc, td, activation, lcc);
}
}
}
ColumnDescriptor newColumnDescriptor = new ColumnDescriptor(colName, columnDescriptor.getPosition(), dataType, columnDescriptor.getDefaultValue(), columnDescriptor.getDefaultInfo(), td, columnDescriptor.getDefaultUUID(), columnDescriptor.getAutoincStart(), columnDescriptor.getAutoincInc(), columnDescriptor.getAutoincCycle());
// Update the ColumnDescriptor with new default info
dd.dropColumnDescriptor(td.getUUID(), colName, tc);
dd.addDescriptor(newColumnDescriptor, td, DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
}
use of org.apache.derby.iapi.types.DataTypeDescriptor 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.DataTypeDescriptor in project derby by apache.
the class UnaryLogicalOperatorNode method setFullTypeInfo.
/**
* Set all of the type info (nullability and DataTypeServices) for
* this node. Extracts out tasks that must be done by both bind()
* and post-bind() AndNode generation.
*
* @exception StandardException Thrown on error
*/
protected void setFullTypeInfo() throws StandardException {
boolean nullableResult;
/*
** Set the result type of this comparison operator based on the
** operands. The result type is always SQLBoolean - the only question
** is whether it is nullable or not. If either of the operands is
** nullable, the result of the comparison must be nullable, too, so
** we can represent the unknown truth value.
*/
nullableResult = operand.getTypeServices().isNullable();
setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID, nullableResult));
}
Aggregations