Пример #1
0
        private static bool ReadSub1Number(LexemCollection collection, out int i1)
        {
            i1 = 0;
            var lex = collection.GetNext();

            if (lex != null && lex.IsSkobraOpen())
            {
                collection.GotoNextMust();
                lex = collection.GotoNextMust();
                if (lex.LexemType == LexType.Number)
                {
                    i1 = int.Parse(lex.LexemText);
                }
                else if (lex.LexemType == LexType.Command)
                {
                    if (lex.LexemText.ToLower() == "max")
                    {
                        i1 = 0;
                    }
                }
                else
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                lex = collection.GotoNextMust();
                if (lex == null || !lex.IsSkobraClose())
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                return(true);
            }
            return(false);
        }
Пример #2
0
 public static string ReadAlias(LexemCollection collection)
 {
     if (collection.CurrentLexem() == null)
     {
         throw new Exception("Alias not found");
     }
     string[] strs = null;
     if (collection.CurrentLexem().LexemType == LexType.Command)
     {
         var r = collection.CurrentLexem().LexemText;
         strs = ParserUtils.ParseStringQuote(r);
     }
     else
     if (collection.CurrentLexem().LexemType == LexType.Text)
     {
         strs = ParserUtils.ParseStringQuote(collection.CurrentLexem().LexemText);
     }
     if (strs != null)
     {
         if (strs.Length > 1)
         {
             collection.Error("Composite alias", collection.CurrentLexem());
         }
         return(strs[0]);
     }
     collection.Error("Alias not found", collection.CurrentLexem());
     return(null);
 }
Пример #3
0
        public static FieldExpr ReadColumn(LexemCollection collection)
        {
            if (collection.CurrentLexem() == null)
            {
                throw new Exception("Alias not found");
            }
            if (collection.CurrentLexem().LexemType == LexType.Command)
            {
                var       r  = collection.CurrentLexem().LexemText;
                FieldExpr fc = new FieldExpr();
                fc.FieldName = collection.CurrentLexem().LexemText;
                return(fc);
            }
            if (collection.CurrentLexem().LexemType == LexType.Text)
            {
                var strs = ParserUtils.ParseStringQuote(collection.CurrentLexem().LexemText);
                if (strs.Length != 1)
                {
                    collection.Error("Composite column name", collection.CurrentLexem());
                }
                FieldExpr fc = new FieldExpr();
                fc.FieldName = strs[0];

                return(fc);
            }
            collection.Error("Column not found", collection.CurrentLexem());
            return(null);
        }
Пример #4
0
        public static Expression ParseCollection(LexemCollection collection)
        {
            ExpressionParser p = new ExpressionParser(collection);

            p.Parse();
            return(p.Single());
        }
Пример #5
0
 public void Parse(LexemCollection collection)
 {
     while (true)
     {
         var idx = collection.IndexLexem;
         ExpressionParser tonode = new ExpressionParser(collection);
         tonode.Parse();
         if (tonode.Results.Count != 1)
         {
             collection.Error("не верное число параметров", collection.Get(idx));
         }
         ColumnClause r = new ColumnClause();
         r.ColumnExpression = tonode.Single();
         Columns.Add(r);
         var lex = collection.CurrentLexem();
         if (lex == null)
         {
             return;
         }
         if (lex.LexemText.ToLower() == "as")
         {
             collection.GotoNext();
             if (lex == null)
             {
                 return;
             }
             r.Alias = CommonParserFunc.ReadAlias(collection);
             lex     = collection.GotoNext();
         }
         else
         if (nextStrings.Contains(lex.LexemText.ToLower()))
         {
             return;
         }
         else
         {
             if (lex.LexemType == LexType.Command || lex.LexemType == LexType.Text)
             {
                 r.Alias = CommonParserFunc.ReadAlias(collection);
                 lex     = collection.GotoNext();
             }
         }
         if (lex == null)
         {
             return;
         }
         if (nextStrings.Contains(lex.LexemText.ToLower()))
         {
             return;
         }
         if (lex.LexemType == LexType.Zpt)
         {
             collection.GotoNext();
             continue;
         }
         return;
     }
 }
Пример #6
0
 public void Parse(LexemCollection collection, bool isOrderBy)
 {
     while (true)
     {
         var idx = collection.IndexLexem;
         ExpressionParser tonode = new ExpressionParser(collection);
         tonode.Parse();
         if (tonode.Results.Count != 1)
         {
             collection.Error("не верное число параметров", collection.Get(idx));
         }
         GroupByClause r = null;
         if (isOrderBy)
         {
             r = new OrderByClause();
         }
         else
         {
             r = new GroupByClause();
         }
         r.Expression = tonode.Single();
         Columns.Add(r);
         var lex = collection.CurrentLexem();
         if (lex == null)
         {
             return;
         }
         if (isOrderBy)
         {
             if (lex.LexemText.ToLower() == "desc")
             {
                 ((OrderByClause)r).Sort = SortType.DESC;
                 lex = collection.GotoNext();
             }
             else if (lex.LexemText.ToLower() == "asc")
             {
                 ((OrderByClause)r).Sort = SortType.ASC;
                 lex = collection.GotoNext();
             }
         }
         if (lex == null)
         {
             return;
         }
         if (lex.LexemType == LexType.Zpt)
         {
             collection.GotoNext();
             continue;
         }
         return;
     }
 }
Пример #7
0
 public static string[] ReadTableName(LexemCollection collection)
 {
     if (collection.CurrentLexem() == null)
     {
         throw new Exception("Alias not found");
     }
     if (collection.CurrentLexem().LexemType == LexType.Command)
     {
         var r = collection.CurrentLexem().LexemText;
         return(ParserUtils.ParseStringQuote(r));
     }
     if (collection.CurrentLexem().LexemType == LexType.Text)
     {
         var strs = ParserUtils.ParseStringQuote(collection.CurrentLexem().LexemText);
         return(strs);
     }
     collection.Error("Alias not found", collection.CurrentLexem());
     return(null);
 }
Пример #8
0
        private static bool ReadSub2Number(LexemCollection collection, out int i1, out int i2)
        {
            i1 = 0;
            i2 = 0;
            var lex = collection.GetNext();

            if (lex != null && lex.IsSkobraOpen())
            {
                collection.GotoNextMust();
                lex = collection.GotoNextMust();
                if (lex.LexemType == LexType.Number)
                {
                    i1 = int.Parse(lex.LexemText);
                }
                else
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                lex = collection.GotoNextMust();
                if (lex == null)
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                if (lex.LexemType == LexType.Zpt)
                {
                    lex = collection.GotoNextMust();
                    if (lex.LexemType != LexType.Number)
                    {
                        collection.ErrorUnexpected(collection.CurrentOrLast());
                    }
                    i2  = int.Parse(lex.LexemText);
                    lex = collection.GotoNextMust();
                }
                if (lex == null || !lex.IsSkobraClose())
                {
                    collection.ErrorUnexpected(collection.CurrentOrLast());
                }
                return(true);
            }
            return(false);
        }
Пример #9
0
        /// <summary>
        /// Проверяет наличие фразы из команд. Если есть первое слово, то должны быть и остальные слова иначе ошибка.
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="phrase">Фраза разделённая пробелами</param>
        /// <param name="shift">True - в случае нахождения фразы позиция в collection передвигается на последнее слово фразы. False - не сдвигать</param>
        /// <returns></returns>
        public static bool ParseCommandPhrase(LexemCollection collection, string phrase, bool shift = true, bool exceptOnNotFull = true)
        {
            var lex = collection.CurrentLexem();

            if (lex == null)
            {
                return(false);
            }
            string[] str = phrase.Split(' ').Select(a => a.Trim().ToLower()).Where(a => a != "").ToArray();
            if (str.Length == 0)
            {
                return(false);
            }
            if (lex.LexemType == LexType.Command && lex.LexemText.ToLower() == str[0])
            {
                var idx = collection.IndexLexem;
                for (int i = 0; i < str.Length; i++)
                {
                    if (lex == null || lex.LexemType != LexType.Command || lex.LexemText.ToLower() != str[i])
                    {
                        if (exceptOnNotFull)
                        {
                            collection.Error("Waiting phrase " + phrase, collection.GetPrev());
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    idx++;
                    lex = collection.Get(idx);
                }
                if (shift)
                {
                    collection.IndexLexem = idx - 1;
                }
                return(true);
            }
            return(false);
        }
Пример #10
0
        public void Parse(LexemCollection collection)
        {
            int num = 0;

            while (true)
            {
                var lex = collection.CurrentLexem();
                if (lex == null)
                {
                    return;
                }
                var st = Read_table_reference(collection, num == 0);
                num++;
                Tables.Add(st);
                lex = collection.CurrentLexem();
                if (lex == null)
                {
                    return;
                }
                if (lex.LexemType == LexType.Zpt)
                {
                    lex = collection.GotoNext();
                    if (lex == null)
                    {
                        collection.Error("Error in table clause", collection.GetPrev());
                    }
                    continue;
                }
                if (nextStrings.Contains(lex.LexemText.ToLower()))
                {
                    return;
                }
                if (joinStrings.Contains(lex.LexemText.ToLower()))
                {
                    continue;
                }
                return;
                //collection.Error("Error parsing", lex);
            }
        }
Пример #11
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);
 }
Пример #12
0
 public ExpressionParser(LexemCollection collection) : base(collection)
 {
 }
Пример #13
0
 public CustomParser(LexemCollection collection)
 {
     Collection = collection;
 }
Пример #14
0
        private TableClause Read_table_reference(LexemCollection collection, bool isFirst)
        {
            var lex = collection.CurrentLexem();

            if (lex == null)
            {
                return(null);
            }
            //+left join
            //+left outer join
            //+inner join
            //+cross join
            //+join
            //+right join
            //+right outer join
            // full join
            JoinType jt = JoinType.Cross;

            if (!isFirst)
            {
                string s1 = collection.CurrentLexem().LexemText.ToLower();
                string s2 = null;
                string s3 = null;
                if (joinStrings.Contains(s1))
                {
                    lex = collection.GotoNext();
                    if (lex != null && joinStrings.Contains(lex.LexemText.ToLower()))
                    {
                        s2  = lex.LexemText.ToLower();
                        lex = collection.GotoNext();
                        if (lex != null && joinStrings.Contains(lex.LexemText.ToLower()))
                        {
                            s3  = lex.LexemText.ToLower();
                            lex = collection.GotoNext();
                        }
                    }
                }

                if (!joinStrings.Contains(s1))// случай ","
                {
                    jt = JoinType.Cross;
                }
                else
                if ((s3 == null && s2 == null && s1 == "join") ||
                    (s3 == null && s1 == "cross" && s2 == "join"))
                {
                    jt = JoinType.Cross;
                }
                else if ((s3 == null && s1 == "left" && s2 == "join") ||
                         (s1 == "left" && s2 == "outer" && s3 == "join"))
                {
                    jt = JoinType.Left;
                }
                else if ((s3 == null && s1 == "right" && s2 == "join") ||
                         (s1 == "right" && s2 == "outer" && s3 == "join"))
                {
                    jt = JoinType.Left;
                }
                else if (s3 == null && s1 == "inner" && s2 == "join")
                {
                    jt = JoinType.Inner;
                }
                else if (s3 == null && s1 == "full" && s2 == "join")
                {
                    jt = JoinType.Full;
                }
                else
                {
                    collection.Error("Unknow JOIN clause", collection.CurrentLexem());
                }
            }
            TableClause st = null;

            if (lex == null)
            {
                collection.Error("Error in table clause", collection.GetPrev());
            }
            if (!lex.IsSkobraOpen())
            {
                string[] tableName = CommonParserFunc.ReadTableName(collection);
                var      v         = collection.TableGetter.GetTableByName(tableName, collection.TableGetterUseCache);
                st  = TableClause.CreateByTable(tableName, v);
                lex = collection.GotoNext();
            }
            else
            {
                lex = collection.GotoNext();
                if (lex == null)
                {
                    collection.Error("Expression is not found", collection.GetLast());
                }
                //подзапрос
                var idx = collection.IndexLexem;
                ExpressionParser tonode = new ExpressionParser(collection);
                tonode.Parse();
                if (tonode.Results.Count != 1)
                {
                    collection.Error("не верное число параметров", collection.Get(idx));
                }
                lex = collection.CurrentLexem();
                if (lex == null || !lex.IsSkobraClose())
                {
                    collection.Error("Expression is not closed", collection.CurrentLexem());
                }
                lex = collection.GotoNext();

                //ITableDesc subselect = CommonUtils.FindParentSelect(tonode.Single()); Это штука работает не правильно
                ITableDesc subselect = (ITableDesc)tonode.Single();
                if (subselect == null)
                {
                    collection.Error("Subselect not found", collection.Get(idx));
                }
                st = TableClause.CreateBySelect(subselect);
            }
            st.Join = jt;
            if (lex == null)
            {
                return(st);
            }
            if (lex.LexemText.ToLower() == "as")
            {
                collection.GotoNext();
                if (lex == null)
                {
                    collection.Error("Alias not found", collection.GetPrev());
                }
                st.Alias = CommonParserFunc.ReadAlias(collection);
                if (st.Alias == null)
                {
                    collection.Error("Alias not found", collection.GetPrev());
                }
                lex = collection.GotoNext();
            }
            else
            {
                if (lex.LexemType == LexType.Text)
                {
                    st.Alias = CommonParserFunc.ReadAlias(collection);
                    if (st.Alias == null)
                    {
                        collection.Error("Alias not found", collection.GetPrev());
                    }
                    lex = collection.GotoNext();
                }
                else
                if (lex.LexemType == LexType.Command &&
                    !nextStrings.Contains(lex.LexemText.ToLower()) &&
                    !joinStrings.Contains(lex.LexemText.ToLower()) &&
                    lex.LexemText.ToLower() != "on")
                {
                    st.Alias = CommonParserFunc.ReadAlias(collection);
                    if (st.Alias == null)
                    {
                        collection.Error("Alias not found", collection.GetPrev());
                    }
                    lex = collection.GotoNext();
                }
            }
            lex = collection.CurrentLexem();
            if (lex == null)
            {
                return(st);
            }
            if (lex.LexemType == LexType.Command && lex.LexemText.ToLower() == "on")
            {
                lex = collection.GotoNext();
                var idx = collection.IndexLexem;
                ExpressionParser tonode = new ExpressionParser(collection);
                tonode.Parse();
                if (tonode.Results.Count != 1)
                {
                    collection.Error("не верное число параметров", collection.Get(idx));
                }
                st.OnExpression = tonode.Single();
            }
            return(st);
        }
Пример #15
0
        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);
        }
Пример #16
0
 public FuncArgsParser(LexemCollection collection)
     : base(collection)
 {
 }
Пример #17
0
 public SelectParser(LexemCollection collection)
     : base(collection)
 {
 }