Beispiel #1
0
        // from clause -
        //  pair each from item with cross join, their join conditions will be handled
        //  with where clause processing.
        //
        LogicNode transformFromClause()
        {
            LogicNode transformOneFrom(TableRef tab)
            {
                LogicNode from;

                switch (tab)
                {
                case BaseTableRef bref:
                    if (bref.Table().source_ == TableDef.TableSource.Table)
                    {
                        from = new LogicScanTable(bref);
                    }
                    else
                    {
                        from = new LogicScanStream(bref);
                    }
                    if (bref.tableSample_ != null)
                    {
                        from = new LogicSampleScan(from, bref.tableSample_);
                    }
                    break;

                case ExternalTableRef eref:
                    from = new LogicScanFile(eref);
                    break;

                case CTEQueryRef cref:
                    if (this is CteSelectStmt css && css.CteId() == cref.cte_.cteId_)
                    {
                        cref.query_.cteInfo_ = cteInfo_;
                        var        ctePlan = cref.query_.CreatePlan();
                        string     alias   = null;
                        NamedQuery key;

                        alias = cref.alias_;
                        key   = new NamedQuery(cref.query_, alias, NamedQuery.QueryType.FROM);

                        from = new LogicFromQuery(cref, ctePlan);
                        subQueries_.Add(key);
                        if (!fromQueries_.ContainsKey(key))
                        {
                            fromQueries_.Add(key, from as LogicFromQuery);
                        }
                    }
                    else
                    {
                        from = new LogicCteConsumer(cteInfo_.GetCteInfoEntryByCteId(cref.cte_.cteId_), cref);
                    }
                    break;
Beispiel #2
0
        // from clause -
        //  pair each from item with cross join, their join conditions will be handled
        //  with where clause processing.
        //
        LogicNode transformFromClause()
        {
            LogicNode transformOneFrom(TableRef tab)
            {
                LogicNode from;

                switch (tab)
                {
                case BaseTableRef bref:
                    if (bref.Table().source_ == TableDef.TableSource.Table)
                    {
                        from = new LogicScanTable(bref);
                    }
                    else
                    {
                        from = new LogicScanStream(bref);
                    }
                    if (bref.tableSample_ != null)
                    {
                        from = new LogicSampleScan(from, bref.tableSample_);
                    }
                    break;

                case ExternalTableRef eref:
                    from = new LogicScanFile(eref);
                    break;

                case QueryRef qref:
                    var plan = qref.query_.CreatePlan();
                    if (qref is FromQueryRef && queryOpt_.optimize_.remove_from_)
                    {
                        from = plan;
                    }
                    else
                    {
                        string alias = null;
                        if (qref is CTEQueryRef cq)
                        {
                            alias = cq.alias_;
                        }
                        else if (qref is FromQueryRef fq)
                        {
                            alias = fq.alias_;
                        }
                        var key = new NamedQuery(qref.query_, alias);
                        from = new LogicFromQuery(qref, plan);
                        subQueries_.Add(key);

                        // if from CTE, then it could be duplicates
                        if (!fromQueries_.ContainsKey(key))
                        {
                            fromQueries_.Add(key, from as LogicFromQuery);
                        }
                    }
                    break;

                case JoinQueryRef jref:
                    // We will form join group on all tables and put a filter on top
                    // of the joins as a normalized form for later processing.
                    //
                    //      from a join b on a1=b1 or a3=b3 join c on a2=c2;
                    //   => from a , b, c where  (a1=b1 or a3=b3) and a2=c2;
                    //
                    LogicJoin subjoin    = new LogicJoin(null, null);
                    Expr      filterexpr = null;
                    for (int i = 0; i < jref.tables_.Count; i++)
                    {
                        LogicNode t        = transformOneFrom(jref.tables_[i]);
                        var       children = subjoin.children_;
                        if (children[0] is null)
                        {
                            children[0] = t;
                        }
                        else
                        {
                            if (children[1] is null)
                            {
                                children[1] = t;
                            }
                            else
                            {
                                subjoin = new LogicJoin(t, subjoin);
                            }
                            subjoin.type_ = jref.joinops_[i - 1];
                            filterexpr    = filterexpr.AddAndFilter(jref.constraints_[i - 1]);
                        }
                    }
                    Debug.Assert(filterexpr != null);
                    from = new LogicFilter(subjoin, filterexpr);
                    break;

                default:
                    throw new InvalidProgramException();
                }

                return(from);
            }

            LogicNode root;

            if (from_.Count >= 2)
            {
                var join     = new LogicJoin(null, null);
                var children = join.children_;
                from_.ForEach(x =>
                {
                    LogicNode from = transformOneFrom(x);
                    if (children[0] is null)
                    {
                        children[0] = from;
                    }
                    else
                    {
                        children[1] = (children[1] is null) ? from :
                                      new LogicJoin(from, children[1]);
                    }
                });
                root = join;
            }
            else if (from_.Count == 1)
            {
                root = transformOneFrom(from_[0]);
            }
            else
            {
                root = new LogicResult(selection_);
            }

            // distributed plan is required if any table is distributed, subquery
            // referenced tables are not counted here. So we may have the query
            // shape with main queyr not distributed but subquery is.
            //
            bool hasdtable      = false;
            bool onlyreplicated = true;

            from_.ForEach(x => checkifHasdtableAndifOnlyReplicated(x, ref hasdtable, ref onlyreplicated));
            if (hasdtable)
            {
                Debug.Assert(!distributed_);
                distributed_ = true;

                // distributed table query can also use memo
                // remote exchange is considered in memo optimization
                queryOpt_.optimize_.memo_use_remoteexchange_ = true;

                if (onlyreplicated)
                {
                    root = new LogicGather(root, new List <int> {
                        0
                    });
                }
                else
                {
                    root = new LogicGather(root);
                }
            }

            return(root);
        }
Beispiel #3
0
        // from clause -
        //  pair each from item with cross join, their join conditions will be handled
        //  with where clauss processing.
        //
        LogicNode transformFromClause()
        {
            LogicNode transformOneFrom(TableRef tab)
            {
                LogicNode from;

                switch (tab)
                {
                case BaseTableRef bref:
                    from = new LogicScanTable(bref);
                    break;

                case ExternalTableRef eref:
                    from = new LogicScanFile(eref);
                    break;

                case QueryRef qref:
                    var plan = qref.query_.CreatePlan();
                    if (qref is FromQueryRef && queryOpt_.optimize_.remove_from_)
                    {
                        from = plan;
                    }
                    else
                    {
                        string alias = null;
                        if (qref is CTEQueryRef cq)
                        {
                            alias = cq.alias_;
                        }
                        else if (qref is FromQueryRef fq)
                        {
                            alias = fq.alias_;
                        }
                        var key = new NamedQuery(qref.query_, alias);
                        from = new LogicFromQuery(qref, plan);
                        subQueries_.Add(key);

                        // if from CTE, then it could be duplicates
                        if (!fromQueries_.ContainsKey(key))
                        {
                            fromQueries_.Add(key, from as LogicFromQuery);
                        }
                    }
                    break;

                case JoinQueryRef jref:
                    // We will form join group on all tables and put a filter on top
                    // of the joins as a normalized form for later processing.
                    //
                    //      from a join b on a1=b1 or a3=b3 join c on a2=c2;
                    //   => from a , b, c where  (a1=b1 or a3=b3) and a2=c2;
                    //
                    LogicJoin subjoin    = new LogicJoin(null, null);
                    Expr      filterexpr = null;
                    for (int i = 0; i < jref.tables_.Count; i++)
                    {
                        LogicNode t        = transformOneFrom(jref.tables_[i]);
                        var       children = subjoin.children_;
                        if (children[0] is null)
                        {
                            children[0] = t;
                        }
                        else
                        {
                            if (children[1] is null)
                            {
                                children[1] = t;
                            }
                            else
                            {
                                subjoin = new LogicJoin(t, subjoin);
                            }
                            subjoin.type_ = jref.joinops_[i - 1];
                            filterexpr    = filterexpr.AddAndFilter(jref.constraints_[i - 1]);
                        }
                    }
                    Debug.Assert(filterexpr != null);
                    from = new LogicFilter(subjoin, filterexpr);
                    break;

                default:
                    throw new Exception();
                }

                return(from);
            }

            LogicNode root;

            if (from_.Count >= 2)
            {
                var join     = new LogicJoin(null, null);
                var children = join.children_;
                from_.ForEach(x =>
                {
                    LogicNode from = transformOneFrom(x);
                    if (children[0] is null)
                    {
                        children[0] = from;
                    }
                    else
                    {
                        children[1] = (children[1] is null) ? from :
                                      new LogicJoin(from, children[1]);
                    }
                });
                root = join;
            }
            else if (from_.Count == 1)
            {
                root = transformOneFrom(from_[0]);
            }
            else
            {
                root = new LogicResult(selection_);
            }

            return(root);
        }