Skip to content

[CALCITE-4597] Allow RelNodes to have an empty row type (zero fields) - #5274

Merged
xuzifu666 merged 1 commit into
apache:mainfrom
xuzifu666:calcite-4597
Oct 8, 2026
Merged

xuzifu666 merged 1 commit into
apache:mainfrom
xuzifu666:calcite-4597

Conversation

@xuzifu666

Copy link
Copy Markdown
Member


/** Adds a relational expression to the stack, checking the
* {@link Config#emptyRowTypePolicy()}. */
private void stackPush(RelNode rel,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing every stack.push call site to stackPush seems fragile. Instead, could you change final Deque<Frame> stack to final Queue<Frame> stack, and assign to it an anonymous subclass of AbstractQueue<Frame> that checks for field-less RelNodes?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion, @julianhyde done in the latest commit.

@xuzifu666

Copy link
Copy Markdown
Member Author

@julianhyde Could you help to review this pr again when you have a time, Thanks!

* {@link #build()} to pop those inputs. */
public RelBuilder push(RelNode node) {
stack.push(new Frame(node));
stack.add(new Frame(node));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changing this API seems dangerous. Why do you need to do it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was my suggestion to convert stack from an ArrayDeque to a custom queue implementation. It will allow most code to continue unchanged.

This particular line of code could and should remain stack.push(new Frame(node)).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay in handling this(I was on vacation before).
Nice catch, that was unintended. All call sites are now back to the original stack.push() / stack.pop(). FrameStackprovides those methods( delegating to a backing ArrayDeque), so no call site changes remain; the only deleted line in RelBuilder is the old field declaration. cc @mihaibudiu @julianhyde

protected final @Nullable RelOptSchema relOptSchema;
private final Deque<Frame> stack = new ArrayDeque<>();
/** Stack of relational expressions that are being built.
*

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This anonymous class is rather verbose to be in the section that declares fields. Make it a named inner class and move it towards the end of the file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, the anonymous class is now a named inner class, FrameStack, placed at the end of the file next to Frame. The check still happens in offer(), which push() delegates to.

@xuzifu666

xuzifu666 commented Oct 7, 2026 •

Copy link
Copy Markdown
Member Author

Since it was approved and all comments should had been addressed , if there no other comments I would squash and merge it in coming days.

@sonarqubecloud

sonarqubecloud Bot commented Oct 7, 2026

Copy link
Copy Markdown

@xuzifu666
xuzifu666 merged commit 6484bed into apache:main Oct 8, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants