예제 #1
0
 public RepeatClause(AbstractClause _clause, int minnum, int maxnum)
 {
     clause = _clause;
     minNum = minnum;
     maxNum = maxnum;
 }
예제 #2
0
        /// <summary>
        /// 这里不考虑COMPUTE与UNION运算,使用COMPUTE的场合不应使用本类,如果实际需要使用UNION,需要写成视图,
        /// 再写视图查询,或者如在MS SQL SERVER中使用内联视图。
        /// 我们只关心SELECT语句的第一层的构成,并且我们假定SQL语句语法是正确的,因些可以忽略许多
        /// 细节的语法,语法构造的EBNF如下:(T表示终截符)
        /// EXP::=[T*][(( '(' SELECT | (EXP ( , EXP )*) ')' ) | T)* ]
        /// EXPLIST::=EXP ( , EXP )*
        /// SELECT::=select EXPLIST from EXPLIST [where EXP][group by EXPLIST [having EXP]][order by EXPLIST]
        /// 因为我们不希望实面全SQL语法的分析,别名关键字AS在语法中成为上下文相关的,这样我们不在语法中定义它,
        /// 而在语法分析完成后,对语法片断采用正则表达式或字符串处理进一点分析。
        /// </summary>
        /// <param name="sqlstr"></param>
        public SQLSelectParser(string sqlstr)
        {
            context = new SQLParserContext(sqlstr);
            AndClause selectQuery = AbstractClause.NewAnd;

            OrClause exp = AbstractClause.NewOr;

            exp.Build(AbstractClause.Terminal.Repeat(),
                      AbstractClause.Identic.And("(",
                                                 selectQuery.Alternative(exp.And(AbstractClause.Identic.And(",", exp).Repeat())),
                                                 ")")[SQLParserClauseType.PARENTHESES].Alternative(AbstractClause.Terminal).Repeat()
                      );  //表达式语法定义
            AbstractClause expression = exp[SQLParserClauseType.EXPRESSION];

            AbstractClause expList = expression.And(AbstractClause.Identic.And(",", expression).Repeat());         //表达式列表语法定义

            selectQuery.Build("select",
                              expList[SQLParserClauseType.SELECT][SQLParserClauseType.COUNT],
                              AbstractClause.Identic.And("from", expList)[SQLParserClauseType.FROM][SQLParserClauseType.COUNT][SQLParserClauseType.COUNT],
                              AbstractClause.Nilpotent.Or(
                                  AbstractClause.Identic.And("where", expression[SQLParserClauseType.WHERE]),
                                  AbstractClause.Identic.And("group by", expList[SQLParserClauseType.GROUPBYLIST].Or("having", expression[SQLParserClauseType.HAVING])
                                                             ),
                                  AbstractClause.Identic.And("order by", expList[SQLParserClauseType.ORDERBYLIST])
                                  )[SQLParserClauseType.COUNT][SQLParserClauseType.COUNT][SQLParserClauseType.COUNT]
                              );  //SELECT语句语法定义

            selectQuery.Parse(context);
            //表别名处理
            Parentheses.Sort(new StringLengthComparer());
            noParenthesesFrom = context.FromClause;
            int pi = 0;

            foreach (string s in Parentheses)
            {
                noParenthesesFrom = noParenthesesFrom.Replace(s, "__EXP" + pi + "__");
                pi++;
            }
            string regex = @"
(?:
	from\s+(\w+(?:\s+(?!left)(?!rigth)(?!full)(?!inner)(?!outer)(?!join)\w+)?)\s*
		(?:
			(?:
				(?:
					(?:
						left|right|full|inner|outer|join
					)
					\s+
				)+
				(\w+(?:\s+(?!on)\w+)?)
				\s+on\s+(?:(?!left)(?!rigth)(?!full)(?!inner)(?!outer)(?!join)[^\s]+\s*)+
			)+
			|	
			(?:,\s*(\w+(?:\s+\w+)?)\s*)+
		)?
)";

            System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Multiline)
                                                                   | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(regex, options);

            string regex0 = "(\\w+)(?:\\s+(\\w+))?";

            System.Text.RegularExpressions.Regex reg0 = new System.Text.RegularExpressions.Regex(regex0, options);

            Match m = reg.Match(noParenthesesFrom);

            if (m.Success)
            {
                for (int i = 1; i <= 3; i++)
                {
                    Group g = m.Groups[i];
                    foreach (Capture c in g.Captures)
                    {
                        Match m0 = reg0.Match(c.Value);
                        if (m0.Success)
                        {
                            if (m0.Groups[2].Captures.Count > 0)
                            {
                                tableAlias[m0.Groups[1].Value] = m0.Groups[2].Value;
                            }
                            else
                            {
                                tableAlias[m0.Groups[1].Value] = m0.Groups[1].Value;
                            }
                        }
                    }
                }
            }
            //select 列表处理
            for (int i = 0; i < Expressions.Count; i++)
            {
                string field = Expressions[i] as string;
                //消除[all | distinct][top n [percent] [with ties]]
                Regex regexp = new Regex("^(?:all|distinct)?\\s*(?:top\\s+[0-9]{0,3}\\s*(?:percent)?\\s*(?:with\\s+ties)?)?", options);
                Match match  = regexp.Match(field.ToLower());
                if (match.Success)
                {
                    field          = field.Substring(match.Index + match.Length);
                    Expressions[i] = field;
                }
                break;
            }
            //处理SELECT列表,构造字段原始名与别名的对应关系,SQL语句中的*号无法在语法分析时扩展成各个列名
            string regex1 = "(.*)(?:\\s+as\\s+(\\w+))?\\s* ";

            System.Text.RegularExpressions.RegexOptions options1 = (((System.Text.RegularExpressions.RegexOptions.RightToLeft | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)
                                                                     | System.Text.RegularExpressions.RegexOptions.Multiline)
                                                                    | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex reg1 = new System.Text.RegularExpressions.Regex(regex1, options1);

            string regex2 = "(\\w+)\\.(\\w+)";

            System.Text.RegularExpressions.RegexOptions options2 = (((System.Text.RegularExpressions.RegexOptions.RightToLeft | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)
                                                                     | System.Text.RegularExpressions.RegexOptions.Multiline)
                                                                    | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            System.Text.RegularExpressions.Regex reg2 = new System.Text.RegularExpressions.Regex(regex2, options2);

            for (int i = 0; i < Expressions.Count; i++)
            {
                string field = Expressions[i] as string;
                Match  match = reg1.Match(field);
                if (match.Success)
                {
                    if (match.Groups[2].Captures.Count > 0)
                    {
                        fieldAlias[match.Groups[1].Value] = match.Groups[2].Value;
                        fieldNames[match.Groups[2].Value] = match.Groups[1].Value;
                    }
                    else
                    {
                        string alias = match.Groups[1].Value;
                        Match  mm    = reg2.Match(alias);
                        if (mm.Success)
                        {
                            alias = mm.Groups[2].Value;
                        }
                        fieldAlias[match.Groups[1].Value] = alias;
                        fieldNames[alias] = match.Groups[1].Value;
                    }
                }
            }
        }
예제 #3
0
 public ArgumentClause(AbstractClause _clause, object arg)
 {
     clause    = _clause;
     clauseArg = arg;
 }