Ejemplo n.º 1
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (this.m_Prop != null)
     {
         if (this.m_Prop.Equals("NON_EMPTY_BEHAVIOR", StringComparison.InvariantCultureIgnoreCase))
         {
             Message m = new Message(this)
             {
                 Id       = 7,
                 Text     = string.Format("AS2008 only: Consider removing NON_EMPTY_BEHAVIOR property", new object[0]),
                 Severity = 2
             };
             analyzer.Add(m);
         }
         else
         {
             Type t = this.m_RValue.GetType();
             if (!MDXNode.IsConstantNode(t) && (t != typeof(MDXIDNode)))
             {
                 Message message2 = new Message(this)
                 {
                     Id       = 8,
                     Text     = string.Format("Calculation property '{0}' is not a constant or member reference. Therefore it will not benefit from neiter block computation mode, nor caching", this.m_Prop),
                     Severity = 4
                 };
                 analyzer.Add(message2);
             }
         }
     }
     try
     {
         analyzer.InLHS = true;
         this.m_LValue.Analyze(analyzer);
     }
     finally
     {
         analyzer.InLHS = false;
     }
     try
     {
         analyzer.InRHS = true;
         this.m_RValue.Analyze(analyzer);
     }
     finally
     {
         analyzer.InRHS = false;
     }
     if ((this.m_Prop == null) && (this.m_RValue.GetMDXType() == MDXDataType.String))
     {
         Message message3 = new Message(this.m_RValue)
         {
             Id       = 9,
             Text     = string.Format("RHS of the assignment evaluates to a string. Strings are difficult to cache - consider using FORMAT_STRING property for value formatting", new object[0]),
             Severity = 2
         };
         analyzer.Add(message3);
     }
 }
Ejemplo n.º 2
0
 internal void FindLoops(Analyzer analyzer)
 {
     foreach (Vertex vertex in this.m_Vertices.Values)
     {
         bool flag = false;
         foreach (Vertex vertex2 in this.GetOutgoingTransitiveClosure(vertex))
         {
             foreach (Vertex vertex3 in vertex2.Outgoing)
             {
                 if (vertex3.Name.Equals(vertex.Name, StringComparison.InvariantCultureIgnoreCase))
                 {
                     flag = true;
                     break;
                 }
             }
             if (flag)
             {
                 break;
             }
         }
         if (flag)
         {
             Message m = new Message(vertex.Node)
             {
                 Severity = 3,
                 Text     = string.Format("Calculation {0} recursively refers to itself. Recursion disables block optimization mode", vertex.Name),
                 Id       = 0x2d
             };
             analyzer.Add(m);
         }
     }
 }
Ejemplo n.º 3
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (this.m_Set.GetType() == typeof(MDXFunctionNode))
     {
         MDXFunctionNode set = this.m_Set as MDXFunctionNode;
         if (set.m_Function.Equals("Filter", StringComparison.InvariantCultureIgnoreCase))
         {
             Message m = new Message(this)
             {
                 Id       = 0x11,
                 Text     = "'NON EMPTY Filter(set, cond)' can be rewritten more efficiently as 'NON EMPTY set HAVING cond'",
                 Severity = 2
             };
             analyzer.Add(m);
         }
     }
     this.m_Set.Analyze(analyzer);
 }
Ejemplo n.º 4
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (this.m_Exp.GetType() == typeof(MDXFunctionNode))
     {
         MDXFunctionNode exp = this.m_Exp as MDXFunctionNode;
         if (exp.m_Function.Equals("NonEmpty", StringComparison.InvariantCultureIgnoreCase))
         {
             Message m = new Message(this.m_Exp)
             {
                 Id       = 6,
                 Text     = "Are you sure you want to use NonEmpty function and not NON EMPTY clause ? The results are different.",
                 Severity = 1
             };
             analyzer.Add(m);
         }
     }
     this.m_Exp.Analyze(analyzer);
 }
Ejemplo n.º 5
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (this.m_Components.Count > 1)
     {
         foreach (string str in this.m_Components)
         {
             if ((!str.StartsWith("[") && !str.StartsWith("&")) && !str.Equals("Measures", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message m = new Message(this)
                 {
                     Id       = 11,
                     Text     = string.Format("Looks like object '{0}' is referenced not by its unique name. Use of unique names in MDX is recommended", this.GetLabel()),
                     Severity = 1
                 };
                 analyzer.Add(m);
                 break;
             }
         }
     }
 }
Ejemplo n.º 6
0
 internal override void Analyze(Analyzer analyzer)
 {
     if (base.Exp.GetMDXType() == MDXDataType.String)
     {
         Message m = new Message(base.Exp)
         {
             Id       = 5,
             Text     = string.Format("Calculated member '{0}' evaluates to a string. Strings are difficult to cache - consider using FORMAT_STRING property for value formatting", base.Name.GetLabel()),
             Severity = 2
         };
         analyzer.Add(m);
     }
     try
     {
         analyzer.InRHS = true;
         base.Exp.Analyze(analyzer);
     }
     finally
     {
         analyzer.InRHS = false;
     }
     base.Analyze(analyzer);
 }
Ejemplo n.º 7
0
 protected void StartAnalyze(Analyzer analyzer)
 {
     if ((!this.IsCacheTrivial() && !analyzer.InCommonSubExpr) && ((base.GetType() == typeof(MDXUnaryOpNode)) || (this.GetMDXType() != MDXDataType.Set)))
     {
         MDXExpNode node;
         if (analyzer.SeenExprs.TryGetValue(this.GetNormalizedMDX(), out node))
         {
             Message m = new Message(this)
             {
                 Id       = 10,
                 Text     = string.Format("Same expression was used before at Line {0} Column {1}. Consider eliminating common subexpressions for better performance and to take advantage of cache", node.Locator.Line, node.Locator.Column),
                 Severity = 2
             };
             analyzer.Add(m);
             analyzer.InCommonSubExpr = true;
             this.m_IsCommonSubExpr   = true;
         }
         else
         {
             analyzer.SeenExprs.Add(this.GetDebugMDX(), this);
         }
     }
 }
Ejemplo n.º 8
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     try
     {
         base.StartAnalyze(analyzer);
         if (!analyzer.InCommonSubExpr)
         {
             this.m_Exp1.Analyze(analyzer);
             if (this.m_Op.Equals("=") || this.m_Op.Equals("<>"))
             {
                 if (IsNameFunction(this.m_Exp1) || IsNameFunction(this.m_Exp2))
                 {
                     Message m = new Message(this)
                     {
                         Id       = 12,
                         Text     = "Use IS operator to compare objects instead of comparing them by name",
                         URL      = "http://sqlblog.com/blogs/mosha/archive/2004/11/04/comparing-members-in-mdx.aspx",
                         Severity = 3
                     };
                     analyzer.Add(m);
                 }
                 if (!this.m_Exp1.IsScalar() && !this.m_Exp2.IsScalar())
                 {
                     Message message2 = new Message(this)
                     {
                         Id       = 13,
                         Text     = string.Format("Operator '{0}' compares cell values. Consider comparing objects instead with IS operator", this.m_Op),
                         Severity = 4
                     };
                     analyzer.Add(message2);
                 }
                 if (this.m_Exp1.GetLabel().Equals("NULL", StringComparison.InvariantCultureIgnoreCase) || this.m_Exp2.GetLabel().Equals("NULL", StringComparison.InvariantCultureIgnoreCase))
                 {
                     Message message3 = new Message(this)
                     {
                         Id       = 14,
                         Text     = "If you want to avoid division by zero - use 'value = 0' check, if you want to check whether cell is empty - use IsEmpty function, if you want to check that MDX member or tuple exists - use 'obj IS NULL' check",
                         URL      = "http://sqlblog.com/blogs/mosha/archive/2005/06/30/how-to-check-if-cell-is-empty-in-mdx.aspx",
                         Severity = 3
                     };
                     analyzer.Add(message3);
                 }
             }
             if (this.m_Op.Equals("IS", StringComparison.InvariantCultureIgnoreCase) && (this.m_Exp1.GetLabel().Equals("NULL", StringComparison.InvariantCultureIgnoreCase) || this.m_Exp2.GetLabel().Equals("NULL", StringComparison.InvariantCultureIgnoreCase)))
             {
                 Message message4 = new Message(this)
                 {
                     Id       = 15,
                     Text     = "If you want to avoid division by zero - use 'value = 0' check, if you want to check whether cell is empty - use IsEmpty function, if you want to check that MDX member or tuple exists - use 'obj IS NULL' check",
                     URL      = "http://sqlblog.com/blogs/mosha/archive/2005/06/30/how-to-check-if-cell-is-empty-in-mdx.aspx",
                     Severity = 3
                 };
                 analyzer.Add(message4);
             }
             if (this.m_Op.Equals("*") && (this.m_Exp1.GetLabel().Equals("100") || this.m_Exp2.GetLabel().Equals("100")))
             {
                 Message message5 = new Message(this)
                 {
                     Id       = 0x10,
                     Text     = "Are you trying to convert to percentage by multiplying by 100 ? If yes, consider using FORMAT_STRING='Percent' instead",
                     Severity = 1
                 };
                 analyzer.Add(message5);
             }
             if (this.IsCompareOp() && ((IsFunction(this.m_Exp1, "Rank") && IsConstant(this.m_Exp2, 0)) || (IsFunction(this.m_Exp2, "Rank") && IsConstant(this.m_Exp1, 0))))
             {
                 Message message6 = new Message(this)
                 {
                     Id       = 0x2c,
                     Text     = "Check inclusion of the element in the set can be done more efficiently with Intersect rather than with Rank",
                     Severity = 1
                 };
                 analyzer.Add(message6);
             }
             this.m_Exp2.Analyze(analyzer);
         }
     }
     finally
     {
         base.EndAnalyze(analyzer);
     }
 }
Ejemplo n.º 9
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (!base.m_IsCommonSubExpr)
     {
         if (base.m_Function.Contains("."))
         {
             Message m = new Message(this)
             {
                 Id       = 30,
                 Text     = string.Format("The usage of user-defined stored procedure '{0}' will disable block computation mode", base.m_Function),
                 Severity = 3,
                 URL      = "http://sqlblog.com/blogs/mosha/archive/2007/04/19/best-practices-for-server-adomd-net-stored-procedures.aspx"
             };
             analyzer.Add(m);
         }
         if (base.m_Function.StartsWith("StrTo", StringComparison.InvariantCultureIgnoreCase))
         {
             bool flag = false;
             if (((base.m_Arguments.Count >= 2) && (base.m_Arguments[1].GetType() == typeof(MDXFlagNode))) && (base.m_Arguments[1] as MDXFlagNode).GetLabel().Equals("CONSTRAINED"))
             {
                 flag = true;
             }
             if (!flag)
             {
                 Message message2 = new Message(this)
                 {
                     Id       = 0x1f,
                     Text     = string.Format("'{0}' function without CONSTRAINED flag will disable block computation mode", base.m_Function),
                     Severity = 3,
                     URL      = "http://crawlmsdn.microsoft.com/en-us/library/bb934106(SQL.100).aspx"
                 };
                 analyzer.Add(message2);
             }
         }
         if (base.XofY("IIF", "IIF"))
         {
             Message message3 = new Message(this)
             {
                 Id       = 0x20,
                 Text     = string.Format("AS2008 only: Nested IIFs can be rewritten more efficiently as CASE operator", new object[0]),
                 Severity = 2
             };
             analyzer.Add(message3);
         }
         if ((((base.m_Function.Equals("Order", StringComparison.InvariantCultureIgnoreCase) || base.m_Function.Equals("Filter", StringComparison.InvariantCultureIgnoreCase)) || (base.m_Function.StartsWith("Top", StringComparison.InvariantCultureIgnoreCase) || base.m_Function.StartsWith("Bottom", StringComparison.InvariantCultureIgnoreCase))) || (base.m_Function.Equals("NonEmpty", StringComparison.InvariantCultureIgnoreCase) || base.m_Function.Equals("Exists", StringComparison.InvariantCultureIgnoreCase))) && base.XofY(base.m_Function, base.m_Function))
         {
             Message message4 = new Message(this)
             {
                 Id       = 0x21,
                 Text     = string.Format("Calling {0}({0}) is not good for performance, consider rewriting as single {0} call", base.m_Function),
                 Severity = 2
             };
             analyzer.Add(message4);
         }
         if (analyzer.InRHS && base.m_Function.Equals("Order", StringComparison.InvariantCultureIgnoreCase))
         {
             Message message5 = new Message(this)
             {
                 Id       = 0x22,
                 Text     = string.Format("Due to bug in Order function, consider rewriting Order(set,exp,BDESC) as TopCount(set,set.Count,exp)", new object[0]),
                 Severity = 1,
                 URL      = "http://cwebbbi.spaces.live.com/blog/cns!7B84B0F2C239489A!1262.entry"
             };
             analyzer.Add(message5);
         }
         if (base.XofY("Filter", "CrossJoin"))
         {
             Message message6 = new Message(this)
             {
                 Id       = 0x23,
                 Text     = string.Format("Consider rewriting Filter(CrossJoin(set)) as CrossJoin(Filter()) for improved performance", new object[0]),
                 Severity = 1
             };
             analyzer.Add(message6);
         }
         if (base.XofY("Filter", "Order"))
         {
             Message message7 = new Message(this)
             {
                 Id       = 0x24,
                 Text     = string.Format("Consider changing Filter(Order(set)) to Order(Filter()) for better performance", new object[0]),
                 Severity = 3
             };
             analyzer.Add(message7);
         }
         if (base.XofY("NonEmpty", "Order"))
         {
             Message message8 = new Message(this)
             {
                 Id       = 0x25,
                 Text     = string.Format("Consider changing NonEmpty(Order(set)) to Order(NonEmpty()) for better performance", new object[0]),
                 Severity = 3
             };
             analyzer.Add(message8);
         }
         if (base.XofY("Count", "Filter"))
         {
             Message message9 = new Message(this)
             {
                 Id       = 0x26,
                 Text     = string.Format("Consider rewriting Count(Filter(set, cond)) construct as Sum(set, summator) with summator IIF(cond, 1, NULL)", new object[0]),
                 URL      = "http://sqlblog.com/blogs/mosha/archive/2007/11/22/optimizing-count-filter-expressions-in-mdx.aspx",
                 Severity = 2
             };
             analyzer.Add(message9);
         }
         if ((base.m_Function.Equals("Filter", StringComparison.InvariantCultureIgnoreCase) && (base.m_Arguments.Count > 1)) && (base.m_Arguments[1].GetType() == typeof(MDXBinOpNode)))
         {
             bool         flag2 = false;
             MDXBinOpNode node  = base.m_Arguments[1] as MDXBinOpNode;
             if (node.m_Exp1.GetType() == typeof(MDXPropertyNode))
             {
                 MDXPropertyNode node2 = node.m_Exp1 as MDXPropertyNode;
                 if (node2.m_Function.Equals("Properties", StringComparison.InvariantCultureIgnoreCase))
                 {
                     flag2 = true;
                 }
             }
             if (node.m_Exp2.GetType() == typeof(MDXPropertyNode))
             {
                 MDXPropertyNode node3 = node.m_Exp2 as MDXPropertyNode;
                 if (node3.m_Function.Equals("Properties", StringComparison.InvariantCultureIgnoreCase))
                 {
                     flag2 = true;
                 }
             }
             if (flag2)
             {
                 Message message10 = new Message(this)
                 {
                     Id       = 0x27,
                     Text     = string.Format("Consider rewriting Filter(set, h.Properties() {0} ...) using Exists function", node.m_Op),
                     Severity = 2
                 };
                 analyzer.Add(message10);
             }
         }
         if (base.XofY("Rank", "Order"))
         {
             Message message11 = new Message(this)
             {
                 Id       = 40,
                 Text     = string.Format("Consider rewriting Rank(item, Order(set, sort_criteria)) as Rank(item, set, sort_criteria) or using DYNAMIC sets", new object[0]),
                 URL      = "http://sqlblog.com/blogs/mosha/archive/2006/03/14/ranking-in-mdx.aspx",
                 Severity = 5
             };
             analyzer.Add(message11);
         }
         if (base.XofY("Aggregate", ".ALLMEMBERS"))
         {
             Message message12 = new Message(this)
             {
                 Id       = 0x29,
                 Text     = string.Format("Aggregate(<o>.ALLMEMBERS) will break when there will be calculated members. Use Aggregate(<o>.MEMBERS) instead.", new object[0]),
                 Severity = 5
             };
             analyzer.Add(message12);
         }
         if (base.XofY("Tail", "Head") || base.XofY("Head", "Tail"))
         {
             Message message13 = new Message(this)
             {
                 Id       = 0x2a,
                 Text     = string.Format("Consider using MDX function SubSet instead of Tail(Head(...)) construct", new object[0]),
                 Severity = 0
             };
             analyzer.Add(message13);
         }
         if (base.XofY("Count", "Descendants"))
         {
             Message message14 = new Message(this)
             {
                 Id       = 0x2b,
                 Text     = string.Format("If you are trying to count number of members in current selection - consider introducing special measure group for this dimension", new object[0]),
                 URL      = "http://sqlblog.com/blogs/mosha/archive/2007/05/27/counting-days-in-mdx.aspx",
                 Severity = 2
             };
             analyzer.Add(message14);
         }
     }
 }
Ejemplo n.º 10
0
 internal override void Analyze(Analyzer analyzer)
 {
     base.Analyze(analyzer);
     if (this.m_ExpressionUsedSingleQuotes)
     {
         Message m = new Message(this.m_Exp)
         {
             Id       = 1,
             Text     = string.Format("Don't use single quotes for definitions of calculation {0}", this.m_Name.GetLabel()),
             Severity = 0,
             URL      = "http://sqlblog.com/blogs/mosha/archive/2005/04/02/to-quote-or-not-to-quote-in-expressions-of-mdx-calculations.aspx"
         };
         analyzer.Add(m);
     }
     if (this.m_CalcProps != null)
     {
         foreach (MDXCalcPropNode node in this.m_CalcProps)
         {
             if (node.PropertyName.Equals("NON_EMPTY_BEHAVIOR", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message message2 = new Message(node)
                 {
                     Id       = 2,
                     Text     = string.Format("AS2008 only: Consider removing NON_EMPTY_BEHAVIOR property for '{0}'", this.m_Name.GetLabel()),
                     Severity = 2
                 };
                 analyzer.Add(message2);
             }
             else
             {
                 Type t = node.PropertyExp.GetType();
                 if ((!node.PropertyName.Equals("SOLVE_ORDER", StringComparison.InvariantCultureIgnoreCase) && !MDXNode.IsConstantNode(t)) && (t != typeof(MDXIDNode)))
                 {
                     Message message3 = new Message(node)
                     {
                         Id       = 3,
                         Text     = string.Format("Calculation property '{0}' of '{1}' is not a constant or member reference. Therefore it will not benefit from neiter block computation mode, nor caching", node.PropertyName, this.m_Name.GetLabel()),
                         Severity = 4
                     };
                     analyzer.Add(message3);
                 }
             }
             if (node.PropertyName.Equals("VISIBLE", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message message4 = new Message(node)
                 {
                     Id       = 4,
                     Severity = 0,
                     URL      = "http://technet.microsoft.com/en-us/library/ms144787(SQL.100).aspx"
                 };
                 if (node.PropertyExp.GetLabel().Equals("0") || node.PropertyExp.GetLabel().Equals("false", StringComparison.InvariantCultureIgnoreCase))
                 {
                     message4.Text = "Consider using 'CREATE HIDDEN ...' syntax instead of ',VISIBLE=0'";
                 }
                 else
                 {
                     message4.Text = string.Format("'VISIBLE={0}' is redundant, since {1} is visible by default", node.PropertyExp.GetMDX(-1), this.m_Name.GetLabel());
                 }
                 analyzer.Add(message4);
             }
             node.PropertyExp.Analyze(analyzer);
         }
     }
 }
Ejemplo n.º 11
0
 internal override void Analyze(Analyzer analyzer)
 {
     try
     {
         base.StartAnalyze(analyzer);
         if (!analyzer.InCommonSubExpr)
         {
             base.Analyze(analyzer);
             if (this.m_Object != null)
             {
                 if (this.m_Object.Optimization == MDXFunctionOpt.Deprecated)
                 {
                     Message m = new Message(this)
                     {
                         Id       = 0x12,
                         Text     = string.Format("MDX function '{0}' is deprecated", this.m_Function),
                         Severity = 5
                     };
                     analyzer.Add(m);
                 }
                 else if (this.m_Object.Optimization == MDXFunctionOpt.Bad)
                 {
                     Message message2 = new Message(this)
                     {
                         Id       = 0x13,
                         Text     = string.Format("MDX function '{0}' generaly has very bad performance and should be avoided", this.m_Function),
                         Severity = 5
                     };
                     analyzer.Add(message2);
                 }
                 else if (((this.m_Object.Optimization == MDXFunctionOpt.Normal) && (this.m_Object.ReturnType != MDXDataType.Set)) && analyzer.InRHS)
                 {
                     Message message3 = new Message(this)
                     {
                         Id       = 20,
                         Text     = string.Format("MDX function '{0}' is not optimized for block computation mode", this.m_Function),
                         Severity = 3,
                         URL      = "http://crawlmsdn.microsoft.com/en-us/library/bb934106(SQL.100).aspx"
                     };
                     analyzer.Add(message3);
                 }
             }
             if ((this.m_Function.Equals("Username", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Member_Caption", StringComparison.InvariantCultureIgnoreCase)) || this.m_Function.Equals("CustomData", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message message4 = new Message(this)
                 {
                     Id       = 0x15,
                     Text     = string.Format("MDX function '{0}' prevents cache sharing between different users", this.m_Function),
                     Severity = 2
                 };
                 analyzer.Add(message4);
             }
             if (this.m_Function.Equals("VisualTotals", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Axis", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message message5 = new Message(this)
                 {
                     Id       = 0x16,
                     Text     = string.Format("MDX function '{0}' prevents use of global formula engine cache", this.m_Function),
                     Severity = 4
                 };
                 analyzer.Add(message5);
             }
             if (analyzer.InLHS && this.m_Function.Equals("MemberValue", StringComparison.InvariantCultureIgnoreCase))
             {
                 Message message6 = new Message(this)
                 {
                     Id       = 0x17,
                     Text     = string.Format("MDX function '{0}' used in named set or SCOPE prevents use of global formula engine cache", this.m_Function),
                     Severity = 4
                 };
                 analyzer.Add(message6);
             }
             if (((this.m_Function.Equals("Aggregate", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Sum", StringComparison.InvariantCultureIgnoreCase)) || ((this.m_Function.Equals("Min", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Max", StringComparison.InvariantCultureIgnoreCase)) || this.m_Function.Equals("Avg", StringComparison.InvariantCultureIgnoreCase))) && (this.m_Arguments.Count > 0))
             {
                 MDXExpNode n = this.m_Arguments[0];
                 if ((n.GetMDXType() != MDXDataType.Set) && (n.GetMDXType() != MDXDataType.Level))
                 {
                     if ((n.GetType() == typeof(MDXIDNode)) && !(n as MDXIDNode).GetLabel().Contains("."))
                     {
                         Message message7 = new Message(this)
                         {
                             Id       = 0x2e,
                             Text     = string.Format("Applying aggregation funciton {0} over named set {1} - this disables block computation mode", this.m_Function, n.GetLabel()),
                             Severity = 1,
                             URL      = "http://msdn.microsoft.com/en-us/library/bb934106.aspx"
                         };
                         analyzer.Add(message7);
                     }
                     else
                     {
                         Message message8 = new Message(n)
                         {
                             Id       = 0x18,
                             Text     = string.Format("It looks like MDX aggregation function '{0}' is called over set with single element. Is that the intent ?", this.m_Function),
                             Severity = 1
                         };
                         analyzer.Add(message8);
                     }
                 }
                 else
                 {
                     this.CheckSetForAggregateFunction(n, analyzer);
                 }
             }
             if ((analyzer.InRHS && !analyzer.IsInExisting()) && ((this.m_Function.Equals("MEMBERS", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Siblings", StringComparison.InvariantCultureIgnoreCase)) || (this.XofY("Children", ".Parent") || this.XofY("Descendants", ".Parent"))))
             {
                 Message message9 = new Message(this)
                 {
                     Id       = 0x19,
                     Text     = string.Format("This set causes the expression to evaluate to the same value over different coordinates. Consider redirecting to coordinate with non-varying attribute to take advantage of cache", new object[0]),
                     Severity = 2,
                     URL      = "http://sqlblog.com/blogs/mosha/archive/2008/03/28/take-advantage-of-fe-caching-to-optimize-mdx-performance.aspx"
                 };
                 analyzer.Add(message9);
             }
             if (analyzer.InRHS && ((((this.m_Function.Equals("CurrentMember", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Parent", StringComparison.InvariantCultureIgnoreCase)) || (this.m_Function.Equals("PrevMember", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("NextMember", StringComparison.InvariantCultureIgnoreCase))) || ((this.m_Function.Equals("Lag", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Lead", StringComparison.InvariantCultureIgnoreCase)) || (this.m_Function.Equals("FirstChild", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("LastChild", StringComparison.InvariantCultureIgnoreCase)))) || (((this.m_Function.Equals("FirstSibling", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("LastSibling", StringComparison.InvariantCultureIgnoreCase)) || (this.m_Function.Equals("ParallelPeriod", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Cousin", StringComparison.InvariantCultureIgnoreCase))) || (((this.m_Function.Equals("PeriodsToDate", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("YTD", StringComparison.InvariantCultureIgnoreCase)) || (this.m_Function.Equals("QTD", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("MTD", StringComparison.InvariantCultureIgnoreCase))) || ((this.m_Function.Equals("WTD", StringComparison.InvariantCultureIgnoreCase) || this.m_Function.Equals("Ancestor", StringComparison.InvariantCultureIgnoreCase)) || this.m_Function.Equals("Ancestors", StringComparison.InvariantCultureIgnoreCase))))))
             {
                 Message message10 = new Message(this)
                 {
                     Id       = 0x1a,
                     Text     = string.Format("MDX function '{0}' may raise an error or produce non-desired result when user applies multiselect", this.m_Function),
                     Severity = 1,
                     URL      = "http://sqlblog.com/blogs/mosha/archive/2007/01/13/multiselect-friendly-mdx-for-calculations-looking-at-current-coordinate.aspx"
                 };
                 analyzer.Add(message10);
             }
             this.m_Arguments.Analyze(analyzer);
         }
     }
     finally
     {
         base.EndAnalyze(analyzer);
     }
 }
Ejemplo n.º 12
0
 private void CheckSetForAggregateFunction(MDXExpNode e, Analyzer analyzer)
 {
     if (e.GetMDXType() == MDXDataType.Set)
     {
         Type type = e.GetType();
         if ((type == typeof(MDXFunctionNode)) || (type == typeof(MDXPropertyNode)))
         {
             MDXBaseFunctionNode n = e as MDXBaseFunctionNode;
             if ((((!n.m_Function.Equals("MTD", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("QTD", StringComparison.InvariantCultureIgnoreCase)) && (!n.m_Function.Equals("YTD", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("WTD", StringComparison.InvariantCultureIgnoreCase))) && ((!n.m_Function.Equals("PeriodsToDate", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("AddCalculatedMembers", StringComparison.InvariantCultureIgnoreCase)) && (!n.m_Function.Equals("PeriodsToDate", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("Tail", StringComparison.InvariantCultureIgnoreCase)))) && (((!n.m_Function.Equals("Descendants", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("Distinct", StringComparison.InvariantCultureIgnoreCase)) && (!n.m_Function.Equals("Unorder", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("Hierarchize", StringComparison.InvariantCultureIgnoreCase))) && ((!n.m_Function.Equals("Children", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("MEMBERS", StringComparison.InvariantCultureIgnoreCase)) && (!n.m_Function.Equals("Siblings", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("ALLMEMBERS", StringComparison.InvariantCultureIgnoreCase)))))
             {
                 if (!n.m_Function.Equals("StrToSet", StringComparison.InvariantCultureIgnoreCase))
                 {
                     if ((!n.m_Function.Equals("Except", StringComparison.InvariantCultureIgnoreCase) && !n.m_Function.Equals("Union", StringComparison.InvariantCultureIgnoreCase)) && !n.m_Function.Equals("Intersect", StringComparison.InvariantCultureIgnoreCase))
                     {
                         if (!n.m_Function.Equals("CrossJoin", StringComparison.InvariantCultureIgnoreCase))
                         {
                             Message m = new Message(n)
                             {
                                 Id       = 0x1b,
                                 Severity = 5,
                                 Text     = string.Format("Function '{0}' was used inside aggregation function - this disables block computation mode", n.m_Function),
                                 URL      = "http://msdn.microsoft.com/en-us/library/bb934106.aspx"
                             };
                             analyzer.Add(m);
                         }
                         else
                         {
                             foreach (MDXExpNode node2 in n.m_Arguments)
                             {
                                 this.CheckSetForAggregateFunction(node2, analyzer);
                             }
                         }
                     }
                     else
                     {
                         if (n.m_Arguments.Count > 1)
                         {
                             this.CheckSetForAggregateFunction(n.m_Arguments[0], analyzer);
                         }
                         if (n.m_Arguments.Count > 2)
                         {
                             this.CheckSetForAggregateFunction(n.m_Arguments[1], analyzer);
                         }
                     }
                 }
             }
             else if (n.m_Arguments.Count > 1)
             {
                 this.CheckSetForAggregateFunction(n.m_Arguments[0], analyzer);
             }
         }
         else if (type == typeof(MDXBinOpNode))
         {
             MDXBinOpNode node3 = e as MDXBinOpNode;
             if ((!node3.m_Op.Equals("-") && !node3.m_Op.Equals("*")) && (!node3.m_Op.Equals(":") && !node3.m_Op.Equals("+")))
             {
                 Message message2 = new Message(node3)
                 {
                     Id       = 0x1c,
                     Severity = 5,
                     Text     = string.Format("Operator '{0}' was used inside aggregation function - this disables block computation mode", node3.m_Op),
                     URL      = "http://crawlmsdn.microsoft.com/en-us/library/bb934106(SQL.100).aspx"
                 };
                 analyzer.Add(message2);
             }
             if (!node3.Equals(":"))
             {
                 this.CheckSetForAggregateFunction(node3.m_Exp1, analyzer);
                 this.CheckSetForAggregateFunction(node3.m_Exp2, analyzer);
             }
         }
         else if (type == typeof(MDXUnaryOpNode))
         {
             MDXUnaryOpNode node4 = e as MDXUnaryOpNode;
             if (!node4.m_Op.Equals("-"))
             {
                 Message message3 = new Message(node4)
                 {
                     Id       = 0x1d,
                     Severity = 5,
                     Text     = string.Format("Operator '{0}' was used inside aggregation function - this disables block computation mode", node4.m_Op),
                     URL      = "http://crawlmsdn.microsoft.com/en-us/library/bb934106(SQL.100).aspx"
                 };
                 analyzer.Add(message3);
             }
             this.CheckSetForAggregateFunction(node4.m_Exp, analyzer);
         }
         else if (type == typeof(MDXTupleNode))
         {
             MDXTupleNode node5 = e as MDXTupleNode;
             foreach (MDXExpNode node6 in node5.m_List)
             {
                 this.CheckSetForAggregateFunction(node6, analyzer);
             }
         }
         else if (type == typeof(MDXEnumSetNode))
         {
             MDXEnumSetNode node7 = e as MDXEnumSetNode;
             foreach (MDXExpNode node8 in node7.m_List)
             {
                 this.CheckSetForAggregateFunction(node8, analyzer);
             }
         }
     }
 }