Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2 #14805

Closed
YuanchengJiang opened this issue Oct 5, 2023 · 2 comments
Assignees
Labels
bug Clear identification of incorrect behaviour

Comments

@YuanchengJiang
Copy link

CrateDB version

5.4.3

CrateDB setup information

Use the system dataset: sys.summits

Problem description

Out of bound:

SQLParseException[Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2:
GroupHashAggregate["collection_count(collect_set(country))", "collection_count(collect_set(mountain))", "collection_count(collect_set(country))"] (rows=2)
  └ Union["collection_count(collect_set(country))", "collection_count(collect_set(mountain))"] (rows=2)
    ├ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
    │  └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
    │    └ NestedLoopJoin[CROSS] (rows=unknown)
    │      ├ NestedLoopJoin[INNER | (country > country)] (rows=unknown)
    │      │  ├ Rename[country] AS t1 (rows=unknown)
    │      │  │  └ Collect[sys.summits | [country] | true] (rows=unknown)
    │      │  └ Rename[mountain, country] AS t2 (rows=unknown)
    │      │    └ Collect[sys.summits | [mountain, country] | true] (rows=unknown)
    │      └ Rename[country] AS t3 (rows=unknown)
    │        └ Collect[sys.summits | [country] | true] (rows=unknown)
    └ Eval[collection_count(collect_set(country)), collection_count(collect_set(mountain))] (rows=1)
      └ HashAggregate[collect_set(country), collect_set(mountain)] (rows=1)
        └ NestedLoopJoin[CROSS] (rows=unknown)
          ├ NestedLoopJoin[INNER | (mountain > mountain)] (rows=unknown)
          │  ├ Rename[mountain] AS t2 (rows=unknown)
          │  │  └ Collect[sys.summits | [mountain] | true] (rows=unknown)
          │  └ Rename[mountain] AS t3 (rows=unknown)
          │    └ Collect[sys.summits | [mountain] | true] (rows=unknown)
          └ Rename[country] AS t1 (rows=unknown)
            └ Collect[sys.summits | [country] | true] (rows=unknown)]

Steps to Reproduce

Run:

SELECT DISTINCT count (distinct T1.country), count (distinct T2.mountain), count (distinct T3.country) FROM sys.summits as T1 INNER JOIN sys.summits as T2 ON T1.country>T2.country CROSS JOIN sys.summits as T3 UNION SELECT DISTINCT count (distinct T1.country), count (distinct T2.mountain), count (distinct T3.country) FROM sys.summits as T1 CROSS JOIN sys.summits as T2 JOIN sys.summits as T3 ON T2.mountain>T3.mountain

Actual Result

SQLParseException[Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2:
GroupHashAggregate["collection_count(collect_set(country))", "collection_count(collect_set(mountain))", "collection_count(collect_set(country))"] (rows=2)
  └ Union["collection_count(collect_set(country))", "collection_count(collect_set(mountain))"] (rows=2)
    ├ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
    │  └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
    │    └ NestedLoopJoin[CROSS] (rows=unknown)
    │      ├ NestedLoopJoin[INNER | (country > country)] (rows=unknown)
    │      │  ├ Rename[country] AS t1 (rows=unknown)
    │      │  │  └ Collect[sys.summits | [country] | true] (rows=unknown)
    │      │  └ Rename[mountain, country] AS t2 (rows=unknown)
    │      │    └ Collect[sys.summits | [mountain, country] | true] (rows=unknown)
    │      └ Rename[country] AS t3 (rows=unknown)
    │        └ Collect[sys.summits | [country] | true] (rows=unknown)
    └ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
      └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
        └ NestedLoopJoin[CROSS] (rows=unknown)
          ├ NestedLoopJoin[INNER | (mountain > mountain)] (rows=unknown)
          │  ├ Rename[mountain] AS t2 (rows=unknown)
          │  │  └ Collect[sys.summits | [mountain] | true] (rows=unknown)
          │  └ Rename[country, mountain] AS t3 (rows=unknown)
          │    └ Collect[sys.summits | [country, mountain] | true] (rows=unknown)
          └ Rename[country] AS t1 (rows=unknown)
            └ Collect[sys.summits | [country] | true] (rows=unknown)]

io.crate.exceptions.SQLParseException: Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2:
GroupHashAggregate["collection_count(collect_set(country))", "collection_count(collect_set(mountain))", "collection_count(collect_set(country))"] (rows=2)
  └ Union["collection_count(collect_set(country))", "collection_count(collect_set(mountain))"] (rows=2)
    ├ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
    │  └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
    │    └ NestedLoopJoin[CROSS] (rows=unknown)
    │      ├ NestedLoopJoin[INNER | (country > country)] (rows=unknown)
    │      │  ├ Rename[country] AS t1 (rows=unknown)
    │      │  │  └ Collect[sys.summits | [country] | true] (rows=unknown)
    │      │  └ Rename[mountain, country] AS t2 (rows=unknown)
    │      │    └ Collect[sys.summits | [mountain, country] | true] (rows=unknown)
    │      └ Rename[country] AS t3 (rows=unknown)
    │        └ Collect[sys.summits | [country] | true] (rows=unknown)
    └ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
      └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
        └ NestedLoopJoin[CROSS] (rows=unknown)
          ├ NestedLoopJoin[INNER | (mountain > mountain)] (rows=unknown)
          │  ├ Rename[mountain] AS t2 (rows=unknown)
          │  │  └ Collect[sys.summits | [mountain] | true] (rows=unknown)
          │  └ Rename[country, mountain] AS t3 (rows=unknown)
          │    └ Collect[sys.summits | [country, mountain] | true] (rows=unknown)
          └ Rename[country] AS t1 (rows=unknown)
            └ Collect[sys.summits | [country] | true] (rows=unknown)
	at io.crate.exceptions.SQLExceptions.esToCrateException(SQLExceptions.java:163)
	at io.crate.exceptions.SQLExceptions.prepareForClientTransmission(SQLExceptions.java:152)
	at io.crate.rest.action.SqlHttpHandler.sendResponse(SqlHttpHandler.java:163)
	at io.crate.rest.action.SqlHttpHandler.lambda$channelRead0$0(SqlHttpHandler.java:119)
	at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
	at java.base/java.util.concurrent.CompletableFuture.uniWhenCompleteStage(CompletableFuture.java:887)
	at java.base/java.util.concurrent.CompletableFuture.whenComplete(CompletableFuture.java:2357)
	at io.crate.rest.action.SqlHttpHandler.channelRead0(SqlHttpHandler.java:117)
	at io.crate.rest.action.SqlHttpHandler.channelRead0(SqlHttpHandler.java:81)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.crate.protocols.http.HttpBlobHandler.channelRead0(HttpBlobHandler.java:166)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.crate.auth.HttpAuthUpstreamHandler.handleHttpChunk(HttpAuthUpstreamHandler.java:135)
	at io.crate.auth.HttpAuthUpstreamHandler.channelRead0(HttpAuthUpstreamHandler.java:84)
	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at java.base/java.lang.Thread.run(Thread.java:1623)
Caused by: java.lang.IllegalArgumentException: Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2:
GroupHashAggregate["collection_count(collect_set(country))", "collection_count(collect_set(mountain))", "collection_count(collect_set(country))"] (rows=2)
  └ Union["collection_count(collect_set(country))", "collection_count(collect_set(mountain))"] (rows=2)
    ├ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
    │  └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
    │    └ NestedLoopJoin[CROSS] (rows=unknown)
    │      ├ NestedLoopJoin[INNER | (country > country)] (rows=unknown)
    │      │  ├ Rename[country] AS t1 (rows=unknown)
    │      │  │  └ Collect[sys.summits | [country] | true] (rows=unknown)
    │      │  └ Rename[mountain, country] AS t2 (rows=unknown)
    │      │    └ Collect[sys.summits | [mountain, country] | true] (rows=unknown)
    │      └ Rename[country] AS t3 (rows=unknown)
    │        └ Collect[sys.summits | [country] | true] (rows=unknown)
    └ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
      └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
        └ NestedLoopJoin[CROSS] (rows=unknown)
          ├ NestedLoopJoin[INNER | (mountain > mountain)] (rows=unknown)
          │  ├ Rename[mountain] AS t2 (rows=unknown)
          │  │  └ Collect[sys.summits | [mountain] | true] (rows=unknown)
          │  └ Rename[country, mountain] AS t3 (rows=unknown)
          │    └ Collect[sys.summits | [country, mountain] | true] (rows=unknown)
          └ Rename[country] AS t1 (rows=unknown)
            └ Collect[sys.summits | [country] | true] (rows=unknown)
	at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
	at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
	at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
	at java.base/java.util.Objects.checkIndex(Objects.java:385)
	at java.base/java.util.ArrayList.get(ArrayList.java:427)
	at io.crate.common.collections.Lists2$LazyMapList.get(Lists2.java:338)
	at io.crate.execution.dsl.projection.EvalProjection.castValues(EvalProjection.java:60)
	at io.crate.planner.operators.Union.addCastsForIncompatibleObjects(Union.java:174)
	at io.crate.planner.operators.Union.build(Union.java:103)
	at io.crate.planner.operators.GroupHashAggregate.build(GroupHashAggregate.java:146)
	at io.crate.planner.operators.RootRelationBoundary.build(RootRelationBoundary.java:60)
	at io.crate.planner.operators.LogicalPlanner.getNodeOperationTree(LogicalPlanner.java:552)
	at io.crate.planner.operators.LogicalPlanner.doExecute(LogicalPlanner.java:531)
	at io.crate.planner.operators.LogicalPlanner.execute(LogicalPlanner.java:509)
	at io.crate.planner.operators.LogicalPlan.executeOrFail(LogicalPlan.java:213)
	at io.crate.planner.Plan.execute(Plan.java:73)
	at io.crate.action.sql.Session.singleExec(Session.java:795)
	at io.crate.action.sql.Session.execute(Session.java:552)
	at io.crate.rest.action.SqlHttpHandler.executeSimpleRequest(SqlHttpHandler.java:260)
	at io.crate.rest.action.SqlHttpHandler.handleSQLRequest(SqlHttpHandler.java:207)
	at io.crate.rest.action.SqlHttpHandler.channelRead0(SqlHttpHandler.java:116)
	... 45 more
Caused by: java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 2
	... 66 more

Expected Result

The valid query should return results.

@YuanchengJiang YuanchengJiang added the triage An issue that needs to be triaged by a maintainer label Oct 5, 2023
@jeeminso
Copy link
Contributor

jeeminso commented Oct 8, 2023

Thanks again for reporting @YuanchengJiang . Similar to #14807, this could be workaround by providing column aliases:

-- create a mini summits table
cr> create table summits as (select * from sys.summits limit 10);                                                                                
CREATE OK, 10 rows affected  (1.702 sec)

-- reproducible:
cr> SELECT DISTINCT count (distinct T1.country), count (distinct T2.mountain), count (distinct T3.country) FROM summits as T1 INNER JOIN summits a
    s T2 ON T1.country>T2.country CROSS JOIN summits as T3 UNION SELECT DISTINCT count (distinct T1.country), count (distinct T2.mountain), count 
    (distinct T3.country) FROM summits as T1 CROSS JOIN summits as T2 JOIN summits as T3 ON T2.mountain>T3.mountain;                              
SQLParseException[Couldn't create execution plan from logical plan because of: Index 2 out of bounds for length 2:
GroupHashAggregate["collection_count(collect_set(country))", "collection_count(collect_set(mountain))", "collection_count(collect_set(country))"] (rows=2)
  └ Union["collection_count(collect_set(country))", "collection_count(collect_set(mountain))"] (rows=2)
    ├ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
    │  └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
    │    └ NestedLoopJoin[CROSS] (rows=unknown)
    │      ├ NestedLoopJoin[INNER | (country > country)] (rows=unknown)
    │      │  ├ Rename[country] AS t1 (rows=unknown)
    │      │  │  └ Collect[doc.summits | [country] | true] (rows=unknown)
    │      │  └ Rename[mountain, country] AS t2 (rows=unknown)
    │      │    └ Collect[doc.summits | [mountain, country] | true] (rows=unknown)
    │      └ Rename[country] AS t3 (rows=unknown)
    │        └ Collect[doc.summits | [country] | true] (rows=unknown)
    └ GroupHashAggregate[collection_count(collect_set(country)), collection_count(collect_set(mountain)), collection_count(collect_set(country))] (rows=1)
      └ HashAggregate[collect_set(country), collect_set(mountain), collect_set(country)] (rows=1)
        └ NestedLoopJoin[CROSS] (rows=unknown)
          ├ NestedLoopJoin[INNER | (mountain > mountain)] (rows=unknown)
          │  ├ Rename[mountain] AS t2 (rows=unknown)
          │  │  └ Collect[doc.summits | [mountain] | true] (rows=unknown)
          │  └ Rename[country, mountain] AS t3 (rows=unknown)
          │    └ Collect[doc.summits | [country, mountain] | true] (rows=unknown)
          └ Rename[country] AS t1 (rows=unknown)
            └ Collect[doc.summits | [country] | true] (rows=unknown)]
            
-- column aliases prevent the exception:
cr> SELECT DISTINCT count (distinct T1.country) x, count (distinct T2.mountain) y, count (distinct T3.country) z FROM summits as T1 INNER JOIN sum
    mits as T2 ON T1.country>T2.country CROSS JOIN summits as T3 UNION SELECT DISTINCT count (distinct T1.country), count (distinct T2.mountain), 
    count (distinct T3.country) FROM summits as T1 CROSS JOIN summits as T2 JOIN summits as T3 ON T2.mountain>T3.mountain;                        
+---+---+---+
| x | y | z |
+---+---+---+
| 2 | 9 | 3 |
| 3 | 9 | 3 |
+---+---+---+
SELECT 2 rows in set (0.045 sec)

@jeeminso jeeminso added bug Clear identification of incorrect behaviour and removed triage An issue that needs to be triaged by a maintainer labels Oct 8, 2023
@jeeminso jeeminso self-assigned this Oct 9, 2023
@seut
Copy link
Member

seut commented Oct 26, 2023

@YuanchengJiang
The issue has been fixed by #14816 and will be released with the next 5.4.5 hotfix release.
Thank you for reporting.

@seut seut closed this as completed Oct 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Clear identification of incorrect behaviour
Projects
None yet
Development

No branches or pull requests

3 participants