diff --git a/core/src/main/java/org/apache/druid/math/expr/Expr.java b/core/src/main/java/org/apache/druid/math/expr/Expr.java index a61a6d50717c..f277179c36ae 100644 --- a/core/src/main/java/org/apache/druid/math/expr/Expr.java +++ b/core/src/main/java/org/apache/druid/math/expr/Expr.java @@ -142,7 +142,7 @@ default String getBindingIfIdentifier() * the entire expression. Otherwise, all vectorizable expressions must produce an output type to correctly operate * with the vectorized engine. * - * Outside of the context of vectorized expressions, a return value of null can also indicate that the given type + * Outside the context of vectorized expressions, a return value of null can also indicate that the given type * information was not enough to resolve the output type, so the expression must be evaluated using default * {@link #eval} handling where types are only known after evaluation, through {@link ExprEval#type}, such as * transform expressions at ingestion time diff --git a/core/src/main/java/org/apache/druid/math/expr/Function.java b/core/src/main/java/org/apache/druid/math/expr/Function.java index cd677b29076a..9e4a241118e5 100644 --- a/core/src/main/java/org/apache/druid/math/expr/Function.java +++ b/core/src/main/java/org/apache/druid/math/expr/Function.java @@ -19,7 +19,6 @@ package org.apache.druid.math.expr; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableSet; import org.apache.druid.common.config.NullHandling; import org.apache.druid.java.util.common.DateTimes; @@ -28,8 +27,6 @@ import org.apache.druid.java.util.common.RE; import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.common.UOE; -import org.apache.druid.math.expr.Expr.InputBindingInspector; -import org.apache.druid.math.expr.Expr.ObjectBinding; import org.apache.druid.math.expr.vector.CastToTypeVectorProcessor; import org.apache.druid.math.expr.vector.ExprVectorProcessor; import org.apache.druid.math.expr.vector.VectorMathProcessors; @@ -3642,56 +3639,4 @@ protected HumanReadableBytes.UnitSystem getUnitSystem() return HumanReadableBytes.UnitSystem.DECIMAL; } } - - /** - * This function makes the current thread sleep for the given amount of seconds. - * Fractional-second delays can be specified. - * - * This function is applied per row. The actual query time can vary depending on how much parallelism is used - * for the query. As it does not provide consistent sleep time, this function should be used only for testing - * when you want to keep a certain query running during the test. - */ - @VisibleForTesting - class Sleep implements Function - { - @Override - public String name() - { - return "sleep"; - } - - @Override - public ExprEval apply(List args, ObjectBinding bindings) - { - ExprEval eval = args.get(0).eval(bindings); - try { - if (!eval.isNumericNull()) { - double seconds = eval.asDouble(); - if (seconds > 0) { - Thread.sleep((long) (seconds * 1000)); - } - } - return ExprEval.of(null); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new RuntimeException(e); - } - } - - @Override - public void validateArguments(List args) - { - if (args.size() != 1) { - throw new IAE("Function[%s] needs 1 argument", name()); - } - } - - @Nullable - @Override - public ExprType getOutputType(InputBindingInspector inspector, List args) - { - return ExprType.STRING; - } - } } diff --git a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java index 99d4753a0c53..a5a9fce54ea2 100644 --- a/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java +++ b/core/src/test/java/org/apache/druid/math/expr/FunctionTest.java @@ -783,37 +783,6 @@ public void testRepeat() assertExpr("repeat(nonexistent, 10)", null); } - @Test - public void testSleep() - { - assertExpr("sleep(1)", null); - assertExpr("sleep(0.5)", null); - assertExpr("sleep(null)", null); - assertExpr("sleep(0)", null); - assertExpr("sleep(-1)", null); - - assertTimeElapsed("sleep(1)", 1000); - assertTimeElapsed("sleep(0.5)", 500); - assertTimeElapsed("sleep(null)", 0); - assertTimeElapsed("sleep(0)", 0); - assertTimeElapsed("sleep(-1)", 0); - } - - private void assertTimeElapsed(String expression, long expectedTimeElapsedMs) - { - final long detla = 50; - final long before = System.currentTimeMillis(); - final Expr expr = Parser.parse(expression, ExprMacroTable.nil()); - expr.eval(bindings).value(); - final long after = System.currentTimeMillis(); - final long elapsed = after - before; - Assert.assertTrue( - StringUtils.format("Expected [%s], but actual elapsed was [%s]", expectedTimeElapsedMs, elapsed), - elapsed >= expectedTimeElapsedMs - && elapsed < expectedTimeElapsedMs + detla - ); - } - private void assertExpr(final String expression, @Nullable final Object expectedResult) { final Expr expr = Parser.parse(expression, ExprMacroTable.nil()); diff --git a/extensions-core/testing-tools/pom.xml b/extensions-core/testing-tools/pom.xml new file mode 100644 index 000000000000..c290baac9e0e --- /dev/null +++ b/extensions-core/testing-tools/pom.xml @@ -0,0 +1,178 @@ + + + + + 4.0.0 + + org.apache.druid.extensions + druid-testing-tools + druid-testing-tools + Tools useful for testing + + + org.apache.druid + druid + 0.22.0-SNAPSHOT + ../../pom.xml + + + + + org.apache.calcite + calcite-core + provided + + + org.apache.druid + druid-core + ${project.parent.version} + provided + + + org.apache.druid + druid-server + ${project.parent.version} + provided + + + org.apache.druid + druid-processing + ${project.parent.version} + provided + + + org.apache.druid + druid-sql + ${project.parent.version} + provided + + + com.google.guava + guava + provided + + + com.google.inject + guice + provided + + + + com.fasterxml.jackson.core + jackson-annotations + provided + + + com.fasterxml.jackson.core + jackson-core + provided + + + com.fasterxml.jackson.core + jackson-databind + provided + + + com.fasterxml.jackson.datatype + jackson-datatype-guava + provided + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + provided + + + com.fasterxml.jackson.dataformat + jackson-dataformat-smile + provided + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + provided + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-smile-provider + provided + + + com.google.code.findbugs + jsr305 + provided + + + joda-time + joda-time + provided + + + + + junit + junit + test + + + org.easymock + easymock + test + + + nl.jqno.equalsverifier + equalsverifier + test + + + org.mockito + mockito-core + + + org.apache.druid + druid-core + ${project.parent.version} + test-jar + test + + + org.apache.druid + druid-processing + ${project.parent.version} + test-jar + test + + + org.apache.druid + druid-server + ${project.parent.version} + test + test-jar + + + org.apache.druid + druid-sql + ${project.parent.version} + test-jar + test + + + + diff --git a/extensions-core/testing-tools/src/main/java/org/apache/druid/guice/SleepModule.java b/extensions-core/testing-tools/src/main/java/org/apache/druid/guice/SleepModule.java new file mode 100644 index 000000000000..ec8231981401 --- /dev/null +++ b/extensions-core/testing-tools/src/main/java/org/apache/druid/guice/SleepModule.java @@ -0,0 +1,46 @@ +/* + * 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.guice; + +import com.fasterxml.jackson.databind.Module; +import com.google.inject.Binder; +import org.apache.druid.initialization.DruidModule; +import org.apache.druid.query.expressions.SleepExprMacro; +import org.apache.druid.query.sql.SleepOperatorConversion; +import org.apache.druid.sql.guice.SqlBindings; + +import java.util.Collections; +import java.util.List; + +public class SleepModule implements DruidModule +{ + @Override + public List getJacksonModules() + { + return Collections.emptyList(); + } + + @Override + public void configure(Binder binder) + { + SqlBindings.addOperatorConversion(binder, SleepOperatorConversion.class); + ExpressionModule.addExprMacro(binder, SleepExprMacro.class); + } +} diff --git a/extensions-core/testing-tools/src/main/java/org/apache/druid/query/expressions/SleepExprMacro.java b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/expressions/SleepExprMacro.java new file mode 100644 index 000000000000..924f495efbd0 --- /dev/null +++ b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/expressions/SleepExprMacro.java @@ -0,0 +1,111 @@ +/* + * 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.query.expressions; + +import org.apache.druid.java.util.common.IAE; +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.ExprEval; +import org.apache.druid.math.expr.ExprMacroTable.BaseScalarUnivariateMacroFunctionExpr; +import org.apache.druid.math.expr.ExprMacroTable.ExprMacro; +import org.apache.druid.math.expr.ExprType; +import org.apache.druid.query.expression.ExprUtils; + +import java.util.List; + +/** + * This function makes the current thread sleep for the given amount of seconds. + * Fractional-second delays can be specified. + * + * This function is applied per row. The actual query time can vary depending on how much parallelism is used + * for the query. As it does not provide consistent sleep time, this function should be used only for testing + * when you want to keep a certain query running during the test. + */ +public class SleepExprMacro implements ExprMacro +{ + private static final String NAME = "sleep"; + + @Override + public String name() + { + return NAME; + } + + @Override + public Expr apply(List args) + { + if (args.size() != 1) { + throw new IAE(ExprUtils.createErrMsg(name(), "must have 1 argument")); + } + + Expr arg = args.get(0); + + class SleepExpr extends BaseScalarUnivariateMacroFunctionExpr + { + public SleepExpr(Expr arg) + { + super(NAME, arg); + } + + @Override + public ExprEval eval(ObjectBinding bindings) + { + ExprEval eval = arg.eval(bindings); + try { + if (!eval.isNumericNull()) { + double seconds = eval.asDouble(); // double to support fractional-second. + if (seconds > 0) { + Thread.sleep((long) (seconds * 1000)); + } + } + return ExprEval.of(null); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } + } + + @Override + public Expr visit(Shuttle shuttle) + { + Expr newArg = arg.visit(shuttle); + return shuttle.visit(new SleepExpr(newArg)); + } + + /** + * Explicitly override this method to not vectorize the sleep expression. + * If we ever want to vectorize this expression, {@link #getOutputType} should be considered to return something + * else than just null. + */ + @Override + public boolean canVectorize(InputBindingInspector inspector) + { + return false; + } + + @Override + public ExprType getOutputType(InputBindingInspector inspector) + { + return null; + } + } + return new SleepExpr(arg); + } +} diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SleepOperatorConversion.java b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java similarity index 93% rename from sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SleepOperatorConversion.java rename to extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java index de9d186efcd7..c50c051514a8 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/expression/builtin/SleepOperatorConversion.java +++ b/extensions-core/testing-tools/src/main/java/org/apache/druid/query/sql/SleepOperatorConversion.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.sql.calcite.expression.builtin; +package org.apache.druid.query.sql; import org.apache.calcite.rex.RexNode; import org.apache.calcite.sql.SqlFunction; @@ -34,7 +34,7 @@ import javax.annotation.Nullable; /** - * A SQL operator conversion for the {@link org.apache.druid.math.expr.Function.Sleep} expression. + * A SQL operator conversion for the {@link org.apache.druid.query.expressions.SleepExprMacro} expression. * The expression is currently evaluated during the query planning when the given argument is a number literal. */ public class SleepOperatorConversion implements SqlOperatorConversion diff --git a/extensions-core/testing-tools/src/main/resources/META-INF/services/org.apache.druid.initialization.DruidModule b/extensions-core/testing-tools/src/main/resources/META-INF/services/org.apache.druid.initialization.DruidModule new file mode 100644 index 000000000000..f2ddf3cf538f --- /dev/null +++ b/extensions-core/testing-tools/src/main/resources/META-INF/services/org.apache.druid.initialization.DruidModule @@ -0,0 +1,16 @@ +# 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. + +org.apache.druid.guice.SleepModule diff --git a/extensions-core/testing-tools/src/test/java/org/apache/druid/query/expressions/SleepExprTest.java b/extensions-core/testing-tools/src/test/java/org/apache/druid/query/expressions/SleepExprTest.java new file mode 100644 index 000000000000..8aa2be74a7a1 --- /dev/null +++ b/extensions-core/testing-tools/src/test/java/org/apache/druid/query/expressions/SleepExprTest.java @@ -0,0 +1,96 @@ +/* + * 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.query.expressions; + +import org.apache.druid.java.util.common.StringUtils; +import org.apache.druid.math.expr.Expr; +import org.apache.druid.math.expr.Expr.ObjectBinding; +import org.apache.druid.math.expr.ExprMacroTable; +import org.apache.druid.math.expr.Parser; +import org.apache.druid.testing.InitializedNullHandlingTest; +import org.junit.Assert; +import org.junit.Test; + +import javax.annotation.Nullable; +import java.util.Collections; + +public class SleepExprTest extends InitializedNullHandlingTest +{ + private final ObjectBinding bindings = new ObjectBinding() + { + @Nullable + @Override + public Object get(String name) + { + return null; + } + }; + + private final ExprMacroTable exprMacroTable = new ExprMacroTable(Collections.singletonList(new SleepExprMacro())); + + @Test + public void testSleep() + { + assertExpr("sleep(1)"); + assertExpr("sleep(0.5)"); + assertExpr("sleep(null)"); + assertExpr("sleep(0)"); + assertExpr("sleep(-1)"); + + assertTimeElapsed("sleep(1)", 1000); + assertTimeElapsed("sleep(0.5)", 500); + assertTimeElapsed("sleep(null)", 0); + assertTimeElapsed("sleep(0)", 0); + assertTimeElapsed("sleep(-1)", 0); + } + + private void assertTimeElapsed(String expression, long expectedTimeElapsedMs) + { + final long detla = 50; + final long before = System.currentTimeMillis(); + final Expr expr = Parser.parse(expression, exprMacroTable); + expr.eval(bindings).value(); + final long after = System.currentTimeMillis(); + final long elapsed = after - before; + Assert.assertTrue( + StringUtils.format("Expected [%s], but actual elapsed was [%s]", expectedTimeElapsedMs, elapsed), + elapsed >= expectedTimeElapsedMs + && elapsed < expectedTimeElapsedMs + detla + ); + } + + private void assertExpr(final String expression) + { + final Expr expr = Parser.parse(expression, exprMacroTable); + Assert.assertNull(expression, expr.eval(bindings).value()); + + final Expr exprNoFlatten = Parser.parse(expression, exprMacroTable, false); + final Expr roundTrip = Parser.parse(exprNoFlatten.stringify(), exprMacroTable); + Assert.assertNull(expr.stringify(), roundTrip.eval(bindings).value()); + + final Expr roundTripFlatten = Parser.parse(expr.stringify(), exprMacroTable); + Assert.assertNull(expr.stringify(), roundTripFlatten.eval(bindings).value()); + + Assert.assertEquals(expr.stringify(), roundTrip.stringify()); + Assert.assertEquals(expr.stringify(), roundTripFlatten.stringify()); + Assert.assertArrayEquals(expr.getCacheKey(), roundTrip.getCacheKey()); + Assert.assertArrayEquals(expr.getCacheKey(), roundTripFlatten.getCacheKey()); + } +} diff --git a/extensions-core/testing-tools/src/test/java/org/apache/druid/query/sql/SleepSqlTest.java b/extensions-core/testing-tools/src/test/java/org/apache/druid/query/sql/SleepSqlTest.java new file mode 100644 index 000000000000..8af1e93f1ac3 --- /dev/null +++ b/extensions-core/testing-tools/src/test/java/org/apache/druid/query/sql/SleepSqlTest.java @@ -0,0 +1,98 @@ +/* + * 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.query.sql; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import org.apache.druid.common.config.NullHandling; +import org.apache.druid.guice.ExpressionModule; +import org.apache.druid.math.expr.ExprMacroTable; +import org.apache.druid.math.expr.ExprMacroTable.ExprMacro; +import org.apache.druid.query.Druids; +import org.apache.druid.query.TableDataSource; +import org.apache.druid.query.expression.LookupExprMacro; +import org.apache.druid.query.expressions.SleepExprMacro; +import org.apache.druid.query.filter.BoundDimFilter; +import org.apache.druid.query.ordering.StringComparators; +import org.apache.druid.query.scan.ScanQuery.ResultFormat; +import org.apache.druid.segment.column.ValueType; +import org.apache.druid.segment.virtual.ExpressionVirtualColumn; +import org.apache.druid.sql.calcite.BaseCalciteQueryTest; +import org.apache.druid.sql.calcite.filtration.Filtration; +import org.apache.druid.sql.calcite.planner.DruidOperatorTable; +import org.apache.druid.sql.calcite.util.CalciteTests; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class SleepSqlTest extends BaseCalciteQueryTest +{ + @Override + public DruidOperatorTable createOperatorTable() + { + return new DruidOperatorTable( + ImmutableSet.of(), + ImmutableSet.of(new SleepOperatorConversion()) + ); + } + + @Override + public ExprMacroTable createMacroTable() + { + final List exprMacros = new ArrayList<>(); + for (Class clazz : ExpressionModule.EXPR_MACROS) { + exprMacros.add(CalciteTests.INJECTOR.getInstance(clazz)); + } + exprMacros.add(CalciteTests.INJECTOR.getInstance(LookupExprMacro.class)); + exprMacros.add(new SleepExprMacro()); + return new ExprMacroTable(exprMacros); + } + + @Test + public void testSleepFunction() throws Exception + { + testQuery( + "SELECT sleep(m1) from foo where m1 < 2.0", + ImmutableList.of( + Druids.newScanQueryBuilder() + .dataSource(new TableDataSource("foo")) + .intervals(querySegmentSpec(Filtration.eternity())) + .virtualColumns( + new ExpressionVirtualColumn( + "v0", + "sleep(\"m1\")", + ValueType.STRING, + createMacroTable() + ) + ) + .columns("v0") + .filters(new BoundDimFilter("m1", null, "2.0", null, true, null, null, StringComparators.NUMERIC)) + .resultFormat(ResultFormat.RESULT_FORMAT_COMPACTED_LIST) + .legacy(false) + .context(QUERY_CONTEXT_DEFAULT) + .build() + ), + ImmutableList.of( + new Object[]{NullHandling.replaceWithDefault() ? "" : null} + ) + ); + } +} diff --git a/pom.xml b/pom.xml index 8989b1a5124f..908abaf3e373 100644 --- a/pom.xml +++ b/pom.xml @@ -170,6 +170,7 @@ extensions-core/druid-basic-security extensions-core/google-extensions extensions-core/druid-ranger-security + extensions-core/testing-tools extensions-contrib/influx-extensions extensions-contrib/cassandra-storage diff --git a/processing/src/main/java/org/apache/druid/query/expression/ExprUtils.java b/processing/src/main/java/org/apache/druid/query/expression/ExprUtils.java index 23ef6847ec06..184ff532d14b 100644 --- a/processing/src/main/java/org/apache/druid/query/expression/ExprUtils.java +++ b/processing/src/main/java/org/apache/druid/query/expression/ExprUtils.java @@ -88,7 +88,7 @@ static PeriodGranularity toPeriodGranularity( return new PeriodGranularity(period, origin, timeZone); } - static String createErrMsg(String functionName, String msg) + public static String createErrMsg(String functionName, String msg) { String prefix = "Function[" + functionName + "] "; return prefix + msg; diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java index 40f7a5836a7b..0f52c3461418 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidOperatorTable.java @@ -97,7 +97,6 @@ import org.apache.druid.sql.calcite.expression.builtin.ReverseOperatorConversion; import org.apache.druid.sql.calcite.expression.builtin.RightOperatorConversion; import org.apache.druid.sql.calcite.expression.builtin.RoundOperatorConversion; -import org.apache.druid.sql.calcite.expression.builtin.SleepOperatorConversion; import org.apache.druid.sql.calcite.expression.builtin.StringFormatOperatorConversion; import org.apache.druid.sql.calcite.expression.builtin.StringToArrayOperatorConversion; import org.apache.druid.sql.calcite.expression.builtin.StrposOperatorConversion; @@ -169,7 +168,6 @@ public class DruidOperatorTable implements SqlOperatorTable .add(new TimeParseOperatorConversion()) .add(new TimeShiftOperatorConversion()) .add(new TimestampToMillisOperatorConversion()) - .add(new SleepOperatorConversion()) .build(); private static final List STRING_OPERATOR_CONVERSIONS = diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java index 102e2b22c35d..3afbbb7dbb54 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java @@ -18858,34 +18858,4 @@ public void testCommonVirtualExpressionWithDifferentValueType() throws Exception ImmutableList.of() ); } - - @Test - public void testSleepFunction() throws Exception - { - testQuery( - "SELECT sleep(m1) from foo where m1 < 2.0", - ImmutableList.of( - Druids.newScanQueryBuilder() - .dataSource(new TableDataSource("foo")) - .intervals(querySegmentSpec(Filtration.eternity())) - .virtualColumns( - new ExpressionVirtualColumn( - "v0", - "sleep(\"m1\")", - ValueType.STRING, - ExprMacroTable.nil() - ) - ) - .columns("v0") - .filters(new BoundDimFilter("m1", null, "2.0", null, true, null, null, StringComparators.NUMERIC)) - .resultFormat(ResultFormat.RESULT_FORMAT_COMPACTED_LIST) - .legacy(false) - .context(QUERY_CONTEXT_DEFAULT) - .build() - ), - ImmutableList.of( - new Object[]{NullHandling.replaceWithDefault() ? "" : null} - ) - ); - } }