I don’t want to encourage people to subclass RelBuilder. It is not designed to 
be extended by subclassing.

Having said that, it seems reasonable to provide a way to find the table 
aliases.

In https://issues.apache.org/jira/browse/CALCITE-4946 I added the method 
RelBuilder.size(); I was surprised that it was necessary, but it made a few 
things easier. A method that returns an immutable list of the N table aliases 
of the N stack entries would seem to complement size().

Julian


> On Jun 20, 2024, at 3:40 PM, Ian Bertolacci 
> <ian.bertola...@workday.com.INVALID> wrote:
> 
> Hello,
> We have a class which extends RelBuilder to add some extra functionality, but 
> we are having issues with aliases being erased when popping the builder 
> stack, and there isn’t much recourse since the Frame stack is all private.
> 
> For example, this is valid:
> ```
> relBuilder.scan("T101").empty().field(1, "T101", "C0_7009")
> ```
> Because the `RelBuilder.empty` implementation copies the alias in the Frame 
> from the top of the Frame stack before the `empty` call, and uses it as the 
> name in the frame created *by* the `empty` call.
> 
> But people extending RelBuilder (us) cannot access or modify those private 
> members.
> So we have no way to replace the node at the top of the stack without  
> eliminating the alias, and making referencing that alias illegal.
> 
> For example, lets say we overrode the `empty()` method do effectively replace 
> the node that would be created by the base `empty()` implementation
> ```
> @Override
> public RelBuilder empty(){
>  super.empty();
>  // pop result from stack to maintain proper stack arrangement
>  RelNode oldEmptyNode = this.build();
>  // and make new node
>  RelNode newEmptyNode = createNewEmptyNode( oldEmptyNode );
>  // push new node on the stack
>  this.push(newEmptyNode);
> }
> ```
> By popping the stack, we erase the alias information, so calling `field` with 
> an alias after `empty`throws an exception, since after the empty call 
> (specifically the `build` call) the alias in the Frame no longer exists.
> 
> The only solution to this would be to call `.as` immediately after the `push` 
> call to restore the alias:
> ```
> @Override
> public RelBuilder empty(){
>  super.empty();
>  // get the current alias
>  String currentAlias = ???;
>  // pop result from stack to maintain proper stack arrangement
>  RelNode oldEmptyNode = this.build();
>  // and make new node
>  RelNode newEmptyNode = createNewEmptyNode( oldEmptyNode );
>  // push new node on the stack
>  this.push(newEmptyNode);
>  // re-use the alias that existed before popping the node
>  this.alias(currentAlias);
> }
> ```
> But there doesn’t seem to be an existing way to ask what the *current* alias 
> is, so that it can be used in the `.as` call.
> As it stands, it appears that it is not possible to add extension to 
> RelBuilder which either (a) cannot rely on an existing method to set-up the 
> Frame or (b) would cause the frame to be popped.
> 
> Is that correct? Or is there actually a way to see what the top Frame’s alias 
> is without modifying the core RelBuilder code?
> Thanks!
> -Ian Bertolacci

Reply via email to