• Calcite RelNode和RexNode 介绍


    SQL 数据处理流程

    在这里插入图片描述

    RelNode

    RelNode 是关系表达式,主要描述处理数据的关系,比如何sort ,join,投影,过滤,扫描

    LogicalTableScan,扫描整表

    // SQL 表示
    select *
    from
    test_user
     
     // 关系表达式生成
     RelNode root = builder.scan("test_user").build();
     
     //实际生成的逻辑计划
     LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    LogicalSort 排序

    // SQL 表示
    select id,name
    from test_user
    group  by id
     
     // 关系表达式生成
     RelNode root =
            builder
                    .scan("test_user").sort(0)
                    .build();
                    
     //实际生成的逻辑计划               
    LogicalSort(sort0=[$0], dir0=[ASC])
      LogicalTableScan(table=[[test_user]])             
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    LogicalProject 投影

    // SQL 表示
    select id
    from test_user
    
     // 关系表达式生成
    RelNode root = builder.scan("test_user").project(builder.field("id")).build();
    
     //实际生成的逻辑计划
    LogicalProject(id=[$0])
      LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    LogicalFilter 过滤

    // SQL 表示
    select * from test_user where id=10
    
    // 关系表达式生成
    RelNode root = builder.scan("test_user").filter(builder.equals(builder.field(0),builder.literal(10))).build();
    
    //实际生成的逻辑计划
    LogicalFilter(condition=[=($0, 10)])
      LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    LogicalJoin 双表join

    // SQL 表示
    select * from test_user join test_address 
    on  test_user.id=test_address.id
    
    // 关系表达式生成
    RelNode root = builder.scan("test_user")        
    .scan("test_address").join(JoinRelType.INNER, builder.field("id"))    
        .build();
    
    //实际生成的逻辑计划
    LogicalJoin(condition=[$0], joinType=[inner])
      LogicalTableScan(table=[[test_user]])
      LogicalTableScan(table=[[test_address]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    LogicalMinus 差集

    // 关系表达式生成
    RelNode root = builder.scan("test_user")
            .scan("test_address").minus(true)
            .build();
       //实际生成的逻辑计划     
     LogicalMinus(all=[true])
       LogicalTableScan(table=[[test_user]])  
       LogicalTableScan(table=[[test_address]])
    LogicalMinus  交集
    
    // 关系表达式生成
    RelNode root = builder.scan("test_user")
            .scan("test_address").intersect(true)
            .build();
       //实际生成的逻辑计划     
    LogicalIntersect(all=[true])
      LogicalTableScan(table=[[test_user]])
      LogicalTableScan(table=[[test_address]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    LogicalUnion union 并集

    // SQL 表示
    select id,name from test_user
    union all 
    select id,address as name from
    test_address
    
    // 关系表达式生成
    RelNode root = builder.scan("test_user")
            .scan("test_address").union(true)
            .build();
      //实际生成的逻辑计划 
    LogicalUnion(all=[true]) 
     LogicalTableScan(table=[[test_user]]) 
     LogicalTableScan(table=[[test_address]])
            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    LogicalAggregate 分组操作

    // SQL 表示
    select 
    id,max(name)
    from
    test_user
    group by id
    
    // 关系表达式生成
    RelNode root = builder.scan("test_user").aggregate(builder.groupKey("id"), builder.max(builder.field("name")))
            .build();
            
         //实际生成的逻辑计划   
    LogicalAggregate(group=[{0}], agg#0=[MAX($1)])
      LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ReXNode

    RexNode 主要表示的对数据行的处理

    RexLiteral 常量表达式

    //SQL 表示
    select * from user where id=1
    1 就是常量
    builder.literal(10)
    
    RelNode root = builder.scan("test_user").filter(builder.equals(builder.field("id"),builder.literal(10)))
            .build();
            
    LogicalFilter(condition=[=($0, 10)])
      LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    RexInputRef 输入引用符

    //SQL 表示
    select id from test_user
    
    RelNode root = builder.scan("test_user").project(builder.field(0))
            .build();
    
    //这里builder.filed(0) 返回的就是第一个元素
    //逻辑计划
    LogicalProject(id=[$0])
      LogicalTableScan(table=[[test_user]])
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    RexCall 多个操作符构建的表达式

    select id,case name='ming' then null else name
    end  from test_user
    比如这里的
    case name='ming' then null else name
    end 
    
    RexSubQuery 子查询
    
    
    select * from test_user where id existes  (10,40)
    
    RelNode root = builder.scan("test_user").filter(builder.call(SqlStdOperatorTable.EXISTS, builder.field(0), builder.literal(10), builder.literal(40)))
            .build();
    
    LogicalFilter(condition=[EXISTS($0, 10, 40)])
      LogicalTableScan(table=[[test_user]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    参考代码

    public static Frameworks.ConfigBuilder config() {
    
        SchemaPlus schemaPlus = Frameworks.createRootSchema(true);
        schemaPlus.add("test_user", new AbstractTable() {
            @Override
            public RelDataType getRowType(RelDataTypeFactory typeFactory) {
    
                List dataTypeList = new ArrayList<>();
                RelDataType integerDataType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BIGINT), true);
    
                RelDataType stringDataType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.VARCHAR), true);
    
                dataTypeList.add(integerDataType);
                dataTypeList.add(stringDataType);
    
    
                List fieldNames = new ArrayList<>();
                fieldNames.add("id");
                fieldNames.add("name");
    
                return typeFactory.createStructType(dataTypeList, fieldNames);
            }
        });
    
    
        schemaPlus.add("test_address", new AbstractTable() {
            @Override
            public RelDataType getRowType(RelDataTypeFactory typeFactory) {
    
                List dataTypeList = new ArrayList<>();
                RelDataType integerDataType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BIGINT), true);
    
                RelDataType stringDataType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.VARCHAR), true);
    
                dataTypeList.add(integerDataType);
                dataTypeList.add(stringDataType);
    
    
                List fieldNames = new ArrayList<>();
                fieldNames.add("id");
                fieldNames.add("address");
    
                return typeFactory.createStructType(dataTypeList, fieldNames);
            }
        });
    
    
        return Frameworks.newConfigBuilder()
                .parserConfig(SqlParser.Config.DEFAULT)
                .defaultSchema(schemaPlus)
                .traitDefs((List) null)
                .programs(Programs.heuristicJoinOrder(Programs.RULE_SET, true, 2));
    }
    
    
    public static void main(String[] args) {
        RelBuilder builder = RelBuilder.create(config().build());
        RelNode root = builder.scan("test_user")
                .build();
    
        System.out.println(RelOptUtil.toString(root));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
  • 相关阅读:
    MSP430F5529时钟系统配置
    Apple 推出全球开发者资源 —— 人人能编程
    [阅读笔记20][BTX]Branch-Train-MiX: Mixing Expert LLMs into a Mixture-of-Experts LLM
    OpenAI的GPT-4.5 Turbo:意外曝光且可能在六月份推出
    Python函数与模块的精髓与高级特性
    思科C9300交换机Bundle模式转换为Install模式
    Rockdb简介
    Lambda 表达式详解
    在Rastion rose中建包并添加类
    干货——生产型企业的供应商管理系统模板
  • 原文地址:https://blog.csdn.net/qq_22222499/article/details/126908926