Regardless of which direction we go (allowing zero-field record types, or disallowing them), Konstantin has found a bug. Konstantin, can you log it, please.
On 2021/04/29 14:25:27, Konstantin Orlov <[email protected]> wrote: > Hi all. > > I faced a problem preventing certain queries being planned because > RelFieldTrimmer throws > an ArrayIndexOutOfBoundsException with message "Index -1 out of bounds for > length 0”. > > The problem is here [1]: > > // If they are asking for no fields, we can't give them what they want, > // because zero-column records are illegal. Give them the last field, > // which is unlikely to be a system field. > if (fieldsUsed.isEmpty()) { > fieldsUsed = ImmutableBitSet.range(fieldCount - 1, fieldCount); > } > > In case fieldsUsed.isEmpty we returns last field, but it is currently > possible that fieldCount=0 as well. > > After some investigation I find out that the reason is empty record derived > as row type for Aggregate. > It is possible when an aggregate has an empty group key and no aggregate > calls. > > So the question is whether an empty record is a legal row type for an > aggregation node? > > Below is a reproducer for this problem, just put it at RelFieldTrimmerTest: > > @Test void test() { > class ContextImpl implements Context { > final Object target; > > ContextImpl(Object target) { > this.target = Objects.requireNonNull(target, "target"); > } > > @Override public <T extends Object> @Nullable T unwrap(Class<T> clazz) { > if (clazz.isInstance(target)) { > return clazz.cast(target); > } > return null; > } > } > > // RelBuilder hides problem when simplifyValues=true, hence we need to > disable it > final RelBuilder builder = RelBuilder.create(config() > .context(new > ContextImpl(RelBuilder.Config.DEFAULT.withSimplifyValues(false))).build()); > > final RelNode root = > builder.scan("EMP") > .aggregate(builder.groupKey()) > .filter(builder.literal(false)) > .project(builder.literal(42)) > .build(); > > final RelFieldTrimmer fieldTrimmer = new RelFieldTrimmer(null, builder); > fieldTrimmer.trim(root); // fails with ArrayIndexOutOfBoundsException: > Index -1 out of bounds for length 0 > } > > > [1] > https://github.com/apache/calcite/blob/master/core/src/main/java/org/apache/calcite/sql2rel/RelFieldTrimmer.java#L1197 > > -- > Regards, > Konstantin Orlov > > > > >
