예제 #1
0
 private void ProcessIsUnique(IndexDef indexDef, IndexAttribute attribute)
 {
     if (attribute.unique.HasValue)
     {
         indexDef.IsUnique = attribute.Unique;
     }
 }
예제 #2
0
        // suppport forms
        //   a.i =|>|< 5
        public static IndexDef FilterCanUseIndex(this Expr filter, BaseTableRef table)
        {
            string[] indexops = { "=", ">=", "<=", ">", "<" };
            Debug.Assert(filter.IsBoolean());

            IndexDef ret = null;

            if (filter is BinExpr fb)
            {
                // expression is already normalized, so no swap side shall considered
                Debug.Assert(!(fb.l_() is LiteralExpr && fb.r_() is ColExpr));
                if (indexops.Contains(fb.op_) && fb.l_() is ColExpr cl && fb.r_() is LiteralExpr)
                {
                    var index = table.Table().IndexContains(cl.colName_);
                    if (index != null)
                    {
                        if (index.columns_[0].Equals(cl.colName_))
                        {
                            ret = index;
                        }
                    }
                }
            }

            return(ret);
        }
        public void Process(AddPrimaryIndexAction action)
        {
            var type = action.Type;

            var primaryIndexes = type.Indexes.Where(i => i.IsPrimary).ToList();

            if (primaryIndexes.Count > 0)
            {
                foreach (var primaryIndex in primaryIndexes)
                {
                    type.Indexes.Remove(primaryIndex);
                }
            }

            var generatedIndex = new IndexDef(action.Type, context.Validator)
            {
                IsPrimary = true
            };

            generatedIndex.Name = context.NameBuilder.BuildIndexName(type, generatedIndex);

            TypeDef hierarchyRoot;

            if (type.IsInterface)
            {
                var implementor = type.Implementors.First();
                hierarchyRoot = implementor;
            }
            else
            {
                hierarchyRoot = type;
            }

            var hierarchyDef = context.ModelDef.FindHierarchy(hierarchyRoot);

            foreach (KeyField pair in hierarchyDef.KeyFields)
            {
                generatedIndex.KeyFields.Add(pair.Name, pair.Direction);
            }

            // Check if user added secondary index equal to auto-generated primary index
            var userDefinedIndex = type.Indexes.Where(i => (i.KeyFields.Count == generatedIndex.KeyFields.Count) && i.KeyFields.SequenceEqual(generatedIndex.KeyFields)).FirstOrDefault();

            if (userDefinedIndex != null)
            {
                type.Indexes.Remove(userDefinedIndex);
                generatedIndex.FillFactor = userDefinedIndex.FillFactor;
                if (!string.IsNullOrEmpty(userDefinedIndex.MappingName))
                {
                    generatedIndex.MappingName = userDefinedIndex.MappingName;
                }
            }

            // Gather "is clustered" flag from hierarchy.
            generatedIndex.IsClustered = hierarchyDef.IsClustered;

            type.Indexes.Add(generatedIndex);
        }
예제 #4
0
        private void ProcessFillFactor(IndexDef index, IndexAttribute attribute)
        {
            if (!attribute.fillFactor.HasValue)
            {
                return;
            }

            index.FillFactor = attribute.FillFactor;
        }
예제 #5
0
 public void Process(IndexDef indexDef, IndexAttribute attribute)
 {
     ProcessMappingName(indexDef, attribute.Name, ValidationRule.Index);
     ProcessKeyFields(attribute.KeyFields, indexDef.KeyFields);
     ProcessIncludedFields(attribute.IncludedFields, indexDef.IncludedFields);
     ProcessFillFactor(indexDef, attribute);
     ProcessIsUnique(indexDef, attribute);
     ProcessFilter(indexDef, attribute);
     ProcessClustered(indexDef, attribute);
 }
예제 #6
0
 private void ProcessClustered(IndexDef indexDef, IndexAttribute attribute)
 {
     if (!attribute.Clustered)
     {
         return;
     }
     if (indexDef.Type.UnderlyingType.IsInterface)
     {
         throw new DomainBuilderException(string.Format(Strings.ExClusteredIndexCanNotBeDeclaredInInterfaceX, indexDef.Type.UnderlyingType));
     }
     indexDef.IsClustered = true;
 }
        public IndexDef DefineIndex(TypeDef typeDef, IndexAttribute attribute)
        {
            var index = new IndexDef(typeDef, context.Validator)
            {
                IsSecondary = true
            };

            attributeProcessor.Process(index, attribute);

            if (string.IsNullOrEmpty(index.Name) && index.KeyFields.Count > 0)
            {
                index.Name = context.NameBuilder.BuildIndexName(typeDef, index);
            }

            return(index);
        }
예제 #8
0
        private void ProcessFilter(IndexDef indexDef, IndexAttribute attribute)
        {
            if (string.IsNullOrEmpty(attribute.Filter))
            {
                return;
            }
            var declaringType = indexDef.Type.UnderlyingType;
            var filterType    = attribute.FilterType ?? declaringType;

            indexDef.FilterExpression = GetExpressionFromProvider(filterType, attribute.Filter, declaringType, typeof(bool));
            if (indexDef.MappingName == null)
            {
                var nameBuilder = context.NameBuilder;
                var name        = nameBuilder.BuildPartialIndexName(indexDef, filterType, attribute.Filter);
                ProcessMappingName(indexDef, name, ValidationRule.Index);
            }
        }
예제 #9
0
        /// <summary>
        /// Gets the name for <see cref="IndexDef"/> object.
        /// </summary>
        /// <param name="type">The type def.</param>
        /// <param name="index">The <see cref="IndexDef"/> object.</param>
        /// <returns>Index name.</returns>
        public string BuildIndexName(TypeDef type, IndexDef index)
        {
            ArgumentValidator.EnsureArgumentNotNull(index, "index");

            string result = string.Empty;

            if (!index.Name.IsNullOrEmpty())
            {
                result = index.Name;
            }
            else if (index.IsPrimary)
            {
                result = string.Format("PK_{0}", type.Name);
            }
            else if (index.KeyFields.Count == 0)
            {
                result = string.Empty;
            }
            else if (!index.MappingName.IsNullOrEmpty())
            {
                result = index.MappingName;
            }
            else
            {
                if (index.KeyFields.Count == 1)
                {
                    FieldDef field;
                    if (type.Fields.TryGetValue(index.KeyFields[0].Key, out field) && field.IsEntity)
                    {
                        result = string.Format("FK_{0}", field.Name);
                    }
                }
                if (result.IsNullOrEmpty())
                {
                    string[] names = new string[index.KeyFields.Keys.Count];
                    index.KeyFields.Keys.CopyTo(names, 0);
                    result = string.Format("IX_{0}", string.Join("", names));
                }
            }
            return(ApplyNamingRules(result));
        }
예제 #10
0
 public void CreateIndex(string tabName, IndexDef index)
 {
     records_[tabName].indexes_.Add(index);
 }
예제 #11
0
 /// <summary>
 /// Builds name for partial index.
 /// </summary>
 /// <param name="index">Index to build name for.</param>
 /// <param name="filterType">Type that defines filter for partial index.</param>
 /// <param name="filterMember">Member that defines filter for partial index.</param>
 /// <returns>Name for <paramref name="index"/>.</returns>
 public string BuildPartialIndexName(IndexDef index, Type filterType, string filterMember)
 {
     return(string.Format("IXP_{0}.{1}", filterType.Name, filterMember));
 }
예제 #12
0
파일: LogicNode.cs 프로젝트: bigwa/qpmodel
        // This is an honest translation from logic to physical plan
        public PhysicNode DirectToPhysical(QueryOption option)
        {
            PhysicNode phy;

            switch (this)
            {
            case LogicScanTable ln:
                // if there are indexes can help filter, use them
                IndexDef index = null;
                if (ln.filter_ != null)
                {
                    if (option.optimize_.enable_indexseek_)
                    {
                        index = ln.filter_.FilterCanUseIndex(ln.tabref_);
                    }
                    ln.filter_.SubqueryDirectToPhysic();
                }
                if (index is null)
                {
                    phy = new PhysicScanTable(ln);
                }
                else
                {
                    phy = new PhysicIndexSeek(ln, index);
                }
                break;

            case LogicJoin lc:
                var l = l_();
                var r = r_();
                Debug.Assert(!l.LeftReferencesRight(r));
                switch (lc)
                {
                case LogicSingleJoin lsmj:
                    phy = new PhysicSingleJoin(lsmj,
                                               l.DirectToPhysical(option),
                                               r.DirectToPhysical(option));
                    break;

                case LogicMarkJoin lmj:
                    phy = new PhysicMarkJoin(lmj,
                                             l.DirectToPhysical(option),
                                             r.DirectToPhysical(option));
                    break;

                default:
                    // one restriction of HJ is that if build side has columns used by probe side
                    // subquries, we need to use NLJ to pass variables. It is can be fixed by changing
                    // the way we pass parameters though.
                    bool lhasSubqCol = TableRef.HasColsUsedBySubquries(l.InclusiveTableRefs());
                    if (lc.filter_.FilterHashable() && !lhasSubqCol &&
                        (lc.type_ == JoinType.Inner || lc.type_ == JoinType.Left))
                    {
                        phy = new PhysicHashJoin(lc,
                                                 l.DirectToPhysical(option),
                                                 r.DirectToPhysical(option));
                    }
                    else
                    {
                        phy = new PhysicNLJoin(lc,
                                               l.DirectToPhysical(option),
                                               r.DirectToPhysical(option));
                    }
                    break;
                }
                break;

            case LogicResult lr:
                phy = new PhysicResult(lr);
                break;

            case LogicFromQuery ls:
                phy = new PhysicFromQuery(ls, child_().DirectToPhysical(option));
                break;

            case LogicFilter lf:
                phy = new PhysicFilter(lf, child_().DirectToPhysical(option));
                if (lf.filter_ != null)
                {
                    lf.filter_.SubqueryDirectToPhysic();
                }
                break;

            case LogicInsert li:
                phy = new PhysicInsert(li, child_().DirectToPhysical(option));
                break;

            case LogicScanFile le:
                phy = new PhysicScanFile(le);
                break;

            case LogicAgg la:
                phy = new PhysicHashAgg(la, child_().DirectToPhysical(option));
                break;

            case LogicOrder lo:
                phy = new PhysicOrder(lo, child_().DirectToPhysical(option));
                break;

            case LogicAnalyze lan:
                phy = new PhysicAnalyze(lan, child_().DirectToPhysical(option));
                break;

            case LogicIndex lindex:
                phy = new PhysicIndex(lindex, child_().DirectToPhysical(option));
                break;

            case LogicLimit limit:
                phy = new PhysicLimit(limit, child_().DirectToPhysical(option));
                break;

            case LogicAppend append:
                phy = new PhysicAppend(append, l_().DirectToPhysical(option), r_().DirectToPhysical(option));
                break;

            case LogicCteProducer cteproducer:
                phy = new PhysicCteProducer(cteproducer, child_().DirectToPhysical(option));
                break;

            case LogicSequence sequence:
                List <PhysicNode> children = sequence.children_.Select(x => x.DirectToPhysical(option)).ToList();
                phy = new PhysicSequence(sequence, children);
                break;

            default:
                throw new NotImplementedException();
            }

            if (option.profile_.enabled_)
            {
                phy = new PhysicProfiling(phy);
            }
            return(phy);
        }