Search in sources :

Example 1 with DTIType

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");
    }
}
Also used : NumberType(org.hsqldb_voltpatches.types.NumberType) DTIType(org.hsqldb_voltpatches.types.DTIType) BinaryData(org.hsqldb_voltpatches.types.BinaryData)

Aggregations

BinaryData (org.hsqldb_voltpatches.types.BinaryData)1 DTIType (org.hsqldb_voltpatches.types.DTIType)1 NumberType (org.hsqldb_voltpatches.types.NumberType)1