@Description("round down to nearest integer")
    @ScalarFunction
    @SqlType(StandardTypes.BIGINT)
    public static long floor(@SqlType(StandardTypes.BIGINT) long num)
    {
        return num;
    }
@Test
    public void testFloor()
    {
        assertFunction("floor(TINYINT'123')", TINYINT, (byte) 123);
        assertFunction("floor(TINYINT'-123')", TINYINT, (byte) -123);
        assertFunction("floor(CAST(NULL AS TINYINT))", TINYINT, null);
        assertFunction("floor(SMALLINT'123')", SMALLINT, (short) 123);
        assertFunction("floor(SMALLINT'-123')", SMALLINT, (short) -123);
        assertFunction("floor(CAST(NULL AS SMALLINT))", SMALLINT, null);
        assertFunction("floor(123)", INTEGER, 123);
        assertFunction("floor(-123)", INTEGER, -123);
        assertFunction("floor(CAST(NULL AS INTEGER))", INTEGER, null);
        assertFunction("floor(BIGINT '123')", BIGINT, 123L);
        assertFunction("floor(BIGINT '-123')", BIGINT, -123L);
        assertFunction("floor(12300000000)", BIGINT, 12300000000L);
        assertFunction("floor(-12300000000)", BIGINT, -12300000000L);
        assertFunction("floor(CAST(NULL as BIGINT))", BIGINT, null);
        assertFunction("floor(123.0E0)", DOUBLE, 123.0);
        assertFunction("floor(-123.0E0)", DOUBLE, -123.0);
        assertFunction("floor(123.45E0)", DOUBLE, 123.0);
        assertFunction("floor(-123.45E0)", DOUBLE, -124.0);

        assertFunction("floor(REAL '123.0')", REAL, 123.0f);
        assertFunction("floor(REAL '-123.0')", REAL, -123.0f);
        assertFunction("floor(REAL '123.45')", REAL, 123.0f);
        assertFunction("floor(REAL '-123.45')", REAL, -124.0f);

        // short DECIMAL -> short DECIMAL
        assertFunction("floor(DECIMAL '0')", createDecimalType(1), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '0.00' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '0.00' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '0.01' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-0.01' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '0.49' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-0.49' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '0.50' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-0.50' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '0.99' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-0.99' AS DECIMAL(3,2)))", createDecimalType(2), SqlDecimal.of("-1"));
        assertFunction("floor(DECIMAL '123')", createDecimalType(3), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123')", createDecimalType(3), SqlDecimal.of("-123"));
        assertFunction("floor(DECIMAL '123.00')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.00')", createDecimalType(4), SqlDecimal.of("-123"));
        assertFunction("floor(DECIMAL '123.01')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.01')", createDecimalType(4), SqlDecimal.of("-124"));
        assertFunction("floor(DECIMAL '123.45')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.45')", createDecimalType(4), SqlDecimal.of("-124"));
        assertFunction("floor(DECIMAL '123.49')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.49')", createDecimalType(4), SqlDecimal.of("-124"));
        assertFunction("floor(DECIMAL '123.50')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.50')", createDecimalType(4), SqlDecimal.of("-124"));
        assertFunction("floor(DECIMAL '123.99')", createDecimalType(4), SqlDecimal.of("123"));
        assertFunction("floor(DECIMAL '-123.99')", createDecimalType(4), SqlDecimal.of("-124"));
        assertFunction("floor(DECIMAL '-999.9')", createDecimalType(4), SqlDecimal.of("-1000"));

        // long DECIMAL -> long DECIMAL
        assertFunction("floor(CAST(DECIMAL '0000000000000000000' AS DECIMAL(19,0)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '000000000000000000.00' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '000000000000000000.01' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-000000000000000000.01' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '000000000000000000.49' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-000000000000000000.49' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '000000000000000000.50' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-000000000000000000.50' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("-1"));
        assertFunction("floor(CAST(DECIMAL '000000000000000000.99' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("0"));
        assertFunction("floor(CAST(DECIMAL '-000000000000000000.99' AS DECIMAL(20,2)))", createDecimalType(19), SqlDecimal.of("-1"));
        assertFunction("floor(DECIMAL '123456789012345678')", createDecimalType(18), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678')", createDecimalType(18), SqlDecimal.of("-123456789012345678"));
        assertFunction("floor(DECIMAL '123456789012345678.00')", createDecimalType(19), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678.00')", createDecimalType(19), SqlDecimal.of("-123456789012345678"));
        assertFunction("floor(DECIMAL '123456789012345678.01')", createDecimalType(19), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678.01')", createDecimalType(19), SqlDecimal.of("-123456789012345679"));
        assertFunction("floor(DECIMAL '123456789012345678.99')", createDecimalType(19), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678.49')", createDecimalType(19), SqlDecimal.of("-123456789012345679"));
        assertFunction("floor(DECIMAL '123456789012345678.49')", createDecimalType(19), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678.50')", createDecimalType(19), SqlDecimal.of("-123456789012345679"));
        assertFunction("floor(DECIMAL '123456789012345678.50')", createDecimalType(19), SqlDecimal.of("123456789012345678"));
        assertFunction("floor(DECIMAL '-123456789012345678.99')", createDecimalType(19), SqlDecimal.of("-123456789012345679"));
        assertFunction("floor(DECIMAL '-999999999999999999.9')", createDecimalType(19), SqlDecimal.of("-1000000000000000000"));

        // long DECIMAL -> short DECIMAL
        assertFunction("floor(DECIMAL '1234567890123456.78')", createDecimalType(17), SqlDecimal.of("1234567890123456"));
        assertFunction("floor(DECIMAL '-1234567890123456.78')", createDecimalType(17), SqlDecimal.of("-1234567890123457"));

        assertFunction("floor(CAST(NULL as REAL))", REAL, null);
        assertFunction("floor(CAST(NULL as DOUBLE))", DOUBLE, null);
        assertFunction("floor(CAST(NULL as DECIMAL(1,0)))", createDecimalType(1), null);
        assertFunction("floor(CAST(NULL as DECIMAL(25,5)))", createDecimalType(21), null);
    }