Calcite Version:1.26.0
CsvTest

select "EMPNO", "JOINTIMES" from "DATE" order by "JOINTIMES"
到優化前的調用棧,
其中avatica,是calcite項目中一個獨立的子項目,用於封裝和server之間的交互,參考,http://people.apache.org/~elserj/calcite/docs/avatica_overview.html
Optimize
在prepareSql中,先調用的是Optimize,
經過優化生成的Cheapest計划,

Programs,對於優化過程的封裝,

可以看到Volcano只是program1,前面還有去關聯,trimFields的Hep優化,后面還有calcRules的Hep優化,
這個Calc算子是Project和Filter的結合,目的就是為了減少算子?

這里會觸發到EnumerableProjectToCalcRule,將project算子轉換為Calc

implement
目的是將物理算子轉換成Linq4J的expressionTree,Expression是什么意思,參考C#里面的LinQ
從而通過將ExpressionTree,bind到一個context,形成可執行代碼,最終獲取Enumerable的實現。
CalcitePrepareImpl.implement

EnumerableInterpretable

EnumerableRelImplementor
調用算子自身的implement函數,

EnumerableSort

遞歸調用child的implement,

最終調用到,EnumerableTableScan
到這implement調用棧,如前所說,目的就是調用各個算子自身的implement,實現轉換


調用getExpression,

最終調用到,tableExpression,
生成是實際是,MethodCallExpression,” Represents a call to either a static or an instance method“,
表示這里的Expression表示函數調用,后面顯示出具體的調用是什么,toString會accept一個ExpressionWriter
其可以由Expression.call生成,這里是調用BuildInMethod.Schema_Get_Table,參數是一個Expressions.constant

Result
Blocks.toBlock,把一堆Expression封裝成一個block,
implementor.result,意思要得到這個block執行的Result,
Result這里是一個封裝,包含,
PhysType,每個字段的類型和名稱
format,row的形式,這里是array,其他的還有list,row等
block,代碼段,這里原先的EnumerableTableScan,已經implement成一個Expression tree,這個tree就代表代碼段

回到EnumerableCalc,implement
第一步生成代碼,input.current,

生成moveNext,

生成Project邏輯,
{ final Object[] current = (Object[]) inputEnumerator.current(); final Object input_value = current[0]; final Object input_value0 = current[3]; return new Object[] { input_value, input_value0}; }

最后拼出一個完整的邏輯,

遞歸回到EnumerableSort,這里的邏輯也比較簡單,就是調用內置的orderBy函數。
這樣就完成了所有算子的implement。
EnumerableRelImplementor.implementRoot
繼續將上面得到block,封裝到bind函數中,並生成baz類

返回到EnumerableInterpretable.toBindable
這里就是將implement得到的class,調用getBindable,即用Janino生成class,並創建實例,

得到的Bindable是啥,
bind接口,將statement綁定到某個DataContext上,從而能執行得到Enumerable的結果。

這里最終生成的Bindable為,
實際使用時,調用bind得到Enumerable,
用這個迭代器的接口,next和current就可以真正的獲取數據,從而完成執行
public org.apache.calcite.linq4j.Enumerable bind(final org.apache.calcite.DataContext root) { final org.apache.calcite.linq4j.Enumerable _inputEnumerable = org.apache.calcite.schema.Schemas.enumerable((org.apache.calcite.schema.ScannableTable) root.getRootSchema().getSubSchema("BUG").getTable("DATE"), root); final org.apache.calcite.linq4j.AbstractEnumerable child = new org.apache.calcite.linq4j.AbstractEnumerable(){ public org.apache.calcite.linq4j.Enumerator enumerator() { return new org.apache.calcite.linq4j.Enumerator(){ public final org.apache.calcite.linq4j.Enumerator inputEnumerator = _inputEnumerable.enumerator(); public void reset() { inputEnumerator.reset(); } public boolean moveNext() { return inputEnumerator.moveNext(); } public void close() { inputEnumerator.close(); } public Object current() { final Object[] current = (Object[]) inputEnumerator.current(); final Object input_value = current[0]; final Object input_value0 = current[3]; return new Object[] { input_value, input_value0}; } }; } }; return child.orderBy(new org.apache.calcite.linq4j.function.Function1() { public Long apply(Object[] v) { return (Long) v[1]; } public Object apply(Object v) { return apply( (Object[]) v); } } , org.apache.calcite.linq4j.function.Functions.nullsComparator(false, false)); } public Class getElementType() { return java.lang.Object[].class; }
