如何从 JDBC Adapter SchemaFactory 链接规划器?

How to chain planners from JDBC Adapter SchemaFactory?

我扩展了 JDBC 适配器并使用了一个 model.json 配置自定义模式工厂,其中包含 1 个原始模式和 2 个派生模式来添加规则并且有效,规则在规划期间在原始模式上执行,但是他们的最终结果并没有被 Volcano 规划者选为最佳选择,因为它太贵了。规则转换 RelNode 以在 2 个派生模式上执行。下面和代码中有更多详细信息。

1) 我可以告诉 Volcano planner 忽略我通过自定义 JDBC SchemaFactory 传递的 3 个模式中的 1 个吗?

我希望解析器在该 1 个原始模式上工作,但规划器永远不要在该模式(仅其他 2 个派生模式)中建议最佳(最便宜)计划。 1 个原始模式总是与其他 2 个派生模式一对一映射,因此我的规则 returns 的 RelNode 在语义上总是等价的,只是更昂贵(安全原因)。

2) 如果那行不通,我如何才能调用 HepPlanner 而不是从 model.json 中设置的 SchemaFactory 调用默认的 Volcano 规划器,因为那是我的起点?

您可以在 GitHub 上找到我的全部代码,我将其公开,以便每个人都可以比我更好地开始使用 Calcite。

这里是 link: https://github.com/igrgurina/multicloud_rewriter

Calcite 库很棒,但很难入门,因为它缺少常见任务的示例和教程。

理想情况下,我会让 HepPlanner 执行我的规则,将它们转换为使用 2 个派生模式而不是 1 个原始模式的语义等效表达式(我有一个规则可以做到这一点),然后让 Volcano planner 优化它只使用出于安全原因,2 个派生模式,不知道存在 1 个原始模式。

我还没有找到任何合理的例子来演示如何做到这一点,所以任何帮助将不胜感激(请不要 post links 到 Druid 示例或 Apache Calcite 文档网站, 我经历了他们一千次)。

我已经设法通过使用 Hook.PROGRAM 并在我的自定义程序之前执行我的规则来完成这项工作。

由于 HookCalcite 库中被标记为 for testing and debugging only,我想说这不是应该如何完成的,但目前我没有更好的办法。

这是一个带有代码示例的简短摘要:

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));
        };
    }
}

然后在SchemaFactory中使用MultiCloudHookManager,您只需调用MultiCloudHookManager.addHook()方法即可。在这种情况下,MultiCloudHookManager.PROGRAM 设置为 MultiCloudProgram,它只是执行 HepPlanner.

中的一组规则

有关详细信息,请参阅 the source code in GitHub repository

此 hack 解决方案的灵感来自 another library