/// <exception cref="System.SqlSyntaxErrorException" /> private IExpression PrimaryExpression(string consumed , string consumedUp) { if (consumed != null) { return StartedFromIdentifier(consumed, consumedUp); } string tempStr; string tempStrUp; StringBuilder tempSb; Number tempNum; IExpression tempExpr; IExpression tempExpr2; IList<IExpression> tempExprList; switch (lexer.Token()) { case MySqlToken.PlaceHolder: { tempStr = lexer.GetStringValue(); tempStrUp = lexer.GetStringValueUppercase(); lexer.NextToken(); return CreatePlaceHolder(tempStr, tempStrUp); } case MySqlToken.LiteralBit: { tempStr = lexer.GetStringValue(); lexer.NextToken(); return new LiteralBitField(null, tempStr).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralHex: { var hex = new LiteralHexadecimal(null, lexer.Sql, lexer.OffsetCache, lexer.SizeCache, charset); lexer.NextToken(); return hex.SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralBoolFalse: { lexer.NextToken(); return new LiteralBoolean(false).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralBoolTrue: { lexer.NextToken(); return new LiteralBoolean(true).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralNull: { lexer.NextToken(); return new LiteralNull().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralNchars: { tempSb = new StringBuilder(); do { lexer.AppendStringContent(tempSb); } while (lexer.NextToken() == MySqlToken.LiteralChars); return new LiteralString(null, tempSb.ToString(), true).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralChars: { tempSb = new StringBuilder(); do { lexer.AppendStringContent(tempSb); } while (lexer.NextToken() == MySqlToken.LiteralChars); return new LiteralString(null, tempSb.ToString(), false).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralNumPureDigit: { tempNum = lexer.GetIntegerValue(); lexer.NextToken(); return new LiteralNumber(tempNum).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralNumMixDigit: { tempNum = lexer.GetDecimalValue(); lexer.NextToken(); return new LiteralNumber(tempNum).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.QuestionMark: { var index = lexer.ParamIndex; lexer.NextToken(); return CreateParam(index); } case MySqlToken.KwCase: { lexer.NextToken(); return CaseWhenExpression(); } case MySqlToken.KwInterval: { lexer.NextToken(); return IntervalExpression(); } case MySqlToken.KwExists: { lexer.NextToken(); Match(MySqlToken.PuncLeftParen); tempExpr = SubQuery(); Match(MySqlToken.PuncRightParen); return new ExistsPrimary((IQueryExpression)tempExpr).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.UsrVar: { tempStr = lexer.GetStringValue(); tempExpr = new UsrDefVarPrimary(tempStr).SetCacheEvalRst(cacheEvalRst); if (lexer.NextToken() == MySqlToken.OpAssign) { lexer.NextToken(); tempExpr2 = Expression(); return new AssignmentExpression(tempExpr, tempExpr2); } return tempExpr; } case MySqlToken.SysVar: { return SystemVariale(); } case MySqlToken.KwMatch: { lexer.NextToken(); return MatchExpression(); } case MySqlToken.PuncLeftParen: { lexer.NextToken(); if (lexer.Token() == MySqlToken.KwSelect) { tempExpr = SubQuery(); Match(MySqlToken.PuncRightParen); return tempExpr; } tempExpr = Expression(); switch (lexer.Token()) { case MySqlToken.PuncRightParen: { lexer.NextToken(); return tempExpr; } case MySqlToken.PuncComma: { lexer.NextToken(); tempExprList = new List<IExpression>(); tempExprList.Add(tempExpr); tempExprList = ExpressionList(tempExprList); return new RowExpression(tempExprList).SetCacheEvalRst(cacheEvalRst); } default: { throw Err("unexpected token: " + lexer.Token()); } } //goto case MySqlToken.KwUtcDate; } case MySqlToken.KwUtcDate: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new UtcDate(null).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwUtcTime: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new UtcTime(null).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwUtcTimestamp: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new UtcTimestamp(null).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwCurrentDate: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new Curdate().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwCurrentTime: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new Curtime().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwCurrentTimestamp: case MySqlToken.KwLocaltime: case MySqlToken.KwLocaltimestamp: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new Now().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwCurrentUser: { lexer.NextToken(); if (lexer.Token() == MySqlToken.PuncLeftParen) { lexer.NextToken(); Match(MySqlToken.PuncRightParen); } return new CurrentUser().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwDefault: { if (lexer.NextToken() == MySqlToken.PuncLeftParen) { return OrdinaryFunction(lexer.GetStringValue(), lexer.GetStringValueUppercase()); } return new DefaultValue().SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwDatabase: case MySqlToken.KwIf: case MySqlToken.KwInsert: case MySqlToken.KwLeft: case MySqlToken.KwRepeat: case MySqlToken.KwReplace: case MySqlToken.KwRight: case MySqlToken.KwSchema: case MySqlToken.KwValues: { tempStr = lexer.GetStringValue(); tempStrUp = lexer.GetStringValueUppercase(); var tempStrUp2 = lexer.Token().KeyWordToString(); if (!tempStrUp2.Equals(tempStrUp)) { tempStrUp = tempStr = tempStrUp2; } if (lexer.NextToken() == MySqlToken.PuncLeftParen) { return OrdinaryFunction(tempStr, tempStrUp); } throw Err("keyword not followed by '(' is not expression: " + tempStr); } case MySqlToken.KwMod: { lexer.NextToken(); Match(MySqlToken.PuncLeftParen); tempExpr = Expression(); Match(MySqlToken.PuncComma); tempExpr2 = Expression(); Match(MySqlToken.PuncRightParen); return new ArithmeticModExpression(tempExpr, tempExpr2).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.KwChar: { lexer.NextToken(); Match(MySqlToken.PuncLeftParen); return FunctionChar(); } case MySqlToken.KwConvert: { lexer.NextToken(); Match(MySqlToken.PuncLeftParen); return FunctionConvert(); } case MySqlToken.Identifier: { tempStr = lexer.GetStringValue(); tempStrUp = lexer.GetStringValueUppercase(); lexer.NextToken(); return StartedFromIdentifier(tempStr, tempStrUp); } case MySqlToken.OpAsterisk: { lexer.NextToken(); return new Wildcard(null).SetCacheEvalRst(cacheEvalRst); } default: { throw Err("unrecognized token as first token of primary: " + lexer.Token()); } } }
/// <summary> /// last token consumed is /// <see cref="MySqlToken.Identifier" /> /// , MUST NOT be /// <code>null</code> /// </summary> /// <exception cref="System.SqlSyntaxErrorException" /> private IExpression StartedFromIdentifier(string consumed, string consumedUp) { IExpression tempExpr; IExpression tempExpr2; IList<IExpression> tempExprList; string tempStr; StringBuilder tempSb; bool tempGroupDistinct; switch (lexer.Token()) { case MySqlToken.PuncDot: { for (tempExpr = new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); lexer.Token() == MySqlToken.PuncDot;) { switch (lexer.NextToken()) { case MySqlToken.Identifier: { tempExpr = new Identifier((Identifier)tempExpr, lexer.GetStringValue(), lexer.GetStringValueUppercase()).SetCacheEvalRst(cacheEvalRst); lexer.NextToken(); break; } case MySqlToken.OpAsterisk: { lexer.NextToken(); return new Wildcard((Identifier)tempExpr).SetCacheEvalRst(cacheEvalRst); } default: { throw Err("expect IDENTIFIER or '*' after '.', but is " + lexer.Token()); } } } return tempExpr; } case MySqlToken.LiteralBit: { if (consumed[0] != '_') { return new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); } tempStr = lexer.GetStringValue(); lexer.NextToken(); return new LiteralBitField(consumed, tempStr).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralHex: { if (consumed[0] != '_') { return new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); } var hex = new LiteralHexadecimal(consumed, lexer.Sql, lexer.OffsetCache, lexer.SizeCache, charset); lexer.NextToken(); return hex.SetCacheEvalRst(cacheEvalRst); } case MySqlToken.LiteralChars: { if (consumed[0] != '_') { return new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); } tempSb = new StringBuilder(); do { lexer.AppendStringContent(tempSb); } while (lexer.NextToken() == MySqlToken.LiteralChars); return new LiteralString(consumed, tempSb.ToString(), false).SetCacheEvalRst(cacheEvalRst); } case MySqlToken.PuncLeftParen: { consumedUp = IdentifierExpr.UnescapeName(consumedUp); switch (functionManager.GetParsingStrategy(consumedUp)) { case FunctionParsingStrategy.GetFormat: { // GET_FORMAT({DATE|TIME|DATETIME}, // {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'}) lexer.NextToken(); var gfi = MatchIdentifier("DATE", "TIME", "DATETIME", "TIMESTAMP"); Match(MySqlToken.PuncComma); var getFormatArg = Expression(); Match(MySqlToken.PuncRightParen); switch (gfi) { case 0: { return new GetFormat(GetFormat.FormatType.Date, getFormatArg); } case 1: { return new GetFormat(GetFormat.FormatType.Time, getFormatArg); } case 2: case 3: { return new GetFormat(GetFormat.FormatType.Datetime, getFormatArg); } } throw Err("unexpected format type for GET_FORMAT()"); } case FunctionParsingStrategy.Cast: { lexer.NextToken(); tempExpr = Expression(); Match(MySqlToken.KwAs); var type = Type4specialFunc(); Match(MySqlToken.PuncRightParen); var info = type.Value; if (info != null) { return new Cast(tempExpr, type.Key, info.Key, info.Value).SetCacheEvalRst( cacheEvalRst); } return new Cast(tempExpr, type.Key, null, null).SetCacheEvalRst(cacheEvalRst); //goto case FunctionParsingStrategy.Position; } case FunctionParsingStrategy.Position: { lexer.NextToken(); tempExprList = new List<IExpression>(2); tempExprList.Add(Expression()); Match(MySqlToken.KwIn); tempExprList.Add(Expression()); Match(MySqlToken.PuncRightParen); return new Locate(tempExprList).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Substring: { lexer.NextToken(); tempExprList = new List<IExpression>(3); tempExprList.Add(Expression()); Match(MySqlToken.PuncComma, MySqlToken.KwFrom); tempExprList.Add(Expression()); switch (lexer.Token()) { case MySqlToken.PuncComma: case MySqlToken.KwFor: { lexer.NextToken(); tempExprList.Add(Expression()); goto default; } default: { Match(MySqlToken.PuncRightParen); break; } } return new Substring(tempExprList).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Row: { lexer.NextToken(); tempExprList = ExpressionList(new List<IExpression>()); return new RowExpression(tempExprList).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Trim: { TrimDirection _trimDirection; switch (lexer.NextToken()) { case MySqlToken.KwBoth: { lexer.NextToken(); _trimDirection = TrimDirection.Both; break; } case MySqlToken.KwLeading: { lexer.NextToken(); _trimDirection = TrimDirection.Leading; break; } case MySqlToken.KwTrailing: { lexer.NextToken(); _trimDirection = TrimDirection.Trailing; break; } default: { _trimDirection = TrimDirection.Default; break; } } if (_trimDirection == TrimDirection.Default) { tempExpr = Expression(); if (lexer.Token() == MySqlToken.KwFrom) { lexer.NextToken(); tempExpr2 = Expression(); Match(MySqlToken.PuncRightParen); return new Trim(_trimDirection, tempExpr, tempExpr2).SetCacheEvalRst(cacheEvalRst); } Match(MySqlToken.PuncRightParen); return new Trim(_trimDirection, null, tempExpr).SetCacheEvalRst(cacheEvalRst); } if (lexer.Token() == MySqlToken.KwFrom) { lexer.NextToken(); tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Trim(_trimDirection, null, tempExpr).SetCacheEvalRst(cacheEvalRst); } tempExpr = Expression(); Match(MySqlToken.KwFrom); tempExpr2 = Expression(); Match(MySqlToken.PuncRightParen); return new Trim(_trimDirection, tempExpr, tempExpr2).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Avg: { if (lexer.NextToken() == MySqlToken.KwDistinct) { tempGroupDistinct = true; lexer.NextToken(); } else { tempGroupDistinct = false; } tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Avg(tempExpr, tempGroupDistinct).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Max: { if (lexer.NextToken() == MySqlToken.KwDistinct) { tempGroupDistinct = true; lexer.NextToken(); } else { tempGroupDistinct = false; } tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Max(tempExpr, tempGroupDistinct).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Min: { if (lexer.NextToken() == MySqlToken.KwDistinct) { tempGroupDistinct = true; lexer.NextToken(); } else { tempGroupDistinct = false; } tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Min(tempExpr, tempGroupDistinct).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Sum: { if (lexer.NextToken() == MySqlToken.KwDistinct) { tempGroupDistinct = true; lexer.NextToken(); } else { tempGroupDistinct = false; } tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Sum(tempExpr, tempGroupDistinct).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Count: { if (lexer.NextToken() == MySqlToken.KwDistinct) { lexer.NextToken(); tempExprList = ExpressionList(new List<IExpression>()); return new Count(tempExprList).SetCacheEvalRst(cacheEvalRst); } tempExpr = Expression(); Match(MySqlToken.PuncRightParen); return new Count(tempExpr).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.GroupConcat: { if (lexer.NextToken() == MySqlToken.KwDistinct) { lexer.NextToken(); tempGroupDistinct = true; } else { tempGroupDistinct = false; } for (tempExprList = new List<IExpression>();;) { tempExpr = Expression(); tempExprList.Add(tempExpr); if (lexer.Token() == MySqlToken.PuncComma) { lexer.NextToken(); } else { break; } } var isDesc = false; IList<IExpression> appendedColumnNames = null; tempExpr = null; // order by tempStr = null; switch (lexer.Token()) { case MySqlToken.KwOrder: { // literalChars lexer.NextToken(); Match(MySqlToken.KwBy); tempExpr = Expression(); if (lexer.Token() == MySqlToken.KwAsc) { lexer.NextToken(); } else { if (lexer.Token() == MySqlToken.KwDesc) { isDesc = true; lexer.NextToken(); } } for (appendedColumnNames = new List<IExpression>() ; lexer.Token() == MySqlToken.PuncComma;) { lexer.NextToken(); appendedColumnNames.Add(Expression()); } if (lexer.Token() != MySqlToken.KwSeparator) { break; } goto case MySqlToken.KwSeparator; } case MySqlToken.KwSeparator: { lexer.NextToken(); tempSb = new StringBuilder(); lexer.AppendStringContent(tempSb); tempStr = LiteralString.GetUnescapedString(tempSb.ToString()); Match(MySqlToken.LiteralChars); break; } } Match(MySqlToken.PuncRightParen); return new GroupConcat(tempGroupDistinct, tempExprList, tempExpr, isDesc, appendedColumnNames, tempStr).SetCacheEvalRst(cacheEvalRst); } case FunctionParsingStrategy.Char: { lexer.NextToken(); return FunctionChar(); } case FunctionParsingStrategy.Convert: { lexer.NextToken(); return FunctionConvert(); } case FunctionParsingStrategy.Extract: { lexer.NextToken(); return Extract(); } case FunctionParsingStrategy.Timestampdiff: { lexer.NextToken(); return Timestampdiff(); } case FunctionParsingStrategy.Timestampadd: { lexer.NextToken(); return Timestampadd(); } case FunctionParsingStrategy.Ordinary: { return OrdinaryFunction(consumed, consumedUp); } case FunctionParsingStrategy.Default: { return new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); } default: { throw Err("unexpected function parsing strategy for id of " + consumed); } } //goto default; } default: { return new Identifier(null, consumed, consumedUp).SetCacheEvalRst(cacheEvalRst); } } }