protected IAType getResultType()

in asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericAddSubMulDivTypeComputer.java [60:392]


    protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
        IAType t1 = strippedInputTypes[0];
        IAType t2 = strippedInputTypes[1];
        ATypeTag tag1 = t1.getTypeTag();
        ATypeTag tag2 = t2.getTypeTag();

        IAType type;
        switch (tag1) {
            case DOUBLE:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                    case BIGINT:
                    case FLOAT:
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case FLOAT:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                    case BIGINT:
                    case FLOAT:
                        type = BuiltinType.AFLOAT;
                        break;
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case BIGINT:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                    case BIGINT:
                        type = BuiltinType.AINT64;
                        break;
                    case FLOAT:
                        type = BuiltinType.AFLOAT;
                        break;
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case INTEGER:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                        type = BuiltinType.AINT32;
                        break;
                    case BIGINT:
                        type = BuiltinType.AINT64;
                        break;
                    case FLOAT:
                        type = BuiltinType.AFLOAT;
                        break;
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case SMALLINT:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                        type = BuiltinType.AINT16;
                        break;
                    case INTEGER:
                        type = BuiltinType.AINT32;
                        break;
                    case BIGINT:
                        type = BuiltinType.AINT64;
                        break;
                    case FLOAT:
                        type = BuiltinType.AFLOAT;
                        break;
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case TINYINT:
                switch (tag2) {
                    case TINYINT:
                        type = BuiltinType.AINT8;
                        break;
                    case SMALLINT:
                        type = BuiltinType.AINT16;
                        break;
                    case INTEGER:
                        type = BuiltinType.AINT32;
                        break;
                    case BIGINT:
                        type = BuiltinType.AINT64;
                        break;
                    case FLOAT:
                        type = BuiltinType.AFLOAT;
                        break;
                    case DOUBLE:
                        type = BuiltinType.ADOUBLE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case ANY:
                switch (tag2) {
                    case TINYINT:
                    case SMALLINT:
                    case INTEGER:
                    case BIGINT:
                    case FLOAT:
                    case DOUBLE:
                    case DATE:
                    case TIME:
                    case DATETIME:
                    case DURATION:
                    case YEARMONTHDURATION:
                    case DAYTIMEDURATION:
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case DATE:
                switch (tag2) {
                    case DATE:
                        if (!isSameTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADURATION;
                        break;
                    case YEARMONTHDURATION:
                    case DAYTIMEDURATION:
                    case DURATION:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATE;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case TIME:
                switch (tag2) {
                    case TIME:
                        if (!isSameTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADURATION;
                        break;
                    case YEARMONTHDURATION:
                        return BuiltinType.ANULL;
                    case DAYTIMEDURATION:
                    case DURATION:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        // TODO(ali): check the runtime consistency of DURATION op TIME vs. TIME op DURATION
                        type = BuiltinType.ATIME;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case DATETIME:
                switch (tag2) {
                    case DATETIME:
                        if (!isSameTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADURATION;
                        break;
                    case YEARMONTHDURATION:
                    case DAYTIMEDURATION:
                    case DURATION:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATETIME;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case DURATION:
                switch (tag2) {
                    case DATE:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATE;
                        break;
                    case TIME:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        // TODO(ali): check the runtime consistency of DURATION op TIME and TIME op DURATION
                        // depending on the runtime values the operation might be invalid and produce NULL
                        type = AUnionType.createNullableType(BuiltinType.ATIME);
                        break;
                    case DATETIME:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATETIME;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case YEARMONTHDURATION:
                switch (tag2) {
                    case DATE:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATE;
                        break;
                    case TIME:
                        return BuiltinType.ANULL;
                    case DATETIME:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATETIME;
                        break;
                    case YEARMONTHDURATION:
                        if (!isSameTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.AYEARMONTHDURATION;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            case DAYTIMEDURATION:
                switch (tag2) {
                    case DATE:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATE;
                        break;
                    case TIME:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ATIME;
                        break;
                    case DATETIME:
                        if (!isMixedTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADATETIME;
                        break;
                    case DAYTIMEDURATION:
                        if (!isSameTemporalAllowed) {
                            return BuiltinType.ANULL;
                        }
                        type = BuiltinType.ADAYTIMEDURATION;
                        break;
                    case ANY:
                        type = BuiltinType.ANY;
                        break;
                    default:
                        return BuiltinType.ANULL;
                }
                break;
            default:
                return BuiltinType.ANULL;
        }

        if (nullable && type.getTypeTag() != ATypeTag.ANY) {
            type = AUnionType.createNullableType(type);
        }

        return type;
    }