Hello, The first operator that comes to mind when we are talking about empty records is a projection that projects nothing. In theory and in most database books the projection is allowed to have arity 0 but in practice I never had to use it; neither aggregate nor any other operator. In fact an aggregate with empty group keys and aggregate calls resembles a lot an empty projection.
@Konstantin how did you come with the empty aggregate? Was it also a result of trimming? If we have to make a decision now I would prefer to disallow them globally unless somebody comes up with a compelling use-case. In order to express other query languages (e.g,, datalog, conjunctive queries, etc) with the algebraic operators we may need 0-arity operators but I don't have an example readily in mind. Best, Stamatis On Thu, Apr 29, 2021 at 7:07 PM Julian Hyde <[email protected]> wrote: > > So the question is whether an empty record is a legal row type for an > aggregation node? > > As that comment indicates, we have tried to avoid empty records — that is, > a relational expression that produces a row type with zero fields — but as > you have just discovered, we have failed to go all the way. > > Mathematically, it is purer to allow empty records. SQL does not allow > them, they crop up naturally in quite a lot of corner cases, especially > after trimming fields. > > Pragmatically, I assumed that quite a lot of code was making the > assumption that records were not empty. And that empty records are > sufficiently rare that we would never be able to find all of those places > via testing. > > Is it time to decide? If we allow empty records, we should test that all > relational operators can handle them. If we ban them, then we should (say) > throw whenever someone registers a RelNode that has an empty row type. > > Julian > > > > > > On Apr 29, 2021, at 7:25 AM, 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 > > > > > > > > > >
