blob: 58278232ddd4e996c07370230be2ef4e8fa445c1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.druid.sql.calcite.expression;
import com.google.common.collect.ImmutableMap;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlIntervalQualifier;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.segment.column.RowSignature;
import org.apache.druid.segment.column.ValueType;
import org.apache.druid.sql.calcite.expression.builtin.GreatestOperatorConversion;
import org.junit.Before;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class GreatestExpressionTest extends ExpressionTestBase
{
private static final String DOUBLE_KEY = "d";
private static final double DOUBLE_VALUE = 3.1;
private static final String LONG_KEY = "l";
private static final long LONG_VALUE = 2L;
private static final String STRING_KEY = "s";
private static final String STRING_VALUE = "foo";
private static final RowSignature ROW_SIGNATURE = RowSignature
.builder()
.add(DOUBLE_KEY, ValueType.DOUBLE)
.add(LONG_KEY, ValueType.LONG)
.add(STRING_KEY, ValueType.STRING)
.build();
private static final Map<String, Object> BINDINGS = ImmutableMap.of(
DOUBLE_KEY, DOUBLE_VALUE,
LONG_KEY, LONG_VALUE,
STRING_KEY, STRING_VALUE
);
private GreatestOperatorConversion target;
private ExpressionTestHelper testHelper;
@Before
public void setUp()
{
target = new GreatestOperatorConversion();
testHelper = new ExpressionTestHelper(ROW_SIGNATURE, BINDINGS);
}
@Test
public void testNoArgs()
{
testExpression(
Collections.emptyList(),
buildExpectedExpression(),
null
);
}
@Test
public void testAllNull()
{
testExpression(
Arrays.asList(
testHelper.getConstantNull(),
testHelper.getConstantNull()
),
buildExpectedExpression(null, null),
null
);
}
@Test
public void testSomeNull()
{
testExpression(
Arrays.asList(
testHelper.makeInputRef(DOUBLE_KEY),
testHelper.getConstantNull(),
testHelper.makeInputRef(STRING_KEY)
),
buildExpectedExpression(
testHelper.makeVariable(DOUBLE_KEY),
null,
testHelper.makeVariable(STRING_KEY)
),
STRING_VALUE
);
}
@Test
public void testAllDouble()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(34.1),
testHelper.makeInputRef(DOUBLE_KEY),
testHelper.makeLiteral(5.2),
testHelper.makeLiteral(767.3)
),
buildExpectedExpression(
34.1,
testHelper.makeVariable(DOUBLE_KEY),
5.2,
767.3
),
767.3
);
}
@Test
public void testAllLong()
{
testExpression(
Arrays.asList(
testHelper.makeInputRef(LONG_KEY),
testHelper.makeLiteral(0)
),
buildExpectedExpression(
testHelper.makeVariable(LONG_KEY),
0
),
LONG_VALUE
);
}
@Test
public void testAllString()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral("B"),
testHelper.makeInputRef(STRING_KEY),
testHelper.makeLiteral("A")
),
buildExpectedExpression(
"B",
testHelper.makeVariable(STRING_KEY),
"A"
),
STRING_VALUE
);
}
@Test
public void testCoerceString()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(-1),
testHelper.makeInputRef(DOUBLE_KEY),
testHelper.makeLiteral("A")
),
buildExpectedExpression(
-1,
testHelper.makeVariable(DOUBLE_KEY),
"A"
),
"A"
);
}
@Test
public void testCoerceDouble()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(-1),
testHelper.makeInputRef(DOUBLE_KEY)
),
buildExpectedExpression(
-1,
testHelper.makeVariable(DOUBLE_KEY)
),
DOUBLE_VALUE
);
}
@Test
public void testDecimal()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(BigDecimal.valueOf(1.2)),
testHelper.makeLiteral(BigDecimal.valueOf(3.4))
),
buildExpectedExpression(
1.2,
3.4
),
3.4
);
}
@Test
public void testDecimalWithNullShouldReturnString()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(BigDecimal.valueOf(1.2)),
testHelper.getConstantNull(),
testHelper.makeLiteral(BigDecimal.valueOf(3.4))
),
buildExpectedExpression(
1.2,
null,
3.4
),
"3.4"
);
}
@Test
public void testTimestamp()
{
testExpression(
Arrays.asList(
testHelper.makeLiteral(DateTimes.utc(1000)),
testHelper.makeLiteral(DateTimes.utc(2000))
),
buildExpectedExpression(
1000,
2000
),
2000L
);
}
@Test
public void testInvalidType()
{
expectException(IllegalArgumentException.class, "Argument 0 has invalid type: INTERVAL_YEAR_MONTH");
testExpression(
Collections.singletonList(
testHelper.makeLiteral(
new BigDecimal(13), // YEAR-MONTH literals value is months
new SqlIntervalQualifier(TimeUnit.YEAR, TimeUnit.MONTH, SqlParserPos.ZERO)
)
),
null,
null
);
}
private void testExpression(
List<? extends RexNode> exprs,
final DruidExpression expectedExpression,
final Object expectedResult
)
{
testHelper.testExpression(target.calciteOperator(), exprs, expectedExpression, expectedResult);
}
private DruidExpression buildExpectedExpression(Object... args)
{
return testHelper.buildExpectedExpression(target.getDruidFunctionName(), args);
}
}