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
> >
> >
> >
> >
>
>

Reply via email to