Class SqlToRelConverter

    • Field Detail

      • SQL2REL_LOGGER

        protected static final org.slf4j.Logger SQL2REL_LOGGER
      • TWO

        private static final java.math.BigDecimal TWO
      • DEFAULT_IN_SUB_QUERY_THRESHOLD

        public static final int DEFAULT_IN_SUB_QUERY_THRESHOLD
        Size of the smallest IN list that will be converted to a semijoin to a static table.
        See Also:
        Constant Field Values
      • DEFAULT_IN_SUBQUERY_THRESHOLD

        @Deprecated
        public static final int DEFAULT_IN_SUBQUERY_THRESHOLD
        Deprecated.
        See Also:
        Constant Field Values
      • rexBuilder

        protected final RexBuilder rexBuilder
      • leaves

        protected final java.util.List<RelNode> leaves
      • dynamicParamSqlNodes

        private final java.util.List<SqlDynamicParam> dynamicParamSqlNodes
      • explainParamCount

        private int explainParamCount
      • datasetStack

        private final java.util.Deque<java.lang.String> datasetStack
        Stack of names of datasets requested by the TABLE(SAMPLE(<datasetName>, <query>)) construct.
      • mapConvertedNonCorrSubqs

        private final java.util.Map<SqlNode,​RexNode> mapConvertedNonCorrSubqs
        Mapping of non-correlated sub-queries that have been converted to their equivalent constants. Used to avoid re-evaluating the sub-query if it's already been evaluated.
    • Method Detail

      • getCluster

        public RelOptCluster getCluster()
        Returns:
        the RelOptCluster in use.
      • getRexBuilder

        public RexBuilder getRexBuilder()
        Returns the row-expression builder.
      • getDynamicParamType

        public RelDataType getDynamicParamType​(int index)
        Returns the type inferred for a dynamic parameter.
        Parameters:
        index - 0-based index of dynamic parameter
        Returns:
        inferred type, never null
      • getDynamicParamCountInExplain

        public int getDynamicParamCountInExplain​(boolean increment)
        Returns the current count of the number of dynamic parameters in an EXPLAIN PLAN statement.
        Parameters:
        increment - if true, increment the count
        Returns:
        the current count before the optional increment
      • getMapConvertedNonCorrSubqs

        public java.util.Map<SqlNode,​RexNode> getMapConvertedNonCorrSubqs()
        Returns:
        mapping of non-correlated sub-queries that have been converted to the constants that they evaluate to
      • addConvertedNonCorrSubqs

        public void addConvertedNonCorrSubqs​(java.util.Map<SqlNode,​RexNode> alreadyConvertedNonCorrSubqs)
        Adds to the current map of non-correlated converted sub-queries the elements from another map that contains non-correlated sub-queries that have been converted by another SqlToRelConverter.
        Parameters:
        alreadyConvertedNonCorrSubqs - the other map
      • setSubQueryConverter

        public void setSubQueryConverter​(SubQueryConverter converter)
        Sets a new SubQueryConverter. To have any effect, this must be called before any convert method.
        Parameters:
        converter - new SubQueryConverter
      • setDynamicParamCountInExplain

        public void setDynamicParamCountInExplain​(int explainParamCount)
        Sets the number of dynamic parameters in the current EXPLAIN PLAN statement.
        Parameters:
        explainParamCount - number of dynamic parameters in the statement
      • checkConvertedType

        private void checkConvertedType​(SqlNode query,
                                        RelNode result)
      • flattenTypes

        public RelNode flattenTypes​(RelNode rootRel,
                                    boolean restructure)
      • decorrelate

        public RelNode decorrelate​(SqlNode query,
                                   RelNode rootRel)
        If sub-query is correlated and decorrelation is enabled, performs decorrelation.
        Parameters:
        query - Query
        rootRel - Root relational expression
        Returns:
        New root relational expression after decorrelation
      • trimUnusedFields

        public RelNode trimUnusedFields​(boolean ordered,
                                        RelNode rootRel)
        Walks over a tree of relational expressions, replacing each RelNode with a 'slimmed down' relational expression that projects only the fields required by its consumer.

        This may make things easier for the optimizer, by removing crud that would expand the search space, but is difficult for the optimizer itself to do it, because optimizer rules must preserve the number and type of fields. Hence, this transform that operates on the entire tree, similar to the type-flattening transform.

        Currently this functionality is disabled in farrago/luciddb; the default implementation of this method does nothing.

        Parameters:
        ordered - Whether the relational expression must produce results in a particular order (typically because it has an ORDER BY at top level)
        rootRel - Relational expression that is at the root of the tree
        Returns:
        Trimmed relational expression
      • newFieldTrimmer

        protected RelFieldTrimmer newFieldTrimmer()
        Creates a RelFieldTrimmer.
        Returns:
        Field trimmer
      • convertQuery

        public RelRoot convertQuery​(SqlNode query,
                                    boolean needsValidation,
                                    boolean top)
        Converts an unvalidated query's parse tree into a relational expression.
        Parameters:
        query - Query to convert
        needsValidation - Whether to validate the query before converting; false if the query has already been validated.
        top - Whether the query is top-level, say if its result will become a JDBC result set; false if the query will be part of a view.
      • isStream

        private static boolean isStream​(SqlNode query)
      • isOrdered

        public static boolean isOrdered​(SqlNode query)
      • convertSelect

        public RelNode convertSelect​(SqlSelect select,
                                     boolean top)
        Converts a SELECT statement's parse tree into a relational expression.
      • distinctify

        private void distinctify​(SqlToRelConverter.Blackboard bb,
                                 boolean checkForDupExprs)
        Having translated 'SELECT ... FROM ... [GROUP BY ...] [HAVING ...]', adds a relational expression to make the results unique.

        If the SELECT clause contains duplicate expressions, adds LogicalProjects so that we are grouping on the minimal set of keys. The performance gain isn't huge, but it is difficult to detect these duplicate expressions later.

        Parameters:
        bb - Blackboard
        checkForDupExprs - Check for duplicate expressions
      • convertOrder

        protected void convertOrder​(SqlSelect select,
                                    SqlToRelConverter.Blackboard bb,
                                    RelCollation collation,
                                    java.util.List<SqlNode> orderExprList,
                                    SqlNode offset,
                                    SqlNode fetch)
        Converts a query's ORDER BY clause, if any.

        Ignores the ORDER BY clause if the query is not top-level and FETCH or OFFSET are not present.

        Parameters:
        select - Query
        bb - Blackboard
        collation - Collation list
        orderExprList - Method populates this list with orderBy expressions not present in selectList
        offset - Expression for number of rows to discard before returning first row
        fetch - Expression for number of rows to fetch
      • containsInOperator

        private static boolean containsInOperator​(SqlNode node)
        Returns whether a given node contains a SqlInOperator.
        Parameters:
        node - a RexNode tree
      • pushDownNotForIn

        private static SqlNode pushDownNotForIn​(SqlValidatorScope scope,
                                                SqlNode sqlNode)
        Push down all the NOT logical operators into any IN/NOT IN operators.
        Parameters:
        scope - Scope where sqlNode occurs
        sqlNode - the root node from which to look for NOT operators
        Returns:
        the transformed SqlNode representation with NOT pushed down.
      • convertWhere

        private void convertWhere​(SqlToRelConverter.Blackboard bb,
                                  SqlNode where)
        Converts a WHERE clause.
        Parameters:
        bb - Blackboard
        where - WHERE clause, may be null
      • containsNullLiteral

        private static boolean containsNullLiteral​(SqlNodeList valueList)
      • convertNonCorrelatedSubQuery

        private boolean convertNonCorrelatedSubQuery​(SqlToRelConverter.SubQuery subQuery,
                                                     SqlToRelConverter.Blackboard bb,
                                                     RelNode converted,
                                                     boolean isExists)
        Determines if a sub-query is non-correlated and if so, converts it to a constant.
        Parameters:
        subQuery - the call that references the sub-query
        bb - blackboard used to convert the sub-query
        converted - RelNode tree corresponding to the sub-query
        isExists - true if the sub-query is part of an EXISTS expression
        Returns:
        Whether the sub-query can be converted to a constant
      • convertToSingleValueSubq

        public RelNode convertToSingleValueSubq​(SqlNode query,
                                                RelNode plan)
        Converts the RelNode tree for a select statement to a select that produces a single value.
        Parameters:
        query - the query
        plan - the original RelNode tree corresponding to the statement
        Returns:
        the converted RelNode tree
      • convertInToOr

        private RexNode convertInToOr​(SqlToRelConverter.Blackboard bb,
                                      java.util.List<RexNode> leftKeys,
                                      SqlNodeList valuesList,
                                      SqlInOperator op)
        Converts "x IN (1, 2, ...)" to "x=1 OR x=2 OR ...".
        Parameters:
        leftKeys - LHS
        valuesList - RHS
        op - The operator (IN, NOT IN, > SOME, ...)
        Returns:
        converted expression
      • ensureSqlType

        private RexNode ensureSqlType​(RelDataType type,
                                      RexNode node)
        Ensures that an expression has a given SqlTypeName, applying a cast if necessary. If the expression already has the right type family, returns the expression unchanged.
      • convertExists

        private RelOptUtil.Exists convertExists​(SqlNode seek,
                                                RelOptUtil.SubQueryType subQueryType,
                                                RelOptUtil.Logic logic,
                                                boolean notIn,
                                                RelDataType targetDataType)
        Converts an EXISTS or IN predicate into a join. For EXISTS, the sub-query produces an indicator variable, and the result is a relational expression which outer joins that indicator to the original query. After performing the outer join, the condition will be TRUE if the EXISTS condition holds, NULL otherwise.
        Parameters:
        seek - A query, for example 'select * from emp' or 'values (1,2,3)' or '('Foo', 34)'.
        subQueryType - Whether sub-query is IN, EXISTS or scalar
        logic - Whether the answer needs to be in full 3-valued logic (TRUE, FALSE, UNKNOWN) will be required, or whether we can accept an approximation (say representing UNKNOWN as FALSE)
        notIn - Whether the operation is NOT IN
        Returns:
        join expression
      • isRowConstructor

        private boolean isRowConstructor​(SqlNode node)
      • findSubQueries

        private void findSubQueries​(SqlToRelConverter.Blackboard bb,
                                    SqlNode node,
                                    RelOptUtil.Logic logic,
                                    boolean registerOnlyScalarSubQueries)
        Builds a list of all IN or EXISTS operators inside SQL parse tree. Does not traverse inside queries.
        Parameters:
        bb - blackboard
        node - the SQL parse tree
        logic - Whether the answer needs to be in full 3-valued logic (TRUE, FALSE, UNKNOWN) will be required, or whether we can accept an approximation (say representing UNKNOWN as FALSE)
        registerOnlyScalarSubQueries - if set to true and the parse tree corresponds to a variation of a select node, only register it if it's a scalar sub-query
      • convertExpression

        public RexNode convertExpression​(SqlNode node)
        Converts an expression from SqlNode to RexNode format.
        Parameters:
        node - Expression to translate
        Returns:
        Converted expression
      • convertExpression

        public RexNode convertExpression​(SqlNode node,
                                         java.util.Map<java.lang.String,​RexNode> nameToNodeMap)
        Converts an expression from SqlNode to RexNode format, mapping identifier references to predefined expressions.
        Parameters:
        node - Expression to translate
        nameToNodeMap - map from String to RexNode; when an SqlIdentifier is encountered, it is used as a key and translated to the corresponding value from this map
        Returns:
        Converted expression
      • convertExtendedExpression

        protected RexNode convertExtendedExpression​(SqlNode node,
                                                    SqlToRelConverter.Blackboard bb)
        Converts a non-standard expression.

        This method is an extension-point that derived classes can override. If this method returns a null result, the normal expression translation process will proceed. The default implementation always returns null.

        Parameters:
        node - Expression
        bb - Blackboard
        Returns:
        null to proceed with the usual expression translation process
      • convertFrom

        protected void convertFrom​(SqlToRelConverter.Blackboard bb,
                                   SqlNode from)
        Converts a FROM clause into a relational expression.
        Parameters:
        bb - Scope within which to resolve identifiers
        from - FROM clause of a query. Examples include:
        • a single table ("SALES.EMP"),
        • an aliased table ("EMP AS E"),
        • a list of tables ("EMP, DEPT"),
        • an ANSI Join expression ("EMP JOIN DEPT ON EMP.DEPTNO = DEPT.DEPTNO"),
        • a VALUES clause ("VALUES ('Fred', 20)"),
        • a query ("(SELECT * FROM EMP WHERE GENDER = 'F')"),
        • or any combination of the above.
      • isSubQueryNonCorrelated

        private boolean isSubQueryNonCorrelated​(RelNode subq,
                                                SqlToRelConverter.Blackboard bb)
        Determines whether a sub-query is non-correlated. Note that a non-correlated sub-query can contain correlated references, provided those references do not reference select statements that are parents of the sub-query.
        Parameters:
        subq - the sub-query
        bb - blackboard used while converting the sub-query, i.e., the blackboard of the parent query of this sub-query
        Returns:
        true if the sub-query is non-correlated
      • getSystemFields

        protected java.util.List<RelDataTypeField> getSystemFields()
        Returns a list of fields to be prefixed to each relational expression.
        Returns:
        List of system fields
      • convertUsing

        @Nonnull
        private RexNode convertUsing​(SqlValidatorNamespace leftNamespace,
                                     SqlValidatorNamespace rightNamespace,
                                     java.util.List<java.lang.String> nameList)
        Returns an expression for matching columns of a USING clause or inferred from NATURAL JOIN. "a JOIN b USING (x, y)" becomes "a.x = b.x AND a.y = b.y". Returns null if the column list is empty.
        Parameters:
        leftNamespace - Namespace of left input to join
        rightNamespace - Namespace of right input to join
        nameList - List of column names to join on
        Returns:
        Expression to match columns from name list, or true if name list is empty
      • createAggregate

        protected RelNode createAggregate​(SqlToRelConverter.Blackboard bb,
                                          ImmutableBitSet groupSet,
                                          com.google.common.collect.ImmutableList<ImmutableBitSet> groupSets,
                                          java.util.List<AggregateCall> aggCalls)
        Creates an Aggregate.

        In case the aggregate rel changes the order in which it projects fields, the groupExprProjection parameter is provided, and the implementation of this method may modify it.

        The sortedCount parameter is the number of expressions known to be monotonic. These expressions must be on the leading edge of the grouping keys. The default implementation of this method ignores this parameter.

        Parameters:
        bb - Blackboard
        groupSet - Bit set of ordinals of grouping columns
        groupSets - Grouping sets
        aggCalls - Array of calls to aggregate functions
        Returns:
        LogicalAggregate
      • gatherOrderExprs

        protected void gatherOrderExprs​(SqlToRelConverter.Blackboard bb,
                                        SqlSelect select,
                                        SqlNodeList orderList,
                                        java.util.List<SqlNode> extraOrderExprs,
                                        java.util.List<RelFieldCollation> collationList)
        Creates a list of collations required to implement the ORDER BY clause, if there is one. Populates extraOrderExprs with any sort expressions which are not in the select clause.
        Parameters:
        bb - Scope within which to resolve identifiers
        select - Select clause. Never null, because we invent a dummy SELECT if ORDER BY is applied to a set operation (UNION etc.)
        orderList - Order by clause, may be null
        extraOrderExprs - Sort expressions which are not in the select clause (output)
        collationList - List of collations (output)
      • enableDecorrelation

        @Deprecated
        protected boolean enableDecorrelation()
        Deprecated.
      • decorrelateQuery

        protected RelNode decorrelateQuery​(RelNode rootRel)
      • isTrimUnusedFields

        @Deprecated
        public boolean isTrimUnusedFields()
        Deprecated.
        Returns whether to trim unused fields as part of the conversion process.
        Returns:
        Whether to trim unused fields
      • convertQueryRecursive

        protected RelRoot convertQueryRecursive​(SqlNode query,
                                                boolean top,
                                                RelDataType targetRowType)
        Recursively converts a query to a relational expression.
        Parameters:
        query - Query
        top - Whether this query is the top-level query of the statement
        targetRowType - Target row type, or null
        Returns:
        Relational expression
      • convertSetOp

        protected RelNode convertSetOp​(SqlCall call)
        Converts a set operation (UNION, INTERSECT, MINUS) into relational expressions.
        Parameters:
        call - Call to set operator
        Returns:
        Relational expression
      • all

        private boolean all​(SqlCall call)
      • createModify

        private RelNode createModify​(RelOptTable targetTable,
                                     RelNode source)
        Creates a relational expression to modify a table or modifiable view.
      • createSource

        private RelNode createSource​(RelOptTable targetTable,
                                     RelNode source,
                                     ModifiableView modifiableView,
                                     RelDataType delegateRowType)
        Wraps a relational expression in the projects and filters implied by a ModifiableView.

        The input relational expression is suitable for inserting into the view, and the returned relational expression is suitable for inserting into its delegate table.

        In principle, the delegate table of a view might be another modifiable view, and if so, the process can be repeated.

      • convertColumnList

        protected RelNode convertColumnList​(SqlInsert call,
                                            RelNode source)
        Creates a source for an INSERT statement.

        If the column list is not specified, source expressions match target columns in order.

        If the column list is specified, Source expressions are mapped to target columns by name via targetColumnList, and may not cover the entire target table. So, we'll make up a full row, using a combination of default values and the source expressions provided.

        Parameters:
        call - Insert expression
        source - Source relational expression
        Returns:
        Converted INSERT statement
      • createInsertBlackboard

        private SqlToRelConverter.Blackboard createInsertBlackboard​(RelOptTable targetTable,
                                                                    RexNode sourceRef,
                                                                    java.util.List<java.lang.String> targetColumnNames)
        Creates a blackboard for translating the expressions of generated columns in an INSERT statement.
      • unwrap

        private static <T> T unwrap​(java.lang.Object o,
                                    java.lang.Class<T> clazz)
      • collectInsertTargets

        protected void collectInsertTargets​(SqlInsert call,
                                            RexNode sourceRef,
                                            java.util.List<java.lang.String> targetColumnNames,
                                            java.util.List<RexNode> columnExprs)
        Given an INSERT statement, collects the list of names to be populated and the expressions to put in them.
        Parameters:
        call - Insert statement
        sourceRef - Expression representing a row from the source relational expression
        targetColumnNames - List of target column names, to be populated
        columnExprs - List of expressions, to be populated
      • convertIdentifier

        private RexNode convertIdentifier​(SqlToRelConverter.Blackboard bb,
                                          SqlIdentifier identifier)
        Converts an identifier into an expression in a given scope. For example, the "empno" in "select empno from emp join dept" becomes "emp.empno".
      • adjustInputRef

        protected RexNode adjustInputRef​(SqlToRelConverter.Blackboard bb,
                                         RexInputRef inputRef)
        Adjusts the type of a reference to an input field to account for nulls introduced by outer joins; and adjusts the offset to match the physical implementation.
        Parameters:
        bb - Blackboard
        inputRef - Input ref
        Returns:
        Adjusted input ref
      • convertRowConstructor

        private RelNode convertRowConstructor​(SqlToRelConverter.Blackboard bb,
                                              SqlCall rowConstructor)
        Converts a row constructor into a relational expression.
        Parameters:
        bb - Blackboard
        rowConstructor - Row constructor expression
        Returns:
        Relational expression which returns a single row.
      • extraSelectItems

        protected void extraSelectItems​(SqlToRelConverter.Blackboard bb,
                                        SqlSelect select,
                                        java.util.List<RexNode> exprList,
                                        java.util.List<java.lang.String> nameList,
                                        java.util.Collection<java.lang.String> aliasList,
                                        java.util.List<SqlMonotonicity> columnMonotonicityList)
        Adds extra select items. The default implementation adds nothing; derived classes may add columns to exprList, nameList, aliasList and columnMonotonicityList.
        Parameters:
        bb - Blackboard
        select - Select statement being translated
        exprList - List of expressions in select clause
        nameList - List of names, one per column
        aliasList - Collection of aliases that have been used already
        columnMonotonicityList - List of monotonicity, one per column
      • deriveAlias

        private java.lang.String deriveAlias​(SqlNode node,
                                             java.util.Collection<java.lang.String> aliases,
                                             int ordinal)
      • convertWith

        public RelRoot convertWith​(SqlWith with,
                                   boolean top)
        Converts a WITH sub-query into a relational expression.
      • convertValues

        public RelNode convertValues​(SqlCall values,
                                     RelDataType targetRowType)
        Converts a SELECT statement's parse tree into a relational expression.
      • convertValuesImpl

        private void convertValuesImpl​(SqlToRelConverter.Blackboard bb,
                                       SqlCall values,
                                       RelDataType targetRowType)
        Converts a values clause (as in "INSERT INTO T(x,y) VALUES (1,2)") into a relational expression.
        Parameters:
        bb - Blackboard
        values - Call to SQL VALUES operator
        targetRowType - Target row type