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); }
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); }
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; } }
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; } }
/// <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 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); }
/// <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); }
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); } }
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); }
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); }