use of org.voltdb.VoltType in project voltdb by VoltDB.
the class OperatorExpression method refineValueType.
@Override
public void refineValueType(VoltType neededType, int neededSize) {
if (!needsRightExpression()) {
return;
}
if (getExpressionType() == ExpressionType.OPERATOR_CASE_WHEN) {
assert (m_right.getExpressionType() == ExpressionType.OPERATOR_ALTERNATIVE);
m_right.refineValueType(neededType, neededSize);
m_valueType = m_right.getValueType();
m_valueSize = m_right.getValueSize();
return;
}
// The intent here is to allow operands to have the maximum flexibility given the
// desired result type. The interesting cases are basically integer, decimal, and
// float. If any of the lhs, rhs, or target result type are float, then any ambiguity
// in the remaining arguments (such as parameters) should be resolved in favor of
// float. Otherwise, if any are decimal, then decimal should be favored. Otherwise,
// the broadest integer type is preferable, even if the target is of a more limited
// integer type -- math has a way of scaling values up AND down.
VoltType operandType = neededType;
if (operandType.isBackendIntegerType()) {
operandType = VoltType.BIGINT;
}
VoltType leftType = m_left.getValueType();
VoltType rightType = m_right.getValueType();
if (leftType == VoltType.FLOAT || rightType == VoltType.FLOAT) {
operandType = VoltType.FLOAT;
} else if (operandType != VoltType.FLOAT) {
if (leftType == VoltType.DECIMAL || rightType == VoltType.DECIMAL) {
operandType = VoltType.DECIMAL;
}
}
m_left.refineOperandType(operandType);
m_right.refineOperandType(operandType);
//XXX Not sure how unary minus (and unary plus?) are handled (possibly via an implicit zero left argument?)
VoltType cast_type = VoltTypeUtil.determineImplicitCasting(m_left.getValueType(), m_right.getValueType());
if (cast_type == VoltType.INVALID) {
throw new RuntimeException("ERROR: Invalid output value type for Expression '" + this + "'");
}
m_valueType = cast_type;
m_valueSize = cast_type.getLengthInBytesForFixedTypes();
}
use of org.voltdb.VoltType in project voltdb by VoltDB.
the class OperatorExpression method finalizeValueTypes.
@Override
public void finalizeValueTypes() {
finalizeChildValueTypes();
ExpressionType type = getExpressionType();
if (m_right == null) {
if (type == ExpressionType.OPERATOR_IS_NULL || type == ExpressionType.OPERATOR_NOT || type == ExpressionType.OPERATOR_EXISTS) {
m_valueType = VoltType.BOOLEAN;
m_valueSize = m_valueType.getLengthInBytesForFixedTypes();
}
return;
}
if (type == ExpressionType.OPERATOR_CASE_WHEN || type == ExpressionType.OPERATOR_ALTERNATIVE) {
assert (m_valueType != null);
m_valueSize = m_valueType.getMaxLengthInBytes();
return;
}
VoltType left_type = m_left.getValueType();
//XXX Not sure how unary minus (and unary plus?) are handled (possibly via an implicit zero left argument?)
VoltType right_type = m_right.getValueType();
VoltType cast_type = VoltTypeUtil.determineImplicitCasting(left_type, right_type);
if (cast_type == VoltType.INVALID) {
throw new RuntimeException("ERROR: Invalid output value type for Expression '" + this + "'");
}
m_valueType = cast_type;
// this may not always be safe
m_valueSize = cast_type.getLengthInBytesForFixedTypes();
}
use of org.voltdb.VoltType in project voltdb by VoltDB.
the class ParameterValueExpression method refineValueType.
@Override
public void refineValueType(VoltType neededType, int neededSize) {
if (m_originalValue != null) {
// Do not push down a target type that contradicts the original constant value
// of a generated parameter.
m_originalValue.refineValueType(neededType, neededSize);
VoltType fallbackType = m_originalValue.getValueType();
if (fallbackType != neededType) {
setValueType(fallbackType);
setValueSize(fallbackType.getLengthInBytesForFixedTypes());
return;
}
}
// Otherwise, target knows best?
setValueType(neededType);
setValueSize(neededSize);
}
use of org.voltdb.VoltType in project voltdb by VoltDB.
the class ParameterValueExpression method finalizeValueTypes.
@Override
public void finalizeValueTypes() {
// indexed access paths, but it might not be critical (i.e. might be obsolete).
if (m_valueType != null && m_valueType != VoltType.NUMERIC) {
return;
}
// BigInt or Float, Decimal is not selected here because of its range is smaller
VoltType fallbackType = VoltType.FLOAT;
if (m_originalValue != null) {
m_originalValue.refineOperandType(VoltType.BIGINT);
// Typically BIGINT or FLOAT.
fallbackType = m_originalValue.getValueType();
}
m_valueType = fallbackType;
m_valueSize = m_valueType.getLengthInBytesForFixedTypes();
}
use of org.voltdb.VoltType in project voltdb by VoltDB.
the class FunctionExpression method negotiateInitialValueTypes.
/** Negotiate the type(s) of the parameterized function's result and its parameter argument.
* This avoids a fatal "non-castable type" runtime exception.
*/
public void negotiateInitialValueTypes() {
// Either of the function result type or parameter type could be null or a specific supported value type, or a generic
// NUMERIC. Replace any "generic" type (null or NUMERIC) with the more specific type without over-specifying
// -- the BEST type might only become clear later when the context/caller of this function is parsed, so don't
// risk guessing wrong here just for the sake of specificity.
// There will be a "finalize" pass over the completed expression tree to finish specifying any remaining "generics".
// DO use the type chosen by HSQL for the parameterized function as a specific type hint
// for numeric constant arguments that could either go decimal or float.
AbstractExpression typing_arg = m_args.get(m_resultTypeParameterIndex);
VoltType param_type = typing_arg.getValueType();
VoltType value_type = getValueType();
// including NUMERIC is better than nothing. And that anything else is better than NUMERIC.
if (value_type != param_type) {
if (value_type == null) {
value_type = param_type;
} else if (value_type == VoltType.NUMERIC) {
if (param_type != null) {
value_type = param_type;
}
// Pushing a type DOWN to the argument is a lot like work, and not worth it just to
// propagate down a known NUMERIC return type,
// since it will just have to be re-specialized when a more specific type is inferred from
// the context or finalized when the expression is complete.
} else if ((param_type == null) || (param_type == VoltType.NUMERIC)) {
// The only purpose of refining the parameter argument's type is to force a more specific
// refinement than NUMERIC as implied by HSQL, in case that might be more specific than
// what can be inferred later from the function call context.
typing_arg.refineValueType(value_type, value_type.getMaxLengthInBytes());
}
}
if (value_type != null) {
setValueType(value_type);
if (value_type != VoltType.INVALID && value_type != VoltType.NUMERIC) {
int size = value_type.getMaxLengthInBytes();
setValueSize(size);
}
}
}
Aggregations