0

我想生成 sql 使用方解石。像这样

org.apache.calcite.rel.rel2sql.RelToSqlConverterTest#testAntiJoin

final FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
       .parserConfig(SqlParser.Config.DEFAULT)
//       .defaultSchema(schema)
       .build();

final RelBuilder builder = RelBuilder.create(frameworkConfig);

final RelBuilder builder = relBuilder();
final RelNode root = builder
       .scan("DEPT")
        .scan("EMP")
        .join(
            JoinRelType.ANTI, builder.equals(
              builder.field(2, 1, "DEPTNO"),
              builder.field(2, 0, "DEPTNO")))
        .project(builder.field("DEPTNO"))
        .build();

但如果我不设置架构,则会抛出未找到的异常表。有没有办法在没有架构信息的情况下生成 sql。

目的是生成sql。只生成sql。



回复第一个答案。因为评论字符长度限制。

我的场景是商业智能。DataSource可以有很多,比如Hive、ClickHouse等。而且有很多桌子。我还需要动态删除或添加数据源。所以我认为 Calcite 不适合了解所有数据源。我还有两个问题:

  1. 如您所说,如何创建“独立式”表格对象
  2. 检查是否可以使用 SqlNode 来执行此操作。例如:
        SqlIdentifier from = new SqlIdentifier("testTable", SqlParserPos.QUOTED_ZERO);
        SqlNode[] nodes = new SqlNode[2];
        nodes[0] = new SqlIdentifier("a", SqlParserPos.QUOTED_ZERO);
        nodes[1] = SqlLiteral.createExactNumeric("1", SqlParserPos.QUOTED_ZERO);
        SqlNode where = new SqlBasicCall(SqlStdOperatorTable.EQUALS, nodes, SqlParserPos.QUOTED_ZERO);
        SqlIdentifier selectNode = new SqlIdentifier("a", SqlParserPos.QUOTED_ZERO);
        SqlSelect select = new SqlSelect(SqlParserPos.QUOTED_ZERO, SqlNodeList.EMPTY,
                new SqlNodeList(Arrays.asList(selectNode), SqlParserPos.QUOTED_ZERO),
                from,
                where,
                null,
                null,
                null,
                null,
                null,
                null,
                null);
        SqlString sqlString = select.toSqlString(CalciteSqlDialect.DEFAULT);
        System.out.println(sqlString.getSql());
4

1 回答 1

0

只有一种方法RelBuilder使用RelOptSchema: scan(String...)(及其变体Scan(Iterable<String>))。当您认为 的目的是作为目录服务时,这是有道理的RelOptSchema,将表名(或表路径,由具有目录和/或模式名称限定的表名组成)转换为RelOptTable对象。

如果您有不通过命名空间访问的“独立”表对象,那么您可以TableScan直接创建关系表达式,然后调用RelBuilder.push(RelNode)将它们添加到堆栈中。由于您从不打电话RelBuilder.scan,因此您可以RelBuilder使用 null创建RelOptSchema

但是在您的情况下,您似乎没有独立的表格对象。这对 Calcite 来说是个问题,因为它需要知道您的“EMP”表有一个名为“DEPTNO”的字段并且它的类型为INTEGER.

所以我建议您创建一个包含类型信息但不一定由真实表支持的“虚拟”模式。在 Calcite 的几个测试中使用的MockCatalogReader类是一个很好的例子。

于 2021-12-23T22:05:32.953 回答