예제 #1
0
 /// <summary>
 /// Visitor for a ScanTableOp. Simply ensures that the keys get
 /// added to the list of referenced columns
 /// </summary>
 /// <param name="op">current ScanTableOp</param>
 /// <param name="n">current subtree</param>
 public override void Visit(ScanTableOp op, Node n)
 {
     // find the keys of the table. Make sure that they are
     // all references
     op.Table.ReferencedColumns.Or(op.Table.Keys);
     // recompute the nodeinfo - keys won't get picked up otherwise
     m_command.RecomputeNodeInfo(n);
 }
 public override Node Visit(ScanTableOp op, Node n)
 {
     PlanCompiler.Assert(!n.HasChild0, "scanTable with an input?"); // no more views
     // update the list of referenced columns in the table
     op.Table.ReferencedColumns.And(m_referencedVars);
     m_command.RecomputeNodeInfo(n);
     return(n);
 }
예제 #3
0
 public override System.Data.Entity.Core.Query.InternalTrees.Node Visit(
     ScanTableOp op,
     System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(!n.HasChild0, "scanTable with an input?");
     op.Table.ReferencedColumns.And(this.m_referencedVars);
     this.m_command.RecomputeNodeInfo(n);
     return(n);
 }
예제 #4
0
 // <summary>
 // If the columnVars defined by the table contain the var that needs to be remapped
 // all the column vars produces by the table are remaped to new vars.
 // </summary>
 public override void Visit(ScanTableOp op, Node n)
 {
     if (op.Table.Columns.Contains(m_oldVar))
     {
         var newScanTableOp = m_command.CreateScanTableOp(op.Table.TableMetadata);
         for (var i = 0; i < op.Table.Columns.Count; i++)
         {
             AddMapping(op.Table.Columns[i], newScanTableOp.Table.Columns[i]);
         }
         n.Op = newScanTableOp;
     }
 }
예제 #5
0
        private static bool ProcessGroupByOpOnAllInputColumnsWithAggregateOperation(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node n,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = n;
            PhysicalProjectOp op1 = context.Command.Root.Op as PhysicalProjectOp;

            if (op1 == null || op1.Outputs.Count > 1 || (n.Child0.Op.OpType != OpType.ScanTable || n.Child2 == null) || (n.Child2.Child0 == null || n.Child2.Child0.Child0 == null || n.Child2.Child0.Child0.Op.OpType != OpType.Aggregate))
            {
                return(false);
            }
            GroupByOp op2     = (GroupByOp)n.Op;
            Table     table   = ((ScanTableBaseOp)n.Child0.Op).Table;
            VarList   columns = table.Columns;

            foreach (Var v in (List <Var>)columns)
            {
                if (!op2.Keys.IsSet(v))
                {
                    return(false);
                }
            }
            foreach (Var v in (List <Var>)columns)
            {
                op2.Outputs.Clear(v);
                op2.Keys.Clear(v);
            }
            Command     command     = context.Command;
            ScanTableOp scanTableOp = command.CreateScanTableOp(table.TableMetadata);

            System.Data.Entity.Core.Query.InternalTrees.Node node1 = command.CreateNode((Op)scanTableOp);
            System.Data.Entity.Core.Query.InternalTrees.Node node2 = command.CreateNode((Op)command.CreateOuterApplyOp(), node1, n);
            Var computedVar;

            System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(command.CreateNode((Op)command.CreateVarRefOp(op2.Outputs.First)), out computedVar);
            newNode = command.CreateNode((Op)command.CreateProjectOp(computedVar), node2, varDefListNode);
            System.Data.Entity.Core.Query.InternalTrees.Node node3 = (System.Data.Entity.Core.Query.InternalTrees.Node)null;
            IEnumerator <Var> enumerator1 = scanTableOp.Table.Keys.GetEnumerator();
            IEnumerator <Var> enumerator2 = table.Keys.GetEnumerator();

            for (int index = 0; index < table.Keys.Count; ++index)
            {
                enumerator1.MoveNext();
                enumerator2.MoveNext();
                System.Data.Entity.Core.Query.InternalTrees.Node node4 = command.CreateNode((Op)command.CreateComparisonOp(OpType.EQ, false), command.CreateNode((Op)command.CreateVarRefOp(enumerator1.Current)), command.CreateNode((Op)command.CreateVarRefOp(enumerator2.Current)));
                node3 = node3 == null ? node4 : command.CreateNode((Op)command.CreateConditionalOp(OpType.And), node3, node4);
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node5 = command.CreateNode((Op)command.CreateFilterOp(), n.Child0, node3);
            n.Child0 = node5;
            return(true);
        }
            public override void Visit(ScanTableOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
            {
                if (!op.Table.Columns.Contains(this.m_oldVar))
                {
                    return;
                }
                ScanTableOp scanTableOp = this.m_command.CreateScanTableOp(op.Table.TableMetadata);

                this.m_command.CreateVarDefListOp();
                for (int index = 0; index < op.Table.Columns.Count; ++index)
                {
                    this.AddMapping(op.Table.Columns[index], scanTableOp.Table.Columns[index]);
                }
                n.Op = (Op)scanTableOp;
            }
예제 #7
0
        private Node ProcessScanTable(Node scanTableNode, ScanTableOp scanTableOp, ref IsOfOp typeFilter)
        {
            HandleTableOpMetadata(scanTableOp);

            PlanCompiler.Assert(scanTableOp.Table.TableMetadata.Extent != null, "ScanTableOp must reference a table with an extent");

            Node ret = null;

            //
            // Get simple things out of the way. If we're dealing with an S-space entityset, 
            // simply return the node
            // 
            if (scanTableOp.Table.TableMetadata.Extent.EntityContainer.DataSpace
                == DataSpace.SSpace)
            {
                return scanTableNode;
            }
            else
            {
                // "Expand" the C-Space view
                ret = ExpandView(scanTableOp, ref typeFilter);
            }

            // Rerun the processor over the resulting subtree
            ret = VisitNode(ret);

            return ret;
        }
예제 #8
0
 public override void Visit(ScanTableOp op, Node n)
 {
     VisitRelOpDefault(op, n);
 }
 /// <summary>
 ///     Visitor pattern method for ScanTableOp
 /// </summary>
 /// <param name="op"> The ScanTableOp being visited </param>
 /// <param name="n"> The Node that references the Op </param>
 public virtual void Visit(ScanTableOp op, Node n)
 {
     VisitTableOp(op, n);
 }
        /// <summary>
        ///     ScanTableOp
        ///     Visit a scanTable Op. Flatten out the table's record into one column
        ///     for each field. Additionally, set up the VarInfo map appropriately
        /// </summary>
        /// <param name="op"> </param>
        /// <param name="n"> </param>
        /// <returns> new subtree </returns>
        public override Node Visit(ScanTableOp op, Node n)
        {
            var columnVar = op.Table.Columns[0];
            var typeInfo = m_typeInfo.GetTypeInfo(columnVar.Type);
            var newRowType = typeInfo.FlattenedType;

            var properties = new List<md.EdmProperty>();
            var keyProperties = new List<md.EdmMember>();
            var declaredProps = new HashSet<string>();
            foreach (md.EdmProperty p in TypeHelpers.GetAllStructuralMembers(columnVar.Type.EdmType))
            {
                declaredProps.Add(p.Name);
            }
            foreach (var p in newRowType.Properties)
            {
                if (declaredProps.Contains(p.Name))
                {
                    properties.Add(p);
                }
            }
            foreach (var pref in typeInfo.GetKeyPropertyRefs())
            {
                var p = typeInfo.GetNewProperty(pref);
                keyProperties.Add(p);
            }

            //
            // Create a flattened table definition, and a table with that definiton;
            //
            var newTableMD = m_command.CreateFlatTableDefinition(properties, keyProperties, op.Table.TableMetadata.Extent);
            var newTable = m_command.CreateTableInstance(newTableMD);

            var varInfo = m_varInfoMap.CreateStructuredVarInfo(columnVar, newRowType, newTable.Columns, properties);

            n.Op = m_command.CreateScanTableOp(newTable);
            return n;
        }
예제 #11
0
 // <summary>
 // ScanTableOp
 // </summary>
 public override int Visit(ScanTableOp op, Node n)
 {
     return(op.Table.Columns.Count);
 }
 public override int Visit(ScanTableOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     return(op.Table.Columns.Count);
 }
예제 #13
0
        // <summary>
        // Copies a ScanTableOp
        // </summary>
        // <param name="op"> The Op to Copy </param>
        // <param name="n"> The Node that references the Op </param>
        // <returns> A copy of the original Node that references a copy of the original Op </returns>
        public override Node Visit(ScanTableOp op, Node n)
        {
            // First create a new ScanTableOp based on the metadata of the existing Op
            var newScan = m_destCmd.CreateScanTableOp(op.Table.TableMetadata);
            // Map the corresponding tables/columns
            MapTable(newScan.Table, op.Table);

            // Create the new node
            Debug.Assert(!n.HasChild0);
            return m_destCmd.CreateNode(newScan);
        }
예제 #14
0
 /// <summary>
 ///     Visitor for a ScanTableOp. Simply ensures that the keys get
 ///     added to the list of referenced columns
 /// </summary>
 /// <param name="op"> current ScanTableOp </param>
 /// <param name="n"> current subtree </param>
 public override void Visit(ScanTableOp op, Node n)
 {
     // find the keys of the table. Make sure that they are 
     // all references
     op.Table.ReferencedColumns.Or(op.Table.Keys);
     // recompute the nodeinfo - keys won't get picked up otherwise
     m_command.RecomputeNodeInfo(n);
 }
예제 #15
0
 public override void Visit(ScanTableOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(!n.HasChild0, "scanTableOp with an input?");
 }
예제 #16
0
 /// <summary>
 /// Processes a ScanTableOp - simply delegates to ProcessScanTableOp
 /// </summary>
 /// <param name="op">the view op</param>
 /// <param name="n">current node tree</param>
 /// <returns>the transformed view-op</returns>
 public override Node Visit(ScanTableOp op, Node n)
 {
     IsOfOp nullFilter = null;
     return ProcessScanTable(n, op, ref nullFilter);
 }
예제 #17
0
        private Node ExpandView(ScanTableOp scanTableOp, ref IsOfOp typeFilter)
        {
            var entitySet = scanTableOp.Table.TableMetadata.Extent;
            PlanCompiler.Assert(entitySet != null, "The target of a ScanTableOp must reference an EntitySet to be used with ExpandView");
            PlanCompiler.Assert(
                entitySet.EntityContainer.DataSpace == DataSpace.CSpace,
                "Store entity sets cannot have Query Mapping Views and should not be used with ExpandView");

            if (typeFilter != null &&
                !typeFilter.IsOfOnly
                &&
                TypeSemantics.IsSubTypeOf(entitySet.ElementType, typeFilter.IsOfType.EdmType))
            {
                //
                // If a type filter is being applied to the ScanTableOp, but that filter is asking
                // for all elements that are the same type or a supertype of the element type of the
                // target entity set, then the type filter is a no-op and can safely be discarded -
                // IF AND ONLY IF the type filter is 'OfType' - which includes subtypes - and NOT
                // 'IsOfOnly' - which requires an exact type match, and so does not include subtypes.
                //
                typeFilter = null;
            }

            //
            // Call the GetGeneratedView method to retrieve the query mapping view for the extent referenced
            // by the ScanTableOp. The actual method used to do this differs depending on whether the default
            // Query Mapping View is sufficient or a targeted view that only filters by element type is required.
            //
            GeneratedView definingQuery = null;
            var requiredType = scanTableOp.Table.TableMetadata.Extent.ElementType;
            var includeSubtypes = true;
            if (typeFilter != null)
            {
                // 
                // A type filter is being applied to the ScanTableOp; it may be possible to produce
                // an optimized expansion of the view based on type-specific views generated for the
                // C-Space entity set. 
                // The type for which the view should be tuned is the 'OfType' specified on the type filter.
                // If the type filter is an 'IsOfOnly' filter then the view should NOT include subtypes of the required type.
                //
                requiredType = (EntityTypeBase)typeFilter.IsOfType.EdmType;
                includeSubtypes = !typeFilter.IsOfOnly;
                if (m_command.MetadataWorkspace.TryGetGeneratedViewOfType(entitySet, requiredType, includeSubtypes, out definingQuery))
                {
                    //
                    // At this point a type-specific view was found that satisifies the type filter's
                    // constraints in terms of required type and whether subtypes should be included;
                    // the type filter itself is now unnecessary and should be set to null indicating
                    // that it can be safely removed (see ProcessScanTableOp and Visit(FilterOp) for this).
                    //
                    typeFilter = null;
                }
            }

            //
            // If a generated view has not been obtained at this point then either:
            // - A type filter was specified but no type-specific view exists that satisfies its constraints.
            //   OR
            // - No type filter was specified.
            // In either case the default query mapping view for the referenced entity set should now be retrieved.
            //
            if (null == definingQuery)
            {
                definingQuery = m_command.MetadataWorkspace.GetGeneratedView(entitySet);
            }

            //
            // If even the default query mapping view was not found then we cannot continue.
            // This implies that the set was not mapped, which should not be allowed, therefore
            // a retail assert is used here instead of a regular exception.
            //
            PlanCompiler.Assert(definingQuery != null, Strings.ADP_NoQueryMappingView(entitySet.EntityContainer.Name, entitySet.Name));

            //
            // At this point we're guaranteed to have found a defining query for the view.
            // We're now going to convert this into an IQT, and then copy it into our own IQT.
            //
            var ret = definingQuery.GetInternalTree(m_command);

            //
            // Make sure we're tracking what we've asked any discriminator maps to contain.
            //
            DetermineDiscriminatorMapUsage(ret, entitySet, requiredType, includeSubtypes);

            //
            // Build up a ScanViewOp to "cap" the defining query below
            //
            var scanViewOp = m_command.CreateScanViewOp(scanTableOp.Table);
            ret = m_command.CreateNode(scanViewOp, ret);

            return ret;
        }
 public override void Visit(ScanTableOp op, Node n)
 {
     PlanCompiler.Assert(!n.HasChild0, "scanTableOp with an input?");
 }
예제 #19
0
 /// <summary>
 /// ScanTableOp handler
 /// </summary>
 /// <param name="op"></param>
 /// <param name="n"></param>
 public override void Visit(ScanTableOp op, Node n)
 {
     PlanCompiler.Assert(!n.HasChild0, "scanTableOp with an input?");
 }
예제 #20
0
 public override void Visit(ScanTableOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     op.Table.ReferencedColumns.Or(op.Table.Keys);
     this.m_command.RecomputeNodeInfo(n);
 }