Exemple #1
0
 /// <summary>
 /// Читаем название колонки в текущей лексеме. Может быть name, "name", [name]
 /// </summary>
 /// <param name="collection"></param>
 /// <returns></returns>
 public static string ReadColumnNameOnly(LexemCollection collection)
 {
     if (collection.CurrentLexem() == null)
     {
         collection.Error("Alias not found", collection.CurrentOrLast());
     }
     if (collection.CurrentLexem().LexemType == LexType.Command)
     {
         var r = collection.CurrentLexem().LexemText;
         return(r);
     }
     if (collection.CurrentLexem().LexemType == LexType.Text)
     {
         var strs = ParserUtils.ParseStringQuote(collection.CurrentLexem().LexemText);
         if (strs.Length != 1)
         {
             collection.Error("Composite column name", collection.CurrentLexem());
         }
         return(strs[0]);
     }
     collection.Error("Column not found", collection.CurrentLexem());
     return(null);
 }
        public override void ParseInside(ExpressionParser parser)
        {
            var collection = parser.Collection;
            var lex        = collection.CurrentLexem();

            if (lex.LexemText.ToLower() != "insert")
            {
                throw new Exception("Not INSERT statment");
            }
            lex = collection.GotoNextMust();
            if (lex.LexemText.ToLower() != "into")
            {
                throw new Exception("INTO keyword is not found");
            }
            lex = collection.GotoNextMust();
            string[] tablename = CommonParserFunc.ReadTableName(collection);
            TableClause = TableClause.CreateByTable(tablename, collection.TableGetter.GetTableByName(tablename, collection.TableGetterUseCache));
            lex         = collection.GotoNextMust();
            if (lex.IsSkobraOpen())
            {
                while (true)
                {
                    lex = collection.GotoNextMust(); //пропускаем SET или ','
                    //lex = collection.CurrentLexem();

                    var col = CommonParserFunc.ReadColumn(collection);
                    ColumnOfValues.Add(col);
                    lex = collection.GotoNextMust();
                    if (lex == null)
                    {
                        break;
                    }
                    if (lex.LexemType == LexType.Zpt)
                    {
                        continue;
                    }
                    if (lex.IsSkobraClose())
                    {
                        break;
                    }
                    collection.Error("Unknow lexem", collection.CurrentLexem());
                }
                //пропускаем ')'
                lex = collection.GotoNextMust();
            }
            else
            {
                if (lex.LexemType == LexType.Command && lex.LexemText.ToLower() == "default")
                {
                    lex = collection.GotoNextMust();
                    if (lex.LexemType == LexType.Command && lex.LexemText.ToLower() == "values")
                    {
                        DefaultValues = true;
                        return;
                    }
                    else
                    {
                        collection.Error("Expected keyword VALUES", lex);
                    }
                }
            }

            if (lex == null)
            {
                return;
            }
            if (lex.LexemText.ToLower() == "values")
            {
                lex = collection.GotoNextMust();
                if (!lex.IsSkobraOpen())
                {
                    collection.Error("'(' not found", lex);
                }
                while (true)
                {
                    SubExpression sub = new SubExpression();
                    sub.MultiValues = true;
                    while (true)
                    {
                        lex = collection.GotoNextMust(); //пропускаем SET или ','
                        //lex = collection.CurrentLexem();

                        ExpressionParser e = new ExpressionParser(collection);
                        e.Parse();
                        sub.AddChild(e.Single());
                        lex = collection.CurrentLexem();
                        if (lex == null)
                        {
                            break;
                        }
                        if (lex.LexemType == LexType.Zpt)
                        {
                            continue;
                        }
                        if (lex.IsSkobraClose())
                        {
                            break;
                        }
                        collection.Error("Unknow lexem", collection.CurrentLexem());
                    }
                    Values.Add(sub);
                    lex = collection.GotoNext();
                    if (lex != null && lex.LexemType == LexType.Zpt)
                    {
                        lex = collection.GotoNextMust();
                        if (!lex.IsSkobraOpen())
                        {
                            collection.ErrorWaitKeyWord("(", lex);
                        }
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            if (lex.LexemText.ToLower() == "select" || lex.IsSkobraOpen())
            {
                ExpressionParser e = new ExpressionParser(collection);
                e.Parse();
                var expr = e.Single();
                var sel  = ParserUtils.FindSelect(expr);
                if (sel == null)
                {
                    throw new Exception("Values in INSERT not found");
                }
                Select = sel;
            }
            ParseReturining(parser);
        }
        public Expression GetNode(ExpressionParser parser)
        {
            var        collection = parser.Collection;
            Lexem      lex        = parser.Collection.CurrentLexem();
            bool       uniar      = parser.waitValue;
            Expression res        = null;

            if (lex.LexemType == LexType.Arfimetic)
            {
                switch (lex.LexemText)
                {
                case "+":
                    if (uniar)
                    {
                        res = new UniarPlus_BoolExpr();
                    }
                    else
                    {
                        res = new Plus_Arifmetic();
                    }
                    break;

                case "-":
                    if (uniar)
                    {
                        res = new UniarMinus_BoolExpr();
                    }
                    else
                    {
                        res = new Minus_Arifmetic();
                    }
                    break;

                case "*":
                    if (uniar)
                    {
                        res = new AllColumnExpr();
                    }
                    else
                    {
                        res = new Multi_Arifmetic();
                    }
                    break;

                case "/":
                    res = new Div_Arifmetic();
                    break;

                case "<":
                    res = new Less_CompExpr();
                    break;

                case "<=":
                    res = new LessOrEqual_CompExpr();
                    break;

                case ">=":
                    res = new GreatOrEqual_CompExpr();
                    break;

                case ">":
                    res = new Great_CompExpr();
                    break;

                case "=":
                    res = new Equal_CompExpr();
                    break;

                case "<>":
                case "!=":
                    res = new NotEqual_CompExpr();
                    break;
                }
            }
            if (lex.LexemType == LexType.Number)
            {
                res = new ConstExpr();
                if (lex.LexemText.Contains('.'))
                {
                    (res as ConstExpr).Init(lex.LexemText.ParseDouble(), SimpleTypes.Float);
                }
                else
                {
                    (res as ConstExpr).Init(long.Parse(lex.LexemText), SimpleTypes.Integer);
                }
            }
            if (lex.LexemType == LexType.Text)
            {
                if (lex.LexemText.StartsWith("'"))
                {
                    res = new ConstExpr();
                    (res as ConstExpr).Init(ParserUtils.StandartDecodeEscape(lex.LexemText), SimpleTypes.String);
                }
            }
            if (lex.LexemType == LexType.Command)
            {
                switch (lex.LexemText.ToLower())
                {
                case "not":
                    res = new Not_BoolExpr();
                    break;

                case "and":
                    res = new And_BoolExpr();
                    break;

                case "or":
                    res = new Or_BoolExpr();
                    break;

                case "true":
                    res = new ConstExpr();
                    (res as ConstExpr).Init(true, SimpleTypes.Boolean);
                    break;

                case "false":
                    res = new ConstExpr();
                    (res as ConstExpr).Init(false, SimpleTypes.Boolean);
                    break;

                case "date":
                    if (collection.GetNext() != null)
                    {
                        var c = collection.GetNext();
                        if (c.LexemType == LexType.Text && c.LexemText.StartsWith("'"))
                        {
                            res = new ConstExpr();
                            string s  = ParserUtils.StandartDecodeEscape(c.LexemText);
                            var    dt = CommonUtils.ParseDateTime(s);
                            if (dt != null)
                            {
                                collection.GotoNext();
                                ((ConstExpr)res).Init(dt.Value, SimpleTypes.Date);
                            }
                            else
                            {
                                collection.Error("Can not parse date lexem", lex);
                            }
                        }
                    }
                    break;

                case "datetime":
                case "timestamp":
                    if (collection.GetNext() != null)
                    {
                        var c = collection.GetNext();
                        if (c.LexemType == LexType.Text && c.LexemText.StartsWith("'"))
                        {
                            res = new ConstExpr();
                            string s  = ParserUtils.StandartDecodeEscape(c.LexemText);
                            var    dt = CommonUtils.ParseDateTime(s);
                            if (dt != null)
                            {
                                collection.GotoNext();
                                ((ConstExpr)res).Init(dt.Value, SimpleTypes.DateTime);
                            }
                            else
                            {
                                collection.Error("Can not parse datetime lexem", lex);
                            }
                        }
                    }
                    break;

                case "time":
                    if (collection.GetNext() != null)
                    {
                        var c = collection.GetNext();
                        if (c.LexemType == LexType.Text && c.LexemText.StartsWith("'"))
                        {
                            res = new ConstExpr();
                            string   s = ParserUtils.StandartDecodeEscape(c.LexemText);
                            DateTime dt;
                            var      r = CommonUtils.ParseDateTime(s, out dt);
                            if (r == ParserDateTimeStatus.Time)
                            {
                                collection.GotoNext();
                                ((ConstExpr)res).Init(dt.TimeOfDay, SimpleTypes.Time);
                            }
                            else
                            {
                                collection.Error("Can not parse time lexem", lex);
                            }
                        }
                    }
                    break;
                }
            }
            return(res);
        }
Exemple #4
0
        public Expression GetNode(ExpressionParser parser)
        {
            Lexem      lex   = parser.Collection.CurrentLexem();
            Expression ex    = null;
            bool       uniar = parser.waitValue;

            if (lex.LexemType == LexType.Arfimetic)
            {
                switch (lex.LexemText)
                {
                case "+":
                    if (uniar)
                    {
                        ex = new UniarPlus_BoolExpr();
                    }
                    else
                    {
                        ex = new Plus_Arifmetic();
                    }
                    break;

                case "-":
                    if (uniar)
                    {
                        ex = new UniarMinus_BoolExpr();
                    }
                    else
                    {
                        ex = new Minus_Arifmetic();
                    }
                    break;

                case "*":
                    if (uniar)
                    {
                        ex = new AllColumnExpr();
                    }
                    else
                    {
                        ex = new Multi_Arifmetic();
                    }
                    break;

                case "/":
                    ex = new Div_Arifmetic();
                    break;

                case "<":
                    ex = new Less_CompExpr();
                    break;

                case "<=":
                    ex = new LessOrEqual_CompExpr();
                    break;

                case ">=":
                    ex = new GreatOrEqual_CompExpr();
                    break;

                case ">":
                    ex = new Great_CompExpr();
                    break;

                case "=":
                    ex = new Equal_CompExpr();
                    break;

                case "<>":
                case "!=":
                    ex = new NotEqual_CompExpr();
                    break;
                }
            }
            if (lex.LexemType == LexType.Number)
            {
                ex = new ConstExpr();
                if (lex.LexemText.Contains('.'))
                {
                    (ex as ConstExpr).Init(lex.LexemText.ParseDouble(), SimpleTypes.Float);
                }
                else
                {
                    (ex as ConstExpr).Init(long.Parse(lex.LexemText), SimpleTypes.Integer);
                }
            }
            if (lex.LexemType == LexType.Text)
            {
                if (lex.LexemText.StartsWith("'"))
                {
                    ex = new ConstExpr();
                    (ex as ConstExpr).Init(ParserUtils.StandartDecodeEscape(lex.LexemText), SimpleTypes.String);
                }
            }
            Lexem n1;

            if (lex.LexemType == LexType.Command)
            {
                switch (lex.LexemText.ToLower())
                {
                case "not":
                    n1 = parser.Collection.GetNext();
                    if (n1 != null && n1.LexemType == LexType.Command && n1.LexemText.ToLower() == "in")
                    {
                        ex = new NotInExpr();
                        parser.Collection.GotoNext();
                        break;
                    }
                    ex = new Not_BoolExpr();
                    break;

                case "case":
                    ex = new CaseExpr();
                    break;

                case "contains":
                    ex = new Contains();
                    break;

                case "containsic":     //ic = ignore case
                case "containscase":
                    ex = new ContainsIgnoreCase();
                    break;

                case "startwith":
                case "startswith":
                    ex = new StartsWith();
                    break;

                case "endwith":
                case "endswith":
                    ex = new EndsWith();
                    break;
                }
                if (parser.Collection.GetNext() != null && parser.Collection.GetNext().IsSkobraOpen())
                {
                    switch (lex.LexemText.ToLower())
                    {
                    case "cast":
                        ex = new Cast();
                        break;

                    case "in":
                        ex = new InExpr();
                        break;

                    case "abs":
                        ex = new Abs();
                        break;

                    case "substring":
                        ex = new SubString();
                        break;

                    case "position":
                        ex = new Position();
                        break;

                    case "ltrim":
                        ex = new LTrim();
                        break;

                    case "rtrim":
                        ex = new RTrim();
                        break;

                    case "trim":
                        ex = new Trim();
                        break;

                    case "length":
                        ex = new Length();
                        break;

                    case "upper":
                        ex = new Upper_operation();
                        break;

                    case "lower":
                        ex = new Lower_operation();
                        break;

                    case "left":
                        ex = new Left();
                        break;

                    case "right":
                        ex = new Right();
                        break;

                    case "replace":
                        ex = new Replace();
                        break;

                    case "now":
                        ex = new Now();
                        break;

                    case "tostr":
                        ex = new ToString();
                        break;

                    case "strtotime":
                        ex = new StrToTime();
                        break;

                    case "strtodatetime":
                        ex = new StrToDateTime();
                        break;

                    case "addseconds":
                        ex = new AddSeconds();
                        break;

                    case "addminutes":
                        ex = new AddMinutes();
                        break;

                    case "addhours":
                        ex = new AddHours();
                        break;

                    case "adddays":
                        ex = new AddDays();
                        break;

                    case "day":
                        ex = new Day();
                        break;

                    case "month":
                        ex = new Month();
                        break;

                    case "year":
                        ex = new Year();
                        break;

                    case "round":
                        ex = new ParserCore.Expr.Extend.Math.Round();
                        break;

                    case "ceiling":
                        ex = new ParserCore.Expr.Extend.Math.Ceiling();
                        break;

                    case "floor":
                        ex = new ParserCore.Expr.Extend.Math.Floor();
                        break;

                    case "pi":
                        ex = new ParserCore.Expr.Extend.Math.Pi();
                        break;

                    case "tan":
                        ex = new ParserCore.Expr.Extend.Math.Tan();
                        break;

                    case "log":
                        ex = new ParserCore.Expr.Extend.Math.Log();
                        break;
                    }
                }
            }
            return(ex);
        }
        public Expression GetNode(ExpressionParser parser)
        {
            Lexem      lex = parser.Collection.CurrentLexem();
            Expression res = null;

            if (lex.LexemType == LexType.Command)
            {
                string lowerLexem = lex.LexemText.ToLower();
                if (ParserUtils.ParseCommandPhrase(parser.Collection, "create view", false, false))
                {
                    res = new CreateView();
                }
                if (ParserUtils.ParseCommandPhrase(parser.Collection, "create table", false, false))
                {
                    res = new CreateTable();
                }
                if (res == null && ParserUtils.ParseCommandPhrase(parser.Collection, "alter table", false, false))
                {
                    res = new AlterTable();
                }
                if (res == null && ParserUtils.ParseCommandPhrase(parser.Collection, "drop table", false, false))
                {
                    res = new DropTable();
                }
                if (res == null && ParserUtils.ParseCommandPhrase(parser.Collection, "drop index", false, false))
                {
                    res = new DropIndex();
                }
                if (res == null && (ParserUtils.ParseCommandPhrase(parser.Collection, "create unique index", false, false) ||
                                    ParserUtils.ParseCommandPhrase(parser.Collection, "create index", false, false)))
                {
                    res = new CreateIndex();
                }
                if (res == null)
                {
                    if (parser.Collection.GetNext() != null && parser.Collection.GetNext().IsSkobraOpen())
                    {
                        switch (lowerLexem)
                        {
                        case "count":
                            res = new CountExpr();
                            break;

                        case "sum":
                            res = new SumExpr();
                            break;

                        case "min":
                            res = new MinExpr();
                            break;

                        case "max":
                            res = new MaxExpr();
                            break;

                        case "avg":
                            res = new AvgExpr();
                            break;

                        case "lastinsertrowid":
                            res = new LastInsertRowidExpr();
                            break;

                        case "exists":
                            res = new ExistsExpr();
                            break;

                        case "any":
                            res = new AnyExpr();
                            break;
                        }
                    }

                    switch (lowerLexem)
                    {
                    case "between":    //не функция
                        res = new Between();
                        break;

                    case "select":
                        res = new SelectExpresion();
                        break;

                    case "update":
                        res = new UpdateStatement();
                        break;

                    case "insert":
                        res = new InsertStatement();
                        break;

                    case "delete":
                        res = new DeleteStatement();
                        break;
                    }
                }
            }
            if (res != null)
            {
                return(res);
            }
            return(res);
        }
 public override string ToStr()
 {
     string s = ColumnExpression.ToStr();
     if (!string.IsNullOrEmpty(Alias)) s = s + " AS " + ParserUtils.ConstToStrEscape(Alias);
     return s;
 }
        public static ExactType?Parse(LexemCollection collection)
        {
            ExactType res;
            var       lex = collection.CurrentLexem();

            if (lex.LexemType != LexType.Command)
            {
                collection.Error("Unknow data type", collection.CurrentLexem());
            }
            string       s      = lex.LexemText.ToLower();
            DbColumnType tp     = DbColumnType.Unknow;
            int          param1 = 0;
            int          param2 = 0;

            switch (s)
            {
            case "datetime":
                tp = DbColumnType.DateTime;
                ReadSub1Number(collection, out param1);    //ignore
                break;

            case "timestamp":
                tp = DbColumnType.DateTime;
                if (ParserUtils.ParseCommandPhrase(collection, "timestamp without time zone", true, false))
                {
                    tp = DbColumnType.DateTime;
                }
                if (ParserUtils.ParseCommandPhrase(collection, "timestamp with time zone", true, false))
                {
                    tp = DbColumnType.DateTimeWithTimeZone;
                }
                ReadSub1Number(collection, out param1);    //ignore
                break;

            case "date":
                tp = DbColumnType.Date;
                ReadSub1Number(collection, out param1);    //ignore
                break;

            case "time":
                tp = DbColumnType.Time;
                if (ParserUtils.ParseCommandPhrase(collection, "time without time zone", true, false))
                {
                    tp = DbColumnType.Time;
                }
                if (ParserUtils.ParseCommandPhrase(collection, "time with time zone", true, false))
                {
                    tp = DbColumnType.TimeWithTimeZome;
                }
                ReadSub1Number(collection, out param1);    //ignore
                break;

            case "int8":
            case "byte":
            case "tinyint":
                tp = DbColumnType.Byte;
                break;

            case "int16":
            case "smallint":
                tp = DbColumnType.SmallInt;
                break;

            case "int32":
            case "integer":
            case "int":
                tp = DbColumnType.Integer;
                break;

            case "float":
            case "real":
                tp = DbColumnType.Real;
                ReadSub1Number(collection, out param1);    //ignore
                break;

            case "double":
                ParserUtils.ParseCommandPhrase(collection, "double precision");
                tp = DbColumnType.Double;
                break;

            case "bigint":
            case "int64":
                tp = DbColumnType.BigInt;
                break;

            case "decimal":
            case "numeric":
                tp = DbColumnType.Numeric;
                ReadSub2Number(collection, out param1, out param2);
                break;

            case "nvarchar":
            case "varchar":
                tp = DbColumnType.VarChar;
                if (ReadSub1Number(collection, out param1))
                {
                    if (param1 == 0)
                    {
                        tp = DbColumnType.Text;
                    }
                }
                break;

            case "nchar":
            case "char":
                tp = DbColumnType.VarChar;
                if (!ReadSub1Number(collection, out param1))
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                break;

            case "character":
                tp = DbColumnType.Char;
                if (ParserUtils.ParseCommandPhrase(collection, "character varying"))
                {
                    tp = DbColumnType.VarChar;
                }
                if (!ReadSub1Number(collection, out param1))
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                break;

            case "text":
                tp = DbColumnType.Text;
                break;

            case "blob":
                tp = DbColumnType.Blob;
                break;

            case "bit":
            case "bool":
            case "boolean":
                tp = DbColumnType.Boolean;
                break;

            case "geometry":
                tp = DbColumnType.Geometry;
                break;

            case "geography":
                tp = DbColumnType.Geography;
                break;

            default:
                return(null);
            }
            res = ExactType.Create(tp);
            if (tp == DbColumnType.Numeric)
            {
                res.Precision = param1;
                res.Scale     = param2;
            }
            if (tp == DbColumnType.Char || tp == DbColumnType.VarChar)
            {
                res.MaxTextLength = param1;
            }
            return(res);
        }