private Expression BuildLinqExpression(ref ParserContext context, StatementPart part) { if (part.SubParts != null) { return(BuildLinqExpression(ref context, part.SubParts, part.SubParts.Count)); } if (part.Variable != null) { var existing = context.LinqParameters.FirstOrDefault(x => x.Name == part.Variable); if (existing != null) { return(existing); } var expression = Expression.Parameter(typeof(double), part.Variable); context.LinqParameters.Add(expression); return(expression); } else if (part.Number != null) { if (!Double.TryParse(part.Number, out double value)) { throw new MathParserException($"Invalid expression \"{part.Number}\" at \"{part.Index}\""); } var expression = Expression.Constant(value, typeof(double)); return(expression); } else { throw new MathParserException($"Invalid expression \"{part.Token}\" at \"{part.Index}\""); } }
// TODO: all operators // public CompareOperatorPart NotEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.NotEqual); // public CompareOperatorPart GreaterThan() => BuildCompareOperatorPart(CompareOperatorKeyword.GreaterThan); // public CompareOperatorPart LessThan() => BuildCompareOperatorPart(CompareOperatorKeyword.LessThan); // public CompareOperatorPart GreaterThanOrEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.GreaterThanOrEqual); // public CompareOperatorPart LessThanOrEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.LessThanOrEqual); // public CompareOperatorPart StartsWith() => BuildCompareOperatorPart(CompareOperatorKeyword.StartsWith); // public CompareOperatorPart EndsWith() => BuildCompareOperatorPart(CompareOperatorKeyword.EndsWith); // public CompareOperatorPart Contains() => BuildCompareOperatorPart(CompareOperatorKeyword.Contains); private StatementPart Build(StatementKeyword statementKeyword) { var part = new StatementPart(statementKeyword, TestQueryBuilder); TestQueryBuilder._queryParts.Add(part); return(part); }
private StatementPart ParseParts(ref ParserContext context) { var subparts = new List <StatementPart>(); var startIndex = context.Index; while (context.Index < context.Chars.Length) { while (Char.IsWhiteSpace(context.Current) && context.Index < context.Chars.Length) { context.Next(); } var subpart = ParseOperators(ref context); if (subpart == null) { break; } subparts.Add(subpart); } while (Char.IsWhiteSpace(context.Current) && context.Index < context.Chars.Length) { context.Next(); } var part = new StatementPart(startIndex, subparts); return(part); }
private void VisitDatePartField(StatementPart datePart) { if (datePart.PartType == StatementPartType.ConstantPart) { var constantPart = (ConstantPart)datePart; // HACK: Not 100% sure it will always be convertible to an int? var value = Convert.ToInt32(constantPart.Value).ToString("D2"); this.VisitField(new ConstantPart(value)); } else { this.VisitField(datePart); } }
public override void EnterPredicate([NotNull] TSqlParser.PredicateContext context) { base.EnterPredicate(context); string debug = context.GetText(); var sourceInterval = context.SourceInterval; Console.WriteLine("EnterPredicate:"); Console.WriteLine(debug); Console.WriteLine("---"); var select = GetStatementAsSelect(); var part = new StatementPart(); part.StatementTableName = select.Tables.FirstOrDefault(); part.Text = context.GetText(); part.StatementOrigin = "EnterPredicate"; int a = context.Start.StartIndex; int b = context.Stop.StopIndex; Interval interval = new Interval(a, b); _charStream = context.Start.InputStream; part.TextWithWhiteSpace = _charStream.GetText(interval); var parent = context.Parent.Parent; if (parent != null) { part.StatementParent = parent.GetText(); var tokenInterval = parent.SourceInterval; part.StatementParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval); } var grandparent = context.Parent.Parent.Parent; if (grandparent != null) { part.StatementGrandParent = grandparent.GetText(); var tokenInterval = grandparent.SourceInterval; part.StatementGrandParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval); } part.ParseStatementPart(); select.Statements.Add(part); }
private StatementPart ParseNumbersAndVariables(ref ParserContext context) { if (numbersAndLetters.Contains(context.Current)) { int startIndex = context.Index; while (context.Index < context.Chars.Length) { context.Next(); if (!numbersAndLetters.Contains(context.Current)) { int length = context.Index - startIndex; var token = context.Chars.Slice(startIndex, length).ToString(); var part = new StatementPart(startIndex, token); return(part); } } } return(null); }
public override void EnterPredicate([NotNull] TSqlParser.PredicateContext context) { base.EnterPredicate(context); Console.WriteLine(context.GetText()); var part = new StatementPart(); part.StatementTableName = _dmlStatement.Tables.FirstOrDefault(); part.Text = context.GetText(); part.StatementOrigin = "EnterPredicate"; part.TextWithWhiteSpace = GetWhiteSpaceFormat(context); var parent = context.Parent.Parent; if (parent != null) { part.StatementParent = parent.GetText(); var tokenInterval = parent.SourceInterval; part.StatementParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval); } var grandparent = context.Parent.Parent.Parent; if (grandparent != null) { part.StatementGrandParent = grandparent.GetText(); var tokenInterval = grandparent.SourceInterval; part.StatementGrandParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval); } if (!part.ParseStatementPart()) { _dmlStatement.IsValid = false; } _dmlStatement.WhereClause.Conditions.Add(part); }
protected virtual StatementPart VisitUnary(UnaryExpression unaryExpression) { switch (unaryExpression.NodeType) { case ExpressionType.Not: var o = Visit(unaryExpression.Operand); if (o is ParameterPart op && op.ParameterType == typeof(bool)) { Parameters[op.Text] = !(bool)Parameters[op.Text]; return(o); } if (o is ColumnAccessPart oc && oc.ColumnType == typeof(bool)) { o = new StatementPart($"{o.Text} = {AddParameter(true)}"); } return(new StatementPart($"NOT ({o})")); case ExpressionType.Convert: if (unaryExpression.Method != null) { var value = Expression.Lambda(unaryExpression).Compile().DynamicInvoke(); if (value != null) { return(AddParameter(value)); } return(null); } break; } return(Visit(unaryExpression.Operand)); }
public SearchStep(StatementPart part) : this() { _part = part; }
protected virtual StatementPart VisitBinary(BinaryExpression binaryExpression) { var left = Visit(binaryExpression.Left); var right = Visit(binaryExpression.Right); var leftca = left as ColumnAccessPart; var rightca = right as ColumnAccessPart; var leftp = left as ParameterPart; var rightp = right as ParameterPart; if (leftp != null && rightp != null) { // if both sides are parameters, let's do the comparison here Parameters.Remove(leftp.Text); Parameters.Remove(rightp.Text); var result = Expression.Lambda(binaryExpression).Compile().DynamicInvoke(); return(AddParameter(result)); } var isIntegral = leftp != null && leftp.ParameterType != typeof(bool); if (!isIntegral && rightp != null && rightp.ParameterType != typeof(bool)) { isIntegral = true; } var operand = DialectProvider.BindOperand(binaryExpression.NodeType, isIntegral); if (operand == "AND" || operand == "OR") { if (leftca?.ColumnType == typeof(bool)) { left = new StatementPart($"{leftca.Text} = {AddParameter(true)}"); } if (rightca?.ColumnType == typeof(bool)) { right = new StatementPart($"{rightca.Text} = {AddParameter(true)}"); } if (leftp?.ParameterType == typeof(bool) || rightp?.ParameterType == typeof(bool)) { var boolValue = (bool)(leftp != null ? Parameters[leftp.Text] : Parameters[rightp.Text]); if (operand == "AND") { if (boolValue) { return(leftp != null ? left : right); } return(AddParameter(false)); } if (operand == "OR") { if (boolValue) { return(AddParameter(true)); } return(leftp != null ? left : right); } } } else { if (leftca != null && leftca.ColumnType.IsEnum() && rightp != null) { Parameters[rightp.Text] = Enum.ToObject(leftca.ColumnType, Parameters[rightp.Text]); } if (rightca != null && rightca.ColumnType.IsEnum() && leftp != null) { Parameters[leftp.Text] = Enum.ToObject(rightca.ColumnType, Parameters[leftp.Text]); } } if (right == null || left == null) { operand = operand == "=" ? "IS" : "IS NOT"; } switch (operand) { case "MOD": case "COALESCE": return(new StatementPart($"{operand}({left},{right})")); default: StringBuilder part = new StringBuilder("("); part.Append(left == null ? "NULL" : left.ToString()); part.Append(" "); part.Append(operand); part.Append(" "); part.Append(right == null ? "NULL" : right.ToString()); part.Append(")"); return(new StatementPart(part.ToString())); } }
private StatementPart ParseOperators(ref ParserContext context) { int startIndex = context.Index; MethodOperator methodFound = null; UnaryOperator unaryFound = null; BinaryOperator binaryFound = null; while (context.Index < context.Chars.Length) { context.Next(); int length = context.Index - startIndex; if (length > operatorStringsMaxLength) { break; } var partTokens = context.Chars.Slice(startIndex, length); foreach (var methodOperator in methodOperators) { if (partTokens.SequenceEqual(methodOperator.TokenWithOpener.AsSpan())) { methodFound = methodOperator; break; } } foreach (var unaryOperator in unaryOperators) { if (partTokens.SequenceEqual(unaryOperator.Token.AsSpan())) { unaryFound = unaryOperator; break; } } foreach (var binaryOperator in binaryOperators) { if (partTokens.SequenceEqual(binaryOperator.Token.AsSpan())) { binaryFound = binaryOperator; break; } } if (methodFound != null) { break; //ending ( guarentees can't be longer } } if (methodFound != null) { var argumentParts = new List <StatementPart>(); while (context.Index < context.Chars.Length) { context.GroupStack.Push(MethodOperator.ArgumentOpener); var argumentPart = ParseParts(ref context); argumentParts.Add(argumentPart); if (context.Current != MethodOperator.ArgumentSeperator) { break; } context.Next(); } var part = new StatementPart(startIndex, methodFound, argumentParts); return(part); } if (unaryFound != null && binaryFound != null) { if (unaryFound.Token.Length < binaryFound.Token.Length) { binaryFound = null; } else if (unaryFound.Token.Length > binaryFound.Token.Length) { unaryFound = null; } if (unaryFound != null && binaryFound != null) { context.Reset(startIndex + unaryFound.Token.Length); //possibly looked for a longer operator name var part = new StatementPart(startIndex, unaryFound, binaryFound); return(part); } } if (unaryFound != null) { context.Reset(startIndex + unaryFound.Token.Length); //possibly looked for a longer operator name var part = new StatementPart(startIndex, unaryFound); return(part); } if (binaryFound != null) { context.Reset(startIndex + binaryFound.Token.Length); //possibly looked for a longer operator name var part = new StatementPart(startIndex, binaryFound); return(part); } context.Reset(startIndex); return(ParseGroupOpen(ref context)); }