trinodb / trino

Official repository of Trino, the distributed SQL query engine for big data, formerly known as PrestoSQL (https://trino.io)
https://trino.io
Apache License 2.0
10.28k stars 2.96k forks source link

Cryptic error when function declaration uses Row with non-lowercase field name #3387

Open rclaude opened 4 years ago

rclaude commented 4 years ago

similar to https://github.com/prestosql/presto/issues/3374

The problem is fixed by lowercasing the row field name upperCaseField I'm not sure if the solution is to add back the support for uppercase or to add sanity check that can report a less cryptic error at plugin initialization time.

To reproduce:


import com.google.common.collect.ImmutableList;
import io.airlift.slice.Slice;
import io.prestosql.spi.PageBuilder;
import io.prestosql.spi.block.Block;
import io.prestosql.spi.block.BlockBuilder;
import io.prestosql.spi.function.ScalarFunction;
import io.prestosql.spi.function.SqlType;
import io.prestosql.spi.type.RowType;
import io.prestosql.spi.type.StandardTypes;
import static io.prestosql.spi.type.VarcharType.VARCHAR;

@ScalarFunction("case_sensitive_error")
public class CaseSensitivityRegression {
    private static final RowType ROW_TYPE = RowType.from(
            ImmutableList.of(
                    RowType.field("upperCaseField",VARCHAR)
            )
    );

    private final PageBuilder pageBuilder;

    public CaseSensitivityRegression()
    {
        pageBuilder = new PageBuilder(ImmutableList.of(ROW_TYPE));
    }

    @SqlType("row(upperCaseField varchar)")
    public Block case_sensitive_error(@SqlType(StandardTypes.VARCHAR) Slice agent) {
        BlockBuilder blockBuilder = pageBuilder.getBlockBuilder(0);
        return ROW_TYPE.getObject(blockBuilder, blockBuilder.getPositionCount() - 1);
    }
}
import io.prestosql.operator.scalar.AbstractTestFunctions;
import org.testng.annotations.BeforeClass;

import static io.prestosql.spi.type.VarcharType.VARCHAR;

public class CaseSensitivityRegressionTest extends AbstractTestFunctions {

    @BeforeClass
    public void setUp() {
        functionAssertions.installPlugin(new MyPlugin());
    }

    @org.testng.annotations.Test
    public void testParserDevice() {
        assertFunction("case_sensitive_error('').upperCaseField", VARCHAR, "something");
    }
}

Stack trace (version 330):

java.lang.IllegalArgumentException: Could not extract bound variables
    at io.prestosql.metadata.FunctionRegistry.lambda$getSpecializedFunctionKey$4(FunctionRegistry.java:745)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at io.prestosql.metadata.FunctionRegistry.getSpecializedFunctionKey(FunctionRegistry.java:745)
    at io.prestosql.metadata.FunctionRegistry.getScalarFunctionImplementation(FunctionRegistry.java:704)
    at io.prestosql.metadata.MetadataManager.getScalarFunctionImplementation(MetadataManager.java:1445)
    at io.prestosql.sql.InterpretedFunctionInvoker.invoke(InterpretedFunctionInvoker.java:55)
    at io.prestosql.sql.planner.ExpressionInterpreter$Visitor.visitFunctionCall(ExpressionInterpreter.java:934)
    at io.prestosql.sql.tree.FunctionCall.accept(FunctionCall.java:110)
    at io.prestosql.sql.tree.AstVisitor.process(AstVisitor.java:27)
    at io.prestosql.sql.planner.ExpressionInterpreter$Visitor.visitDereferenceExpression(ExpressionInterpreter.java:300)
    at io.prestosql.sql.tree.DereferenceExpression.accept(DereferenceExpression.java:52)
    at io.prestosql.sql.tree.AstVisitor.process(AstVisitor.java:27)
    at io.prestosql.sql.planner.ExpressionInterpreter.optimize(ExpressionInterpreter.java:278)
    at io.prestosql.sql.planner.iterative.rule.SimplifyExpressions.rewrite(SimplifyExpressions.java:54)
    at io.prestosql.sql.planner.iterative.rule.SimplifyExpressions.lambda$createRewrite$0(SimplifyExpressions.java:79)
    at io.prestosql.sql.planner.iterative.rule.ExpressionRewriteRuleSet$ProjectExpressionRewrite.lambda$apply$0(ExpressionRewriteRuleSet.java:125)
    at io.prestosql.sql.planner.plan.Assignments.lambda$rewrite$1(Assignments.java:108)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
    at io.prestosql.sql.planner.plan.Assignments.rewrite(Assignments.java:109)
    at io.prestosql.sql.planner.iterative.rule.ExpressionRewriteRuleSet$ProjectExpressionRewrite.apply(ExpressionRewriteRuleSet.java:125)
    at io.prestosql.sql.planner.iterative.rule.ExpressionRewriteRuleSet$ProjectExpressionRewrite.apply(ExpressionRewriteRuleSet.java:106)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.transform(IterativeOptimizer.java:165)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreNode(IterativeOptimizer.java:140)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreGroup(IterativeOptimizer.java:105)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreChildren(IterativeOptimizer.java:190)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreGroup(IterativeOptimizer.java:107)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreChildren(IterativeOptimizer.java:190)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreGroup(IterativeOptimizer.java:107)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreChildren(IterativeOptimizer.java:190)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreGroup(IterativeOptimizer.java:107)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreChildren(IterativeOptimizer.java:190)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.exploreGroup(IterativeOptimizer.java:107)
    at io.prestosql.sql.planner.iterative.IterativeOptimizer.optimize(IterativeOptimizer.java:96)
    at io.prestosql.sql.planner.LogicalPlanner.plan(LogicalPlanner.java:196)
    at io.prestosql.sql.planner.LogicalPlanner.plan(LogicalPlanner.java:185)
    at io.prestosql.testing.LocalQueryRunner.createPlan(LocalQueryRunner.java:850)
    at io.prestosql.testing.LocalQueryRunner.createPlan(LocalQueryRunner.java:802)
    at io.prestosql.testing.LocalQueryRunner.createPlan(LocalQueryRunner.java:793)
    at io.prestosql.testing.LocalQueryRunner.createPlan(LocalQueryRunner.java:788)
    at io.prestosql.testing.LocalQueryRunner.executeInternal(LocalQueryRunner.java:628)
    at io.prestosql.testing.LocalQueryRunner.lambda$executeWithPlan$3(LocalQueryRunner.java:598)
    at io.prestosql.transaction.TransactionBuilder.execute(TransactionBuilder.java:150)
    at io.prestosql.testing.LocalQueryRunner.inTransaction(LocalQueryRunner.java:610)
    at io.prestosql.testing.LocalQueryRunner.executeWithPlan(LocalQueryRunner.java:598)
    at io.prestosql.testing.LocalQueryRunner.execute(LocalQueryRunner.java:592)
    at io.prestosql.testing.LocalQueryRunner.execute(LocalQueryRunner.java:586)
    at io.prestosql.operator.scalar.FunctionAssertions.executeProjectionWithAll(FunctionAssertions.java:474)
    at io.prestosql.operator.scalar.FunctionAssertions.selectUniqueValue(FunctionAssertions.java:282)
    at io.prestosql.operator.scalar.FunctionAssertions.selectSingleValue(FunctionAssertions.java:277)
    at io.prestosql.operator.scalar.FunctionAssertions.assertFunction(FunctionAssertions.java:240)
    at io.prestosql.operator.scalar.AbstractTestFunctions.assertFunction(AbstractTestFunctions.java:90)
    at com.criteo.presto.udf.CaseSensitivityRegressionTest.testParserDevice(CaseSensitivityRegressionTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:645)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)
    at org.testng.TestRunner.privateRun(TestRunner.java:756)
    at org.testng.TestRunner.run(TestRunner.java:610)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
    at org.testng.SuiteRunner.run(SuiteRunner.java:289)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
    at org.testng.TestNG.runSuites(TestNG.java:1133)
    at org.testng.TestNG.run(TestNG.java:1104)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:141)
    at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:90)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:175)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:157)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
    at java.lang.Thread.run(Thread.java:748)
JoJoBizarreAdventure commented 3 years ago

I'm interested in this issue and want to have a try fixing it. But I wonder where should I place CaseSensitivityRegression and CaseSensitivityRegressionTest mentioned above? Please help me to start with it.

JoJoBizarreAdventure commented 3 years ago

@findepi Could you please give me some advice?

findepi commented 3 years ago

@martint please chime in here

JoJoBizarreAdventure commented 3 years ago

@findepi I wonder this should be trino or prestosql ? It seems that prestosql doesn't work. image

findepi commented 3 years ago

@JoJoBizarreAdventure yes, trino. it used to be io.prestosql package before the rebranding

JoJoBizarreAdventure commented 3 years ago

And I wonder what is this MyPlugin? @findepi Do you know something about this? image

findepi commented 3 years ago

i do not.

JoJoBizarreAdventure commented 3 years ago

@rclaude Could you show me the content about MyPlugin?

JoJoBizarreAdventure commented 3 years ago

Now, it reports that image Could you please help me register the function which is defined in CaseSensitivityRegression ? I check other Plugin in trino, but I don't really know what to do.