risinglightdb / risinglight

An educational OLAP database system.
Apache License 2.0
1.59k stars 211 forks source link

explain: improve projection explain #819

Open skyzh opened 9 months ago

skyzh commented 9 months ago
> create table t1(v1 int, v2 int);
> explain select v3 from (select v1 + v1 as v3 from t1);
+--------------------------------------------------------------------------------+
| Projection { exprs: [ + { lhs: v1, rhs: v1 } ], cost: 3.4499998, rows: 3 }     |
| └── Projection { exprs: [ + { lhs: v1, rhs: v1 } ], cost: 3.3899999, rows: 3 } |
|     └── Scan { table: t1, list: [ v1 ], filter: null, cost: 3, rows: 3 }       |
+--------------------------------------------------------------------------------+

currently, if we have a query like this, the output is kind of a little bit hard to decipher, as we repeat the same expression twice in the explain format.

probably we should have something like,

> create table t1(v1 int, v2 int);
> explain select v3 from (select v1 + v1 as v3 from t1);
+--------------------------------------------------------------------------------+
| Projection { exprs: [ v3 ], cost: 3.4499998, rows: 3 }     |
| └── Projection { exprs: [ + { lhs: v1, rhs: v1 } as v3 ], cost: 3.3899999, rows: 3 } |
|     └── Scan { table: t1, list: [ v1 ], filter: null, cost: 3, rows: 3 }       |
+--------------------------------------------------------------------------------+
wangrunji0408 commented 9 months ago

The reason for the repeat is that as is eliminated at binder stage and doesn't exist in the plan. In egg-based planner, common expressions always share the same node. So I didn't introduce the as node in order not to make things complicated.

I think there are 2 possible solutions for this issue:

  1. Resolve common expressions from child nodes and assign temporary variables for them in EXPLAIN. The output would be like:
    Projection { exprs: [ $0 ] }
    └── Projection { exprs: [ + { lhs: v1, rhs: v1 } as $0 ] }
        ...
  2. Keep as variable information by introducing as node to the planner. However, this may break some optimization rules and lead to unknown behavior.
caicancai commented 9 months ago

The reason for the repeat is that as is eliminated at binder stage and doesn't exist in the plan. In egg-based planner, common expressions always share the same node. So I didn't introduce the as node in order not to make things complicated.

I think there are 2 possible solutions for this issue:

  1. Resolve common expressions from child nodes and assign temporary variables for them in EXPLAIN. The output would be like:
    Projection { exprs: [ $0 ] }
    └── Projection { exprs: [ + { lhs: v1, rhs: v1 } as $0 ] }
       ...
  2. Keep as variable information by introducing as node to the planner. However, this may break some optimization rules and lead to unknown behavior.

It looks like option 1 might be simpler