phoenix-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Miles Spielberg (JIRA)" <>
Subject [jira] [Commented] (PHOENIX-4871) Query parser throws exception on parameterized join
Date Wed, 29 May 2019 21:32:00 GMT


Miles Spielberg commented on PHOENIX-4871:

The failure occurs when the queryserver client attempts to read parameter metadata to determine
data types. Data types are attached to bind parameters by ExpressionCompiler.addBindParamMetaData,
and tracked in the BindManager of the current StatementContext. When ParameterMetadata is
queried on a PreparedStatement, the outermost QueryPlan is queried for its associated StatementContext
and BindManager.

When executing subqueries or join plans, a new inner StatementContext is set up and used,
and bind parameter information is being recorded in that inner StatementContext's BindManager.
The inner StatementContext is eventually discarded, and the StatementContext of the outermost
statement is never updated. So at the end of query compilation, the outermost statement may
still have bind parameters with no recorded column or datatype association.

This patch arranges for the BindManager initially allocated for the outermost StatementContext
to be used in any created child StatementContext. Any information recorded about bind parameters
during subquery or join compilation is then available to the final returned QueryPlan.

> Query parser throws exception on parameterized join
> ---------------------------------------------------
>                 Key: PHOENIX-4871
>                 URL:
>             Project: Phoenix
>          Issue Type: Bug
>    Affects Versions: 4.14.0
>         Environment: This issue exists on version 4 and I could reproduce it on current
git repo version 
>            Reporter: Mehdi Salarkia
>            Priority: Major
>         Attachments: PHOENIX-4871-repo.patch, PHOENIX-4871.master.v1.patch
>          Time Spent: 10m
>  Remaining Estimate: 0h
> When a join select statement has a parameter, Phoenix query parser fails to create query
metadata and fails this query :
> {code:java}
> SELECT "A"."a2" FROM "A" JOIN "B" ON ("A"."a1" = "B"."b1" ) WHERE "B"."b2" = ? 
> {code}
> with the following exception: 
> {code:java}
> org.apache.calcite.avatica.AvaticaSqlException: Error -1 (00000) : while preparing SQL:
SELECT "A"."a2" FROM "A" JOIN "B" ON ("A"."a1" = "B"."b1") WHERE ("B"."b2" = ?) 
> at org.apache.calcite.avatica.Helper.createException(
> at org.apache.calcite.avatica.Helper.createException(
> at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(
> at org.apache.calcite.avatica.AvaticaConnection.prepareStatement(
> at org.apache.phoenix.end2end.QueryServerBasicsIT.testParameterizedJoin(
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(
> at java.lang.reflect.Method.invoke(
> at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(
> at
> at org.junit.runners.model.FrameworkMethod.invokeExplosively(
> at org.junit.internal.runners.statements.InvokeMethod.evaluate(
> at org.junit.internal.runners.statements.RunAfters.evaluate(
> at org.junit.rules.TestWatcher$1.evaluate(
> at org.junit.rules.RunRules.evaluate(
> at org.junit.runners.ParentRunner.runLeaf(
> at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> at org.junit.runners.BlockJUnit4ClassRunner.runChild(
> at org.junit.runners.ParentRunner$
> at org.junit.runners.ParentRunner$1.schedule(
> at org.junit.runners.ParentRunner.runChildren(
> at org.junit.runners.ParentRunner.access$000(
> at org.junit.runners.ParentRunner$2.evaluate(
> at org.junit.internal.runners.statements.RunBefores.evaluate(
> at org.junit.internal.runners.statements.RunAfters.evaluate(
> at org.junit.rules.ExternalResource$1.evaluate(
> at org.junit.rules.RunRules.evaluate(
> at
> at
> at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(
> at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(
> at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(
> at com.intellij.rt.execution.junit.JUnitStarter.main(
> java.lang.RuntimeException: java.sql.SQLException: ERROR 2004 (INT05): Parameter value
unbound. Parameter at index 1 is unbound
> at org.apache.calcite.avatica.jdbc.JdbcMeta.propagate(
> at org.apache.calcite.avatica.jdbc.JdbcMeta.prepare(
> at org.apache.calcite.avatica.remote.LocalService.apply(
> at org.apache.calcite.avatica.remote.Service$PrepareRequest.accept(
> at org.apache.calcite.avatica.remote.Service$PrepareRequest.accept(
> at org.apache.calcite.avatica.remote.AbstractHandler.apply(
> at org.apache.calcite.avatica.remote.ProtobufHandler.apply(
> at org.apache.calcite.avatica.server.AvaticaProtobufHandler.handle(
> at org.eclipse.jetty.server.handler.HandlerList.handle(
> at org.eclipse.jetty.server.handler.HandlerWrapper.handle(
> at org.eclipse.jetty.server.Server.handle(
> at org.eclipse.jetty.server.HttpChannel.handle(
> at org.eclipse.jetty.server.HttpConnection.onFillable(
> at$ReadCallback.succeeded(
> at
> at$
> at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(
> at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(
> at
> at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(
> at org.eclipse.jetty.util.thread.QueuedThreadPool$
> at
> Caused by: java.sql.SQLException: ERROR 2004 (INT05): Parameter value unbound. Parameter
at index 1 is unbound
> at org.apache.phoenix.exception.SQLExceptionCode$Factory$1.newException(
> at org.apache.phoenix.exception.SQLExceptionInfo.buildException(
> at org.apache.phoenix.jdbc.PhoenixParameterMetaData.getParam(
> at org.apache.phoenix.jdbc.PhoenixParameterMetaData.isSigned(
> at org.apache.calcite.avatica.jdbc.JdbcMeta.parameters(
> at org.apache.calcite.avatica.jdbc.JdbcMeta.signature(
> at org.apache.calcite.avatica.jdbc.JdbcMeta.prepare(
> ... 20 more
> {code}
>  As a workaround you can change the order of tables. Meaning that the table that has
the condition in the where clause must appear first in the query. For the example above this
will work
> {code:java}
> SELECT "A"."a2" FROM "B" JOIN "A" ON ("A"."a1" = "B"."b1" ) WHERE "B"."b2" = ? {code}
> After debugging this it looks like the Phoenix server splits the join in two separated
queries and constructs two java.sql.Statement. The first of the two is referenced for reading
the query metadata down steam and since the column in the condition in the example above is in table
`B` rather than `A` it won't exists in the first query and later it fails with the error
> That's why changing the order of tables in the query fixes the issue.
> This issue has also been reported here: []
>   See org.apache.phoenix.compile.QueryCompiler#compileJoinQuery for details

This message was sent by Atlassian JIRA

View raw message