Class RelStructuredTypeFlattener

  • All Implemented Interfaces:

    public class RelStructuredTypeFlattener
    extends java.lang.Object
    implements ReflectiveVisitor
    RelStructuredTypeFlattener removes all structured types from a tree of relational expressions. Because it must operate globally on the tree, it is implemented as an explicit self-contained rewrite operation instead of via normal optimizer rules. This approach has the benefit that real optimizer and codegen rules never have to deal with structured types.

    As an example, suppose we have a structured type ST(A1 smallint, A2 bigint), a table T(c1 ST, c2 double), and a query select t.c2, t.c1.a2 from t. After SqlToRelConverter executes, the unflattened tree looks like:

     LogicalProject(C2=[$1], A2=[$0.A2])

    After flattening, the resulting tree looks like

     LogicalProject(C2=[$3], A2=[$2])
       FtrsIndexScanRel(table=[T], index=[clustered])

    The index scan produces a flattened row type (boolean, smallint, bigint, double) (the boolean is a null indicator for c1), and the projection picks out the desired attributes (omitting $0 and $1 altogether). After optimization, the projection might be pushed down into the index scan, resulting in a final tree like

     FtrsIndexScanRel(table=[T], index=[clustered], projection=[3, 2])
    • Field Detail

      • restructure

        private final boolean restructure
      • oldToNewRelMap

        private final java.util.Map<RelNode,​RelNode> oldToNewRelMap
      • currentRel

        private RelNode currentRel
      • iRestructureInput

        private int iRestructureInput
      • flattenedRootType

        private RelDataType flattenedRootType
      • restructured

        boolean restructured
    • Method Detail

      • updateRelInMap

        public void updateRelInMap​(<RelNode,​CorrelationId> mapRefRelToCorVar)
      • restructureFields

        private java.util.List<RexNode> restructureFields​(RelDataType structuredType)
        When called with old root rowType it's known that flattened root (which may become input) returns flat fields, so it simply refers flat fields by increasing index and collects them back into struct constructor expressions if necessary.
        structuredType - old root rowType or it's nested struct
        list of rex nodes, some of them may collect flattened struct's fields back into original structure to return correct type for client
      • setNewForOldRel

        protected void setNewForOldRel​(RelNode oldRel,
                                       RelNode newRel)
      • getNewForOldRel

        protected RelNode getNewForOldRel​(RelNode oldRel)
      • getNewForOldInput

        protected int getNewForOldInput​(int oldOrdinal)
        Maps the ordinal of a field pre-flattening to the ordinal of the corresponding field post-flattening.
        oldOrdinal - Pre-flattening ordinal
        Post-flattening ordinal
      • getNewFieldForOldInput

        private Ord<RelDataType> getNewFieldForOldInput​(int oldOrdinal,
                                                        int innerOrdinal)
        Finds type and new ordinal relative to new inputs by oldOrdinal and innerOrdinal indexes.
        oldOrdinal - ordinal of the field relative to old inputs
        innerOrdinal - when oldOrdinal points to struct and target field is inner field of struct, this argument should contain calculated field's ordinal within struct after flattening. Otherwise when oldOrdinal points to primitive field, this argument should be zero.
        flat type with new ordinal relative to new inputs
      • getNewInputFieldByNewOrdinal

        private RelDataTypeField getNewInputFieldByNewOrdinal​(int newOrdinal)
      • getNewFieldForOldInput

        protected Ord<RelDataType> getNewFieldForOldInput​(int oldOrdinal)
        Maps the ordinal of a field pre-flattening to the ordinal of the corresponding field post-flattening, and also returns its type.
        oldOrdinal - Pre-flattening ordinal
        Post-flattening ordinal and type
      • getNewForOldInputMapping

        private Mappings.TargetMapping getNewForOldInputMapping​(RelNode oldRel)
        Returns a mapping between old and new fields.
        oldRel - Old relational expression
        Mapping between fields of old and new
      • getPostFlatteningOrdinal

        private int getPostFlatteningOrdinal​(RelDataType preFlattenRowType,
                                             int preFlattenOrdinal)
      • postFlattenSize

        private int postFlattenSize​(RelDataType type)
      • rewriteRel

        public void rewriteRel​(Sort rel)
      • rewriteRel

        public void rewriteRel​(LogicalJoin rel)
      • rewriteRel

        public void rewriteRel​(Collect rel)
      • rewriteRel

        public void rewriteRel​(Uncollect rel)
      • rewriteRel

        public void rewriteRel​(Sample rel)
      • rewriteRel

        public void rewriteRel​(LogicalCalc rel)
      • rewriteGeneric

        public void rewriteGeneric​(RelNode rel)
      • extractName

        private java.lang.String extractName​(java.util.List<java.lang.String> fieldNames,
                                             java.lang.String prefix,
                                             int i)
      • flattenResultTypeOfRexCall

        private void flattenResultTypeOfRexCall​(RexNode newExp,
                                                java.lang.String fieldName,
                                                java.util.List<Pair<RexNode,​java.lang.String>> flattenedExps)
      • flattenNullLiteral

        private void flattenNullLiteral​(RelDataType type,
                                        java.util.List<Pair<RexNode,​java.lang.String>> flattenedExps)
      • isConstructor

        private boolean isConstructor​(RexNode rexNode)
      • rewriteRel

        public void rewriteRel​(TableScan rel)
      • rewriteRel

        public void rewriteRel​(LogicalChi rel)
      • flattenInputs

        private void flattenInputs​(java.util.List<RelDataTypeField> fieldList,
                                   RexNode prefix,
                                   java.util.List<Pair<RexNode,​java.lang.String>> flattenedExpList)
        Generates expressions that reference the flattened input fields from a given row type.
      • getNewInnerOrdinal

        private int getNewInnerOrdinal​(RexNode firstOp,
                                       java.lang.String literalString)