我扩展了JDBC适配器,并使用具有1个原始模式和2个派生模式的model.json配置自定义模式工厂来添加规则,并且该规则有效,规则在计划期间已在原始模式上执行,但最终结果没有得到火山规划者选择它为最佳选择,因为它太贵了。规则将RelNode转换为可在2个派生架构上执行。下面和代码中有更多详细信息。
1)我可以告诉Volcano Planner忽略通过自定义JDBC SchemaFactory传递的3个模式中的1个吗?
我希望解析器在那个原始模式上工作,但是对于计划者来说,永远不要在那个模式(仅其他两个派生模式)中建议最佳(最便宜)的计划。 1个原始模式始终与其他2个派生模式一对一映射,因此我的规则返回的RelNode始终在语义上等效,只是价格更高(出于安全原因)。
2)如果那行不通,那我是怎么做的,我该如何从Model.json中设置的SchemaFactory中调用HepPlanner而不是默认的Volcano Planner?
您可以在GitHub上找到我的全部代码,我将其公开发布,以便每个人都能比我拥有一个更好的Calcite起点。
以下是链接:https://github.com/igrgurina/multicloud_rewriter
方解石库令人惊叹,但由于缺乏常见任务的示例和教程,因此很难进入。
理想情况下,我将让HepPlanner执行我的规则,将其转换为使用2个派生模式而不是1个原始模式的语义等效表达式(我有一个做到这一点的规则),然后让Volcano planner使用仅2个派生模式进行优化架构,出于安全原因,不知道存在1个原始架构。
我没有找到任何合理的示例来演示如何做到这一点,因此将不胜感激(请不要发布指向Druid示例或Apache Calcite文档网站的链接,我经历了1000遍)。 / p>
答案 0 :(得分:0)
通过使用Hook.PROGRAM
并在执行所有其他规则之前执行我的规则的自定义程序,我已经设法完成了这项工作。
由于Hook
在for testing and debugging only
库中被标记为Calcite
,所以我想这不是应该做的事情,但是目前我没有什么更好的选择。
以下是带有代码示例的简短摘要:
public static class MultiCloudHookManager {
private static final Program PROGRAM = new MultiCloudProgram();
private static Hook.Closeable globalProgramClosable;
public static void addHook() {
if (globalProgramClosable == null) {
globalProgramClosable = Hook.PROGRAM.add(program());
}
}
private static Consumer<Holder<Program>> program() {
return prepend(PROGRAM);
}
// this doesn't have to be in the separate program
private static Consumer<Holder<Program>> prepend(Program program) {
return (holder) -> {
if (holder == null) {
throw new IllegalStateException("No program holder");
}
Program chain = holder.get();
if (chain == null) {
chain = Programs.standard();
}
holder.set(Programs.sequence(program, chain));
};
}
}
然后在MultiCloudHookManager
中使用SchemaFactory
,您只需在其中调用MultiCloudHookManager.addHook()
方法。在这种情况下,MultiCloudHookManager.PROGRAM
设置为MultiCloudProgram
,这仅执行HepPlanner
中的一组规则。
有关详细信息,请参阅the source code in GitHub repository。
此黑客解决方案的灵感来自another library。