Methods Summary |
---|
public org.hibernate.type.Type | getDataType()Figure out the type of the binary expression by looking at
the types of the operands. Sometimes we don't know both types,
if, for example, one is a parameter.
if ( super.getDataType() == null ) {
super.setDataType( resolveDataType() );
}
return super.getDataType();
|
public java.lang.String | getDisplayText()
return "{dataType=" + getDataType() + "}";
|
public Node | getLeftHandOperand()Retrieves the left-hand operand of the operator.
return ( Node ) getFirstChild();
|
public Node | getRightHandOperand()Retrieves the right-hand operand of the operator.
return ( Node ) getFirstChild().getNextSibling();
|
public void | initialize()
Node lhs = getLeftHandOperand();
Node rhs = getRightHandOperand();
if ( lhs == null ) {
throw new SemanticException( "left-hand operand of a binary operator was null" );
}
if ( rhs == null ) {
throw new SemanticException( "right-hand operand of a binary operator was null" );
}
Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) && rhType != null ) {
Type expectedType = null;
// we have something like : "? [op] rhs"
if ( isDateTimeType( rhType ) ) {
// more specifically : "? [op] datetime"
// 1) if the operator is MINUS, the param needs to be of
// some datetime type
// 2) if the operator is PLUS, the param needs to be of
// some numeric type
expectedType = getType() == HqlSqlTokenTypes.PLUS ? Hibernate.DOUBLE : rhType;
}
else {
expectedType = rhType;
}
( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( expectedType );
}
else if ( ParameterNode.class.isAssignableFrom( rhs.getClass() ) && lhType != null ) {
Type expectedType = null;
// we have something like : "lhs [op] ?"
if ( isDateTimeType( lhType ) ) {
// more specifically : "datetime [op] ?"
// 1) if the operator is MINUS, we really cannot determine
// the expected type as either another datetime or
// numeric would be valid
// 2) if the operator is PLUS, the param needs to be of
// some numeric type
if ( getType() == HqlSqlTokenTypes.PLUS ) {
expectedType = Hibernate.DOUBLE;
}
}
else {
expectedType = lhType;
}
( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( expectedType );
}
|
private boolean | isDateTimeType(org.hibernate.type.Type type)
if ( type == null ) {
return false;
}
return java.util.Date.class.isAssignableFrom( type.getReturnedClass() ) ||
java.util.Calendar.class.isAssignableFrom( type.getReturnedClass() );
|
private org.hibernate.type.Type | resolveDataType()
// TODO : we may also want to check that the types here map to exactly one column/JDBC-type
// can't think of a situation where arithmetic expression between multi-column mappings
// makes any sense.
Node lhs = getLeftHandOperand();
Node rhs = getRightHandOperand();
Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
if ( isDateTimeType( lhType ) || isDateTimeType( rhType ) ) {
return resolveDateTimeArithmeticResultType( lhType, rhType );
}
else {
if ( lhType == null ) {
if ( rhType == null ) {
// we do not know either type
return Hibernate.DOUBLE; //BLIND GUESS!
}
else {
// we know only the rhs-hand type, so use that
return rhType;
}
}
else {
if ( rhType == null ) {
// we know only the lhs-hand type, so use that
return lhType;
}
else {
if ( lhType==Hibernate.DOUBLE || rhType==Hibernate.DOUBLE ) return Hibernate.DOUBLE;
if ( lhType==Hibernate.FLOAT || rhType==Hibernate.FLOAT ) return Hibernate.FLOAT;
if ( lhType==Hibernate.BIG_DECIMAL || rhType==Hibernate.BIG_DECIMAL ) return Hibernate.BIG_DECIMAL;
if ( lhType==Hibernate.BIG_INTEGER || rhType==Hibernate.BIG_INTEGER ) return Hibernate.BIG_INTEGER;
if ( lhType==Hibernate.LONG || rhType==Hibernate.LONG ) return Hibernate.LONG;
if ( lhType==Hibernate.INTEGER || rhType==Hibernate.INTEGER ) return Hibernate.INTEGER;
return lhType;
}
}
}
|
private org.hibernate.type.Type | resolveDateTimeArithmeticResultType(org.hibernate.type.Type lhType, org.hibernate.type.Type rhType)
// here, we work under the following assumptions:
// ------------ valid cases --------------------------------------
// 1) datetime + {something other than datetime} : always results
// in a datetime ( db will catch invalid conversions )
// 2) datetime - datetime : always results in a DOUBLE
// 3) datetime - {something other than datetime} : always results
// in a datetime ( db will catch invalid conversions )
// ------------ invalid cases ------------------------------------
// 4) datetime + datetime
// 5) {something other than datetime} - datetime
// 6) datetime * {any type}
// 7) datetime / {any type}
// 8) {any type} / datetime
// doing so allows us to properly handle parameters as either the left
// or right side here in the majority of cases
boolean lhsIsDateTime = isDateTimeType( lhType );
boolean rhsIsDateTime = isDateTimeType( rhType );
// handle the (assumed) valid cases:
// #1 - the only valid datetime addition synatx is one or the other is a datetime (but not both)
if ( getType() == HqlSqlTokenTypes.PLUS ) {
// one or the other needs to be a datetime for us to get into this method in the first place...
return lhsIsDateTime ? lhType : rhType;
}
else if ( getType() == HqlSqlTokenTypes.MINUS ) {
// #3 - note that this is also true of "datetime - :param"...
if ( lhsIsDateTime && !rhsIsDateTime ) {
return lhType;
}
// #2
if ( lhsIsDateTime && rhsIsDateTime ) {
return Hibernate.DOUBLE;
}
}
return null;
|
public void | setScalarColumnText(int i)
ColumnHelper.generateSingleScalarColumn( this, i );
|