public RepeatClause(AbstractClause _clause, int minnum, int maxnum) { clause = _clause; minNum = minnum; maxNum = maxnum; }
/// <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; } } } }
public ArgumentClause(AbstractClause _clause, object arg) { clause = _clause; clauseArg = arg; }