/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { string s = Parser.NextToken().ToUpper(); if (s != "FROM") { return(false); } ScriptNode Source = Parser.ParseNoWhiteSpace(); ScriptNode Where = null; s = Parser.PeekNextToken().ToUpper(); if (s == "WHERE") { Parser.NextToken(); Where = Parser.ParseOrs(); } Result = new Delete(Source, Where, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { string s = Parser.NextToken().ToUpper(); if (s != "INDEX") { return(false); } ScriptNode Name = Parser.ParseNoWhiteSpace(); s = Parser.NextToken().ToUpper(); if (s != "ON") { return(false); } if (!SelectParser.TryParseSources(Parser, out SourceDefinition Source)) { return(false); } Result = new DropIndex(Name, Source, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { string s = Parser.NextToken().ToUpper(); if (s != "INDEX") { return(false); } ScriptNode Name = Parser.ParseNoWhiteSpace(); s = Parser.NextToken().ToUpper(); if (s != "ON") { return(false); } if (!SelectParser.TryParseSources(Parser, out SourceDefinition Source)) { return(false); } s = Parser.NextToken(); if (s != "(") { return(false); } this.ParseList(Parser, out ScriptNode[] Columns, out bool[] Ascending); if (Columns.Length == 0) { return(false); } if (Parser.NextToken() != ")") { return(false); } Result = new CreateIndex(Name, Source, Columns, Ascending, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { string s = Parser.NextToken().ToUpper(); switch (s) { case "INDEX": ScriptNode Name = Parser.ParseNoWhiteSpace(); s = Parser.NextToken().ToUpper(); if (s != "ON") { return(false); } if (!SelectParser.TryParseSources(Parser, out SourceDefinition Source)) { return(false); } Result = new DropIndex(Name, Source, Parser.Start, Parser.Length, Parser.Expression); return(true); case "TABLE": case "COLLECTION": if (!SelectParser.TryParseSources(Parser, out Source)) { return(false); } Result = new DropCollection(Source, Parser.Start, Parser.Length, Parser.Expression); return(true); default: return(false); } } catch (Exception) { return(false); } }
internal void ParseList(ScriptParser Parser, out ScriptNode[] Columns, out bool[] Ascending) { List <ScriptNode> ColumnList = new List <ScriptNode>(); List <bool> AscendingList = new List <bool>(); string s; do { ScriptNode Node = Parser.ParseIf(); switch (s = Parser.PeekNextToken().ToUpper()) { case "ASC": Parser.NextToken(); ColumnList.Add(Node); AscendingList.Add(true); s = Parser.PeekNextToken(); break; case "DESC": Parser.NextToken(); ColumnList.Add(Node); AscendingList.Add(false); s = Parser.PeekNextToken(); break; case ",": Parser.NextToken(); ColumnList.Add(Node); AscendingList.Add(true); break; default: ColumnList.Add(Node); AscendingList.Add(true); break; } }while (s == ","); Columns = ColumnList.ToArray(); Ascending = AscendingList.ToArray(); }
private static ScriptNode ParseJoinConditions(ScriptParser Parser) { if (Parser.PeekNextToken().ToUpper() != "ON") { return(null); } Parser.NextToken(); return(Parser.ParseOrs()); }
internal static bool TryParseSource(ScriptParser Parser, out SourceDefinition Source) { Parser.SkipWhiteSpace(); int Start = Parser.Position; ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; string s; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && IsAlias(s) && s != "INNER" && s != "OUTER" && s != "LEFT" && s != "RIGHT" && s != "FULL" && s != "JOIN" && s != "WHERE" && s != "GROUP" && s != "ORDER" && s != "OFFSET" && s != "ON" && s != "SET" && s != "SELECT" && s != "OBJECT" && s != "OBJECTS") { if (s == "AS") { Parser.NextToken(); } Name = Parser.ParseNoWhiteSpace(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } Source = new SourceReference(Node, Name, Start, Parser.Position - Start, Parser.Expression); return(true); }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { ScriptNode Source = Parser.ParseNoWhiteSpace(); string s = Parser.NextToken().ToUpper(); if (s != "SET") { return(false); } List <Assignment> SetOperations = new List <Assignment>(); ScriptNode Node = Parser.ParseList(); if (!(Node is ElementList List)) { List = new ElementList(new ScriptNode[] { Node }, Node.Start, Node.Length, Node.Expression); } foreach (ScriptNode Operation in List.Elements) { if (Operation is EqualTo EqualTo) { if (EqualTo.LeftOperand is VariableReference Ref) { SetOperations.Add(new Assignment(Ref.VariableName, EqualTo.RightOperand, EqualTo.Start, EqualTo.Length, EqualTo.Expression)); } else { return(false); } } else if (Operation is Assignment Assignment) { SetOperations.Add(Assignment); } else { return(false); } } ScriptNode Where = null; s = Parser.PeekNextToken().ToUpper(); if (s == "WHERE") { Parser.NextToken(); Where = Parser.ParseOrs(); } Result = new Update(Source, SetOperations.ToArray(), Where, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { string s = Parser.NextToken().ToUpper(); if (s != "INTO") { return(false); } if (!SelectParser.TryParseSources(Parser, out SourceDefinition Source)) { return(false); } switch (Parser.PeekNextToken().ToUpper()) { case "(": Parser.NextToken(); ScriptNode Node = Parser.ParseList(); if (!(Node is ElementList Columns)) { Columns = new ElementList(new ScriptNode[] { Node }, Node.Start, Node.Length, Node.Expression); } if (Parser.NextToken() != ")") { return(false); } if (Parser.NextToken().ToUpper() != "VALUES") { return(false); } if (Parser.NextToken() != "(") { return(false); } Node = Parser.ParseList(); if (!(Node is ElementList Values)) { Values = new ElementList(new ScriptNode[] { Node }, Node.Start, Node.Length, Node.Expression); } if (Values.Elements.Length != Columns.Elements.Length) { return(false); } if (Parser.NextToken() != ")") { return(false); } Result = new InsertValues(Source, Columns, Values, Parser.Start, Parser.Length, Parser.Expression); return(true); case "SELECT": Node = Parser.ParseStatement(); if (!(Node is Select Select)) { return(false); } Result = new InsertSelect(Source, Select, Parser.Start, Parser.Position, Parser.Expression); return(true); case "OBJECT": case "OBJECTS": Parser.NextToken(); Node = Parser.ParseList(); if (!(Node is ElementList Objects)) { Objects = new ElementList(new ScriptNode[] { Node }, Node.Start, Node.Length, Node.Expression); } Result = new InsertObjects(Source, Objects, Parser.Start, Parser.Length, Parser.Expression); return(true); default: return(false); } } catch (Exception) { return(false); } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { List <ScriptNode> Columns; List <ScriptNode> ColumnNames; ScriptNode Top = null; string s; bool Distinct = false; s = Parser.PeekNextToken().ToUpper(); if (string.IsNullOrEmpty(s)) { return(false); } while (s == "TOP" || s == "DISTINCT") { switch (s) { case "TOP": Parser.NextToken(); Top = Parser.ParseNoWhiteSpace(); break; case "DISTINCT": Parser.NextToken(); Distinct = true; break; } s = Parser.PeekNextToken(); if (string.IsNullOrEmpty(s)) { return(false); } } if (s == "*") { Parser.NextToken(); Columns = null; ColumnNames = null; } else { Columns = new List <ScriptNode>(); ColumnNames = new List <ScriptNode>(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && s != "," && s != "FROM") { if (s == "AS") { Parser.NextToken(); } Name = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } else if (Node is NamedMember NamedMember) { Name = new ConstantElement(new StringValue(NamedMember.Name), Node.Start, Node.Length, Node.Expression); } Columns.Add(Node); ColumnNames.Add(Name); if (s != ",") { break; } Parser.NextToken(); } } s = Parser.NextToken().ToUpper(); if (s != "FROM") { return(false); } if (!TryParseSources(Parser, out SourceDefinition Source)) { return(false); } ScriptNode Where = null; s = Parser.PeekNextToken().ToUpper(); if (s == "WHERE") { Parser.NextToken(); Where = Parser.ParseOrs(); s = Parser.PeekNextToken().ToUpper(); } List <ScriptNode> GroupBy = null; List <ScriptNode> GroupByNames = null; ScriptNode Having = null; if (s == "GROUP") { Parser.NextToken(); if (Parser.NextToken().ToUpper() != "BY") { return(false); } GroupBy = new List <ScriptNode>(); GroupByNames = new List <ScriptNode>(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && s != "," && s != "HAVING" && s != "ORDER" && s != "OFFSET") { if (s == "AS") { Parser.NextToken(); } Name = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } else if (Node is NamedMember NamedMember) { Name = new ConstantElement(new StringValue(NamedMember.Name), Node.Start, Node.Length, Node.Expression); } GroupBy.Add(Node); GroupByNames.Add(Name); if (s != ",") { break; } Parser.NextToken(); } if (s == "HAVING") { Parser.NextToken(); Having = Parser.ParseOrs(); s = Parser.PeekNextToken().ToUpper(); } } else if (!(Columns is null)) { bool ImplicitGrouping = false; foreach (ScriptNode Column in Columns) { if (this.ContainsVectorFunction(Column)) { ImplicitGrouping = true; break; } } if (ImplicitGrouping) { GroupBy = new List <ScriptNode>(); GroupByNames = new List <ScriptNode>(); } } List <KeyValuePair <ScriptNode, bool> > OrderBy = null; if (s == "ORDER") { Parser.NextToken(); if (Parser.NextToken().ToUpper() != "BY") { return(false); } OrderBy = new List <KeyValuePair <ScriptNode, bool> >(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (s == "ASC") { Parser.NextToken(); OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, true)); s = Parser.PeekNextToken().ToUpper(); } else if (s == "DESC") { Parser.NextToken(); OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, false)); s = Parser.PeekNextToken().ToUpper(); } else { OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, true)); } if (s != ",") { break; } Parser.NextToken(); } } ScriptNode Offset = null; if (s == "OFFSET") { Parser.NextToken(); Offset = Parser.ParseNoWhiteSpace(); } Result = new Select(Columns?.ToArray(), ColumnNames?.ToArray(), Source, Where, GroupBy?.ToArray(), GroupByNames?.ToArray(), Having, OrderBy?.ToArray(), Top, Offset, Distinct, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }
internal static bool TryParseSources(ScriptParser Parser, out SourceDefinition Source) { if (!TryParseSource(Parser, out Source)) { return(false); } while (true) { string s = Parser.PeekNextToken().ToUpper(); switch (s) { case ",": Parser.NextToken(); if (!TryParseSource(Parser, out SourceDefinition Source2)) { return(false); } Source = new CrossJoin(Source, Source2, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; case "INNER": case "JOIN": Parser.NextToken(); if (s == "INNER") { if (Parser.NextToken().ToUpper() != "JOIN") { return(false); } } if (!TryParseSource(Parser, out Source2)) { return(false); } ScriptNode Conditions = ParseJoinConditions(Parser); Source = new InnerJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; case "LEFT": Parser.NextToken(); switch (Parser.NextToken().ToUpper()) { case "JOIN": break; case "OUTER": if (Parser.NextToken().ToUpper() != "JOIN") { return(false); } break; default: return(false); } if (!TryParseSource(Parser, out Source2)) { return(false); } Conditions = ParseJoinConditions(Parser); Source = new LeftOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; case "RIGHT": Parser.NextToken(); switch (Parser.NextToken().ToUpper()) { case "JOIN": break; case "OUTER": if (Parser.NextToken().ToUpper() != "JOIN") { return(false); } break; default: return(false); } if (!TryParseSource(Parser, out Source2)) { return(false); } Conditions = ParseJoinConditions(Parser); Source = new RightOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; case "FULL": Parser.NextToken(); switch (Parser.NextToken().ToUpper()) { case "JOIN": break; case "OUTER": if (Parser.NextToken().ToUpper() != "JOIN") { return(false); } break; default: return(false); } if (!TryParseSource(Parser, out Source2)) { return(false); } Conditions = ParseJoinConditions(Parser); Source = new FullOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; case "OUTER": Parser.NextToken(); if (Parser.NextToken().ToUpper() != "JOIN") { return(false); } if (!TryParseSource(Parser, out Source2)) { return(false); } Conditions = ParseJoinConditions(Parser); Source = new FullOuterJoin(Source, Source2, Conditions, Source.Start, Parser.Position - Source.Start, Parser.Expression); break; default: return(true); } } }
/// <summary> /// Tries to parse a script node. /// </summary> /// <param name="Parser">Custom parser.</param> /// <param name="Result">Parsed Script Node.</param> /// <returns>If successful in parsing a script node.</returns> public bool TryParse(ScriptParser Parser, out ScriptNode Result) { Result = null; try { List <ScriptNode> Columns; List <ScriptNode> ColumnNames; ScriptNode Top; string s; s = Parser.PeekNextToken().ToUpper(); if (s == string.Empty) { return(false); } if (s == "TOP") { Parser.NextToken(); Top = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken(); if (s == string.Empty) { return(false); } } else { Top = null; } if (s == "*") { Parser.NextToken(); Columns = null; ColumnNames = null; } else { Columns = new List <ScriptNode>(); ColumnNames = new List <ScriptNode>(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && s != "," && s != "FROM") { Name = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } Columns.Add(Node); ColumnNames.Add(Name); if (s != ",") { break; } Parser.NextToken(); } } s = Parser.NextToken().ToUpper(); if (s != "FROM") { return(false); } List <ScriptNode> Sources = new List <ScriptNode>(); List <ScriptNode> SourceNames = new List <ScriptNode>(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && s != "," && s != "WHERE" && s != "GROUP" && s != "ORDER" && s != "OFFSET") { Name = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } Sources.Add(Node); SourceNames.Add(Name); if (s != ",") { break; } Parser.NextToken(); } ScriptNode Where = null; if (s == "WHERE") { Parser.NextToken(); Where = Parser.ParseOrs(); s = Parser.PeekNextToken().ToUpper(); } List <ScriptNode> GroupBy = null; List <ScriptNode> GroupByNames = null; ScriptNode Having = null; if (s == "GROUP") { Parser.NextToken(); if (Parser.NextToken().ToUpper() != "BY") { return(false); } GroupBy = new List <ScriptNode>(); GroupByNames = new List <ScriptNode>(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); ScriptNode Name = null; Parser.SkipWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (!string.IsNullOrEmpty(s) && s != "," && s != "HAVING" && s != "ORDER" && s != "OFFSET") { Name = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); } else if (Node is VariableReference Ref) { Name = new ConstantElement(new StringValue(Ref.VariableName), Node.Start, Node.Length, Node.Expression); } GroupBy.Add(Node); GroupByNames.Add(Name); if (s != ",") { break; } Parser.NextToken(); } if (s == "HAVING") { Parser.NextToken(); Having = Parser.ParseOrs(); s = Parser.PeekNextToken().ToUpper(); } } List <KeyValuePair <ScriptNode, bool> > OrderBy = null; if (s == "ORDER") { Parser.NextToken(); if (Parser.NextToken().ToUpper() != "BY") { return(false); } OrderBy = new List <KeyValuePair <ScriptNode, bool> >(); while (true) { ScriptNode Node = Parser.ParseNoWhiteSpace(); s = Parser.PeekNextToken().ToUpper(); if (s == "ASC") { Parser.NextToken(); OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, true)); s = Parser.PeekNextToken().ToUpper(); } else if (s == "DESC") { Parser.NextToken(); OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, false)); s = Parser.PeekNextToken().ToUpper(); } else { OrderBy.Add(new KeyValuePair <ScriptNode, bool>(Node, true)); } if (s != ",") { break; } Parser.NextToken(); } } ScriptNode Offset = null; if (s == "OFFSET") { Parser.NextToken(); Offset = Parser.ParseNoWhiteSpace(); } Result = new Select(Columns?.ToArray(), ColumnNames?.ToArray(), Sources.ToArray(), SourceNames.ToArray(), Where, GroupBy?.ToArray(), GroupByNames?.ToArray(), Having, OrderBy?.ToArray(), Top, Offset, Parser.Start, Parser.Length, Parser.Expression); return(true); } catch (Exception) { return(false); } }