use of org.hsqldb_voltpatches.types.DTIType in project voltdb by VoltDB.
the class FunctionSQL method resolveTypes.
@Override
public void resolveTypes(Session session, Expression parent) {
for (int i = 0; i < nodes.length; i++) {
if (nodes[i] != null) {
nodes[i].resolveTypes(session, this);
}
}
switch(funcType) {
case FUNC_POSITION_CHAR:
case FUNC_POSITION_BINARY:
{
if (nodes[0].dataType == null) {
if (nodes[1].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
if (nodes[1].dataType.typeCode == Types.SQL_CLOB || nodes[1].dataType.isBinaryType()) {
nodes[0].dataType = nodes[1].dataType;
} else {
nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
}
}
if (nodes[1].dataType == null) {
if (nodes[0].dataType.typeCode == Types.SQL_CLOB || nodes[0].dataType.isBinaryType()) {
nodes[1].dataType = nodes[0].dataType;
} else {
nodes[1].dataType = Type.SQL_VARCHAR_DEFAULT;
}
}
if (nodes[0].dataType.isCharacterType() && nodes[1].dataType.isCharacterType()) {
funcType = FUNC_POSITION_CHAR;
} else if (nodes[0].dataType.isBinaryType() && nodes[1].dataType.isBinaryType()) {
if (nodes[0].dataType.isBitType() || nodes[1].dataType.isBitType()) {
throw Error.error(ErrorCode.X_42565);
}
funcType = FUNC_POSITION_BINARY;
} else {
throw Error.error(ErrorCode.X_42565);
}
dataType = Type.SQL_BIGINT;
break;
}
/*
case FUNC_OCCURENCES_REGEX :
case FUNC_POSITION_REGEX :
*/
case FUNC_EXTRACT:
{
if (nodes[1].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
if (!nodes[1].dataType.isDateTimeType() && !nodes[1].dataType.isIntervalType()) {
throw Error.error(ErrorCode.X_42565);
}
int part = ((Number) nodes[0].valueData).intValue();
DTIType type = (DTIType) nodes[1].dataType;
part = DTIType.getFieldNameTypeForToken(part);
dataType = type.getExtractType(part);
break;
}
case FUNC_BIT_LENGTH:
{
if (nodes[0].dataType == null) {
nodes[0].dataType = Type.SQL_BIT_VARYING_MAX_LENGTH;
}
if (!nodes[0].dataType.isCharacterType() && !nodes[0].dataType.isBinaryType()) {
throw Error.error(ErrorCode.X_42565);
}
dataType = Type.SQL_BIGINT;
break;
}
case FUNC_CHAR_LENGTH:
case FUNC_OCTET_LENGTH:
{
if (nodes[0].dataType == null) {
nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
} else if (!nodes[0].dataType.isCharacterType() && ((funcType == FUNC_CHAR_LENGTH) || (!nodes[0].dataType.isBinaryType() && (funcType == FUNC_OCTET_LENGTH)))) {
throw Error.error(ErrorCode.X_42565);
}
dataType = Type.SQL_BIGINT;
break;
}
case FUNC_CARDINALITY:
{
dataType = Type.SQL_BIGINT;
break;
}
case FUNC_MOD:
{
if (nodes[0].dataType == null) {
if (nodes[1].dataType == null) {
// Data types for both operands are unknown, throw exception.
throw Error.error(ErrorCode.X_42567);
}
nodes[0].dataType = nodes[1].dataType;
}
if (nodes[0].dataType.isIntegralType()) {
// Promote the data type to BIGINT for integral data types.
nodes[0].dataType = Type.SQL_BIGINT;
}
if (nodes[1].dataType == null) {
nodes[1].dataType = nodes[0].dataType;
}
// "scale != 0", supported by customer request).
if (!(nodes[0].dataType.isIntegralType() || nodes[0].dataType.typeCode == Types.SQL_DECIMAL)) {
throw Error.error(ErrorCode.X_42565);
}
if (!(nodes[1].dataType.isIntegralType() || nodes[1].dataType.typeCode == Types.SQL_DECIMAL)) {
throw Error.error(ErrorCode.X_42565);
}
// (by the decision of the requesting customer).
if (nodes[0].dataType.isIntegralType() != nodes[1].dataType.isIntegralType()) {
throw Error.error(ErrorCode.X_42565);
}
parameterArg = 1;
dataType = nodes[1].dataType;
break;
}
case FUNC_POWER:
{
if (nodes[0].dataType == null) {
// A VoltDB extension to customize the SQL function set support
// VoltDB swapped out this odd propagation of nulls.
// VoltDB simply gives missing types the benefit of the doubt.
nodes[0].dataType = Type.SQL_DOUBLE;
// For VoltDB, the retest for null below is now redundant.
/* disable 1 line ...
nodes[1].dataType = nodes[0].dataType;
... disabled 1 line */
// End of VoltDB extension
}
if (nodes[1].dataType == null) {
// VoltDB swapped out this odd propagation of nulls.
// ORIGINAL HSQL CODE: nodes[0].dataType = nodes[1].dataType;
// VoltDB simply gives missing types the benefit of the doubt.
nodes[1].dataType = Type.SQL_DOUBLE;
// A VoltDB extension to customize the SQL function set support
// VoltDB swapped out this odd propagation of nulls.
/* disable 1 line ...
nodes[0].dataType = nodes[1].dataType;
... disabled 1 line */
// End of VoltDB extension
}
if (nodes[0].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
if (!nodes[0].dataType.isNumberType() || !nodes[1].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
nodes[0].dataType = Type.SQL_DOUBLE;
nodes[1].dataType = Type.SQL_DOUBLE;
dataType = Type.SQL_DOUBLE;
break;
}
case FUNC_LN:
case FUNC_EXP:
case FUNC_SQRT:
{
if (nodes[0].dataType == null) {
nodes[0].dataType = Type.SQL_DOUBLE;
}
if (!nodes[0].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
nodes[0].dataType = Type.SQL_DOUBLE;
dataType = Type.SQL_DOUBLE;
break;
}
case FUNC_ABS:
if (nodes[0].dataType != null && nodes[0].dataType.isIntervalType()) {
dataType = nodes[0].dataType;
// A VoltDB extension to customize the SQL function set support
parameterArg = 0;
break;
}
// $FALL-THROUGH$
case FUNC_FLOOR:
case FUNC_CEILING:
{
if (nodes[0].dataType == null) {
nodes[0].dataType = Type.SQL_DOUBLE;
}
if (!nodes[0].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
dataType = nodes[0].dataType;
// A VoltDB extension to customize the SQL function set support
parameterArg = 0;
break;
}
case FUNC_WIDTH_BUCKET:
{
if (nodes[0].dataType == null || nodes[1].dataType == null || nodes[2].dataType == null || nodes[3].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
if (!nodes[0].dataType.isNumberType() || !nodes[1].dataType.isNumberType() || !nodes[2].dataType.isNumberType() || !nodes[3].dataType.isIntegralType()) {
throw Error.error(ErrorCode.X_42565);
}
dataType = nodes[3].dataType;
// A VoltDB extension to customize the SQL function set support
parameterArg = 3;
break;
}
case FUNC_SUBSTRING_CHAR:
case FUNC_SUBSTRING_BINARY:
{
if (nodes[0].dataType == null) {
// in 20.6 parameter not allowed as type cannot be determined as binary or char
throw Error.error(ErrorCode.X_42567);
}
if (nodes[1].dataType == null) {
nodes[1].dataType = NumberType.SQL_NUMERIC_DEFAULT_INT;
}
if (!nodes[1].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
/* disable 1 line ...
if (nodes[2] != null) {
... disabled 1 line */
if (nodes.length > 2 && nodes[2] != null) {
// End of VoltDB extension
if (nodes[2].dataType == null) {
nodes[2].dataType = NumberType.SQL_NUMERIC_DEFAULT_INT;
}
if (!nodes[2].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
nodes[2].dataType = ((NumberType) nodes[2].dataType).getIntegralType();
}
dataType = nodes[0].dataType;
// A VoltDB extension to customize the SQL function set support
parameterArg = 0;
if (dataType.isCharacterType()) {
funcType = FUNC_SUBSTRING_CHAR;
if (dataType.typeCode == Types.SQL_CHAR) {
dataType = CharacterType.getCharacterType(Types.SQL_VARCHAR, dataType.precision);
}
} else if (dataType.isBinaryType()) {
funcType = FUNC_SUBSTRING_BINARY;
} else {
throw Error.error(ErrorCode.X_42565);
}
if (nodes.length > 3 && nodes[3] != null) {
// always boolean constant if defined
}
break;
}
/*
case FUNCTION_SUBSTRING_REG_EXPR :
break;
case FUNCTION_SUBSTRING_REGEX :
break;
*/
case FUNC_FOLD_LOWER:
case FUNC_FOLD_UPPER:
if (nodes[0].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
dataType = nodes[0].dataType;
// A VoltDB extension to customize the SQL function set support
parameterArg = 0;
if (!dataType.isCharacterType()) {
throw Error.error(ErrorCode.X_42565);
}
break;
/*
case FUNCTION_TRANSCODING :
break;
case FUNCTION_TRANSLITERATION :
break;
case FUNCTION_REGEX_TRANSLITERATION :
break;
*/
case FUNC_TRIM_CHAR:
case FUNC_TRIM_BINARY:
if (nodes[0] == null) {
nodes[0] = new ExpressionValue(ValuePool.getInt(Tokens.BOTH), Type.SQL_INTEGER);
}
// with the default value ' '.
if (nodes[2] == null) {
nodes[2] = nodes[1];
nodes[1] = null;
}
// End of VoltDB extension
if (nodes[2].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
dataType = nodes[2].dataType;
if (dataType.isCharacterType()) {
funcType = FUNC_TRIM_CHAR;
if (dataType.typeCode == Types.SQL_CHAR) {
dataType = CharacterType.getCharacterType(Types.SQL_VARCHAR, dataType.precision);
}
if (nodes[1] == null) {
nodes[1] = new ExpressionValue(" ", Type.SQL_CHAR);
} else // A VoltDB extension to customize the SQL function set support
if (nodes[1].dataType != Type.SQL_CHAR) {
nodes[1].dataType = Type.SQL_CHAR;
}
// End of VoltDB extension
} else if (dataType.isBinaryType()) {
funcType = FUNC_TRIM_BINARY;
if (nodes[1] == null) {
nodes[1] = new ExpressionValue(new BinaryData(new byte[] { 0 }, false), Type.SQL_BINARY);
}
} else {
throw Error.error(ErrorCode.X_42565);
}
break;
case FUNC_OVERLAY_CHAR:
case FUNC_OVERLAY_BINARY:
{
if (nodes[0].dataType == null) {
if (nodes[1].dataType == null) {
throw Error.error(ErrorCode.X_42567);
}
if (nodes[1].dataType.typeCode == Types.SQL_CLOB || nodes[1].dataType.isBinaryType()) {
nodes[0].dataType = nodes[1].dataType;
} else {
nodes[0].dataType = Type.SQL_VARCHAR_DEFAULT;
}
}
if (nodes[1].dataType == null) {
if (nodes[0].dataType.typeCode == Types.SQL_CLOB || nodes[0].dataType.isBinaryType()) {
nodes[1].dataType = nodes[0].dataType;
} else {
nodes[1].dataType = Type.SQL_VARCHAR_DEFAULT;
}
}
if (nodes[0].dataType.isCharacterType() && nodes[1].dataType.isCharacterType()) {
funcType = FUNC_OVERLAY_CHAR;
if (nodes[0].dataType.typeCode == Types.SQL_CLOB || nodes[1].dataType.typeCode == Types.SQL_CLOB) {
dataType = CharacterType.getCharacterType(Types.SQL_CLOB, nodes[0].dataType.precision + nodes[1].dataType.precision);
} else {
dataType = CharacterType.getCharacterType(Types.SQL_VARCHAR, nodes[0].dataType.precision + nodes[1].dataType.precision);
}
} else if (nodes[0].dataType.isBinaryType() && nodes[1].dataType.isBinaryType()) {
funcType = FUNC_OVERLAY_BINARY;
if (nodes[0].dataType.typeCode == Types.SQL_BLOB || nodes[1].dataType.typeCode == Types.SQL_BLOB) {
dataType = BinaryType.getBinaryType(Types.SQL_BLOB, nodes[0].dataType.precision + nodes[1].dataType.precision);
} else {
dataType = BinaryType.getBinaryType(Types.SQL_VARBINARY, nodes[0].dataType.precision + nodes[1].dataType.precision);
}
} else {
throw Error.error(ErrorCode.X_42565);
}
// A VoltDB extension to customize the SQL function set support
parameterArg = 0;
if (nodes[2].dataType == null) {
nodes[2].dataType = NumberType.SQL_NUMERIC_DEFAULT_INT;
}
if (!nodes[2].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
nodes[2].dataType = ((NumberType) nodes[2].dataType).getIntegralType();
if (nodes[3] != null) {
if (nodes[3].dataType == null) {
nodes[3].dataType = NumberType.SQL_NUMERIC_DEFAULT_INT;
}
if (!nodes[3].dataType.isNumberType()) {
throw Error.error(ErrorCode.X_42565);
}
nodes[3].dataType = ((NumberType) nodes[3].dataType).getIntegralType();
}
break;
}
/*
case FUNCTION_CHAR_NORMALIZE :
break;
*/
case FUNC_CURRENT_CATALOG:
case FUNC_CURRENT_DEFAULT_TRANSFORM_GROUP:
case FUNC_CURRENT_PATH:
case FUNC_CURRENT_ROLE:
case FUNC_CURRENT_SCHEMA:
case FUNC_CURRENT_TRANSFORM_GROUP_FOR_TYPE:
case FUNC_CURRENT_USER:
case FUNC_SESSION_USER:
case FUNC_SYSTEM_USER:
case FUNC_USER:
dataType = SqlInvariants.SQL_IDENTIFIER;
break;
case FUNC_VALUE:
break;
case FUNC_CURRENT_DATE:
dataType = CharacterType.SQL_DATE;
break;
case FUNC_CURRENT_TIME:
{
int precision = DateTimeType.defaultTimeFractionPrecision;
if (nodes[0] != null) {
precision = ((Integer) nodes[0].valueData).intValue();
}
dataType = DateTimeType.getDateTimeType(Types.SQL_TIME_WITH_TIME_ZONE, precision);
break;
}
case FUNC_CURRENT_TIMESTAMP:
{
// A VoltDB extension to disable TIME ZONE support
dataType = Type.SQL_TIMESTAMP;
break;
}
case FUNC_LOCALTIME:
{
int precision = DateTimeType.defaultTimeFractionPrecision;
if (nodes.length > 0 && nodes[0] != null) {
precision = ((Integer) nodes[0].valueData).intValue();
}
dataType = DateTimeType.getDateTimeType(Types.SQL_TIME, precision);
break;
}
case FUNC_LOCALTIMESTAMP:
{
int precision = DateTimeType.defaultTimestampFractionPrecision;
if (nodes[0] != null) {
precision = ((Integer) nodes[0].valueData).intValue();
}
dataType = DateTimeType.getDateTimeType(Types.SQL_TIMESTAMP, precision);
break;
}
default:
throw Error.runtimeError(ErrorCode.U_S0500, "FunctionSQL");
}
}
Aggregations