public abstract TOutput Visit(SqlBinaryScalarExpression sqlObject, TArg input);
public abstract TResult Visit(SqlBinaryScalarExpression sqlObject);
public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into) { if (into == null) { return(null); } if (replacement == null) { throw new ArgumentNullException("replacement"); } switch (into.Kind) { case SqlObjectKind.ArrayCreateScalarExpression: { var arrayExp = into as SqlArrayCreateScalarExpression; if (arrayExp == null) { throw new DocumentQueryException("Expected a SqlArrayCreateScalarExpression, got a " + into.GetType()); } SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Count]; for (int i = 0; i < items.Length; i++) { var item = arrayExp.Items[i]; var replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlArrayCreateScalarExpression.Create(items)); } case SqlObjectKind.BinaryScalarExpression: { var binaryExp = into as SqlBinaryScalarExpression; if (binaryExp == null) { throw new DocumentQueryException("Expected a BinaryScalarExpression, got a " + into.GetType()); } var replleft = Substitute(replacement, toReplace, binaryExp.LeftExpression); var replright = Substitute(replacement, toReplace, binaryExp.RightExpression); return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright)); } case SqlObjectKind.UnaryScalarExpression: { var unaryExp = into as SqlUnaryScalarExpression; if (unaryExp == null) { throw new DocumentQueryException("Expected a SqlUnaryScalarExpression, got a " + into.GetType()); } var repl = Substitute(replacement, toReplace, unaryExp.Expression); return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl)); } case SqlObjectKind.LiteralScalarExpression: { return(into); } case SqlObjectKind.FunctionCallScalarExpression: { var funcExp = into as SqlFunctionCallScalarExpression; if (funcExp == null) { throw new DocumentQueryException("Expected a SqlFunctionCallScalarExpression, got a " + into.GetType()); } SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Count]; for (int i = 0; i < items.Length; i++) { var item = funcExp.Arguments[i]; var replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items)); } case SqlObjectKind.ObjectCreateScalarExpression: { SqlObjectCreateScalarExpression objExp = into as SqlObjectCreateScalarExpression; if (objExp == null) { throw new DocumentQueryException("Expected a SqlObjectCreateScalarExpression, got a " + into.GetType()); } return(SqlObjectCreateScalarExpression.Create( objExp .Properties .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Expression))))); } case SqlObjectKind.MemberIndexerScalarExpression: { var memberExp = into as SqlMemberIndexerScalarExpression; if (memberExp == null) { throw new DocumentQueryException("Expected a SqlMemberIndexerScalarExpression, got a " + into.GetType()); } var replMember = Substitute(replacement, toReplace, memberExp.MemberExpression); var replIndex = Substitute(replacement, toReplace, memberExp.IndexExpression); return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex)); } case SqlObjectKind.PropertyRefScalarExpression: { // This is the leaf of the recursion var propExp = into as SqlPropertyRefScalarExpression; if (propExp == null) { throw new DocumentQueryException("Expected a SqlPropertyRefScalarExpression, got a " + into.GetType()); } if (propExp.MemberExpression == null) { if (propExp.PropertyIdentifier.Value == toReplace.Value) { return(replacement); } else { return(propExp); } } else { var replMember = Substitute(replacement, toReplace, propExp.MemberExpression); return(SqlPropertyRefScalarExpression.Create(replMember, propExp.PropertyIdentifier)); } } case SqlObjectKind.ConditionalScalarExpression: { SqlConditionalScalarExpression conditionalExpression = (SqlConditionalScalarExpression)into; if (conditionalExpression == null) { throw new ArgumentException(); } SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.ConditionExpression); SqlScalarExpression first = Substitute(replacement, toReplace, conditionalExpression.FirstExpression); SqlScalarExpression second = Substitute(replacement, toReplace, conditionalExpression.SecondExpression); return(SqlConditionalScalarExpression.Create(condition, first, second)); } case SqlObjectKind.InScalarExpression: { SqlInScalarExpression inExpression = (SqlInScalarExpression)into; if (inExpression == null) { throw new ArgumentException(); } SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Expression); SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Items.Count]; for (int i = 0; i < items.Length; i++) { items[i] = Substitute(replacement, toReplace, inExpression.Items[i]); } return(SqlInScalarExpression.Create(expression, inExpression.Not, items)); } default: throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.Kind); } }
public abstract void Visit(SqlBinaryScalarExpression sqlObject);
public abstract TResult Visit(SqlBinaryScalarExpression scalarExpression);
private void AddFieldFromBinaryExpression(SqlBinaryScalarExpression expression, string name, MemoryDbDataReader.ResultBatch batch, RawData rawData) { var select = new SelectDataFromBinaryScalarExpression(expression, rawData); AddFieldFromSelectData(name, batch, select); }
public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into) { if (into == null) { return(null); } if (replacement == null) { throw new ArgumentNullException("replacement"); } switch (into) { case SqlArrayCreateScalarExpression arrayExp: { SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Length]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = arrayExp.Items[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlArrayCreateScalarExpression.Create(items)); } case SqlBinaryScalarExpression binaryExp: { SqlScalarExpression replleft = Substitute(replacement, toReplace, binaryExp.LeftExpression); SqlScalarExpression replright = Substitute(replacement, toReplace, binaryExp.RightExpression); return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright)); } case SqlUnaryScalarExpression unaryExp: { SqlScalarExpression repl = Substitute(replacement, toReplace, unaryExp.Expression); return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl)); } case SqlLiteralScalarExpression literalScalarExpression: { return(into); } case SqlFunctionCallScalarExpression funcExp: { SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Length]; for (int i = 0; i < items.Length; i++) { SqlScalarExpression item = funcExp.Arguments[i]; SqlScalarExpression replitem = Substitute(replacement, toReplace, item); items[i] = replitem; } return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items)); } case SqlObjectCreateScalarExpression objExp: { return(SqlObjectCreateScalarExpression.Create( objExp .Properties .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Value))) .ToImmutableArray())); } case SqlMemberIndexerScalarExpression memberExp: { SqlScalarExpression replMember = Substitute(replacement, toReplace, memberExp.Member); SqlScalarExpression replIndex = Substitute(replacement, toReplace, memberExp.Indexer); return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex)); } case SqlPropertyRefScalarExpression propExp: { // This is the leaf of the recursion if (propExp.Member == null) { if (propExp.Identifier.Value == toReplace.Value) { return(replacement); } else { return(propExp); } } else { SqlScalarExpression replMember = Substitute(replacement, toReplace, propExp.Member); return(SqlPropertyRefScalarExpression.Create(replMember, propExp.Identifier)); } } case SqlConditionalScalarExpression conditionalExpression: { SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.Condition); SqlScalarExpression first = Substitute(replacement, toReplace, conditionalExpression.Consequent); SqlScalarExpression second = Substitute(replacement, toReplace, conditionalExpression.Alternative); return(SqlConditionalScalarExpression.Create(condition, first, second)); } case SqlInScalarExpression inExpression: { SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Needle); SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Haystack.Length]; for (int i = 0; i < items.Length; i++) { items[i] = Substitute(replacement, toReplace, inExpression.Haystack[i]); } return(SqlInScalarExpression.Create(expression, inExpression.Not, items)); } default: throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.GetType()); } }
public void Binary() { // Positive List <SqlParserBaselineTestInput> inputs = new List <SqlParserBaselineTestInput>(); foreach (SqlBinaryScalarOperatorKind binaryOperator in (SqlBinaryScalarOperatorKind[])Enum.GetValues(typeof(SqlBinaryScalarOperatorKind))) { inputs.Add( CreateInput( description: binaryOperator.ToString(), scalarExpression: SqlBinaryScalarExpression.Create( binaryOperator, SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(42)), SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(1337))).ToString())); } // Order of operations inputs.Add(CreateInput( description: "Multiplication, division, and remainder -> left to right", scalarExpression: "1 / 2 * 3 % 4")); inputs.Add(CreateInput( description: "Addition and subtraction -> left to right", scalarExpression: "1 + 2 - 3 + 4")); inputs.Add(CreateInput( description: "Relational operators -> left to right", scalarExpression: "1 < 2 <= 3 > 4 >= 5")); inputs.Add(CreateInput( description: "Equality operators -> left to right", scalarExpression: "1 = 2 != 3 = 4")); inputs.Add(CreateInput( description: "Bitwise AND > Bitwise XOR (exclusive or) > Bitwise OR (inclusive or)", scalarExpression: "1 | 2 & 3 ^ 4")); inputs.Add(CreateInput( description: "Logical AND > Logical OR", scalarExpression: "1 AND 2 OR 3 AND 4")); inputs.Add(CreateInput( description: "Conditional-expression Right to left", scalarExpression: "1 ? 2 : 3 + 4")); inputs.Add(CreateInput( description: "Multiplicative > Additive", scalarExpression: "1 + 2 * 3 - 4 / 5")); inputs.Add(CreateInput( description: "Additive > Relational", scalarExpression: "1 + 2 < 2 + 3 <= 10 - 4 > 5 >= 3")); inputs.Add(CreateInput( description: "Relational > Equality", scalarExpression: "1 > 2 = false AND 1 > 2 != true")); inputs.Add(CreateInput( description: "Equality > Bitwise AND", scalarExpression: "1 = 2 & 3 != 4")); inputs.Add(CreateInput( description: "Bitwise AND > Bitwise Exclusive OR", scalarExpression: "1 ^ 2 & 3 ^ 4")); inputs.Add(CreateInput( description: "Bitwise Exclusive OR > Bitwise Inclusive OR", scalarExpression: "1 | 2 ^ 3 | 4")); inputs.Add(CreateInput( description: "Bitwise Inclusive OR > Logical AND", scalarExpression: "1 AND 2 | 3 AND 4")); inputs.Add(CreateInput( description: "Logical AND > Logical OR", scalarExpression: "1 OR 2 AND 3 OR 4")); inputs.Add(CreateInput( description: "Logical OR > String Concat", scalarExpression: "1 || 2 OR 3 || 4")); // Binary with logical expressions inputs.Add(CreateInput( description: "AND with LIKE expressions", scalarExpression: "r.name LIKE 12 AND r.name LIKE 34")); inputs.Add(CreateInput( description: "OR with LIKE expression", scalarExpression: "r.name LIKE 12 OR r.name LIKE 34")); inputs.Add(CreateInput( description: "AND with IN expression", scalarExpression: "r.name IN (1,2,3) AND r.name IN (4,5,6)")); inputs.Add(CreateInput( description: "OR with IN expression", scalarExpression: "r.name IN (1,2,3) OR r.name IN (4,5,6)")); inputs.Add(CreateInput( description: "Double AND", scalarExpression: "r.age = 1 AND r.age = 2 AND r.age = 3")); inputs.Add(CreateInput( description: "Double OR", scalarExpression: "r.age = 1 OR r.age = 2 OR r.age = 3")); inputs.Add(CreateInput( description: "AND and then OR", scalarExpression: "r.age = 1 AND r.age = 2 OR r.age = 3")); inputs.Add(CreateInput( description: "OR and then AND", scalarExpression: "r.age = 1 OR r.age = 2 AND r.age = 3")); // Negative inputs.Add(CreateInput(description: "Missing Right", scalarExpression: "42 +")); inputs.Add(CreateInput(description: "Missing Left", scalarExpression: "AND 1337")); inputs.Add(CreateInput(description: "Unknown Operator", scalarExpression: "42 # 1337")); this.ExecuteTestSuite(inputs); }
public override bool Visit(SqlBinaryScalarExpression sqlBinaryScalarExpression) { return(sqlBinaryScalarExpression.LeftExpression.Accept(this) || sqlBinaryScalarExpression.RightExpression.Accept(this)); }
public abstract void Visit(SqlBinaryScalarExpression scalarExpression);
public override void Visit(SqlBinaryScalarExpression codeObject) { Format(codeObject); }
public override CosmosElement Visit( SqlBinaryScalarExpression scalarExpression, CosmosElement document) { CosmosElement left = scalarExpression.LeftExpression.Accept(this, document); CosmosElement right = scalarExpression.RightExpression.Accept(this, document); CosmosElement result; switch (scalarExpression.OperatorKind) { case SqlBinaryScalarOperatorKind.Add: result = PerformBinaryNumberOperation((number1, number2) => number1 + number2, left, right); break; case SqlBinaryScalarOperatorKind.And: result = PerformLogicalAnd(left, right); break; case SqlBinaryScalarOperatorKind.BitwiseAnd: result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) & DoubleToInt32Bitwise(number2), left, right); break; case SqlBinaryScalarOperatorKind.BitwiseOr: result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) | DoubleToInt32Bitwise(number2), left, right); break; case SqlBinaryScalarOperatorKind.BitwiseXor: result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) ^ DoubleToInt32Bitwise(number2), left, right); break; case SqlBinaryScalarOperatorKind.Coalesce: if (left != Undefined) { result = left; } else { result = right; } break; case SqlBinaryScalarOperatorKind.Divide: result = PerformBinaryNumberOperation((number1, number2) => number1 / number2, left, right); break; case SqlBinaryScalarOperatorKind.Equal: result = PerformBinaryEquality(equals => equals, left, right); break; case SqlBinaryScalarOperatorKind.GreaterThan: result = PerformBinaryInequality((comparison) => comparison > 0, left, right); break; case SqlBinaryScalarOperatorKind.GreaterThanOrEqual: result = PerformBinaryInequality((comparison) => comparison >= 0, left, right); break; case SqlBinaryScalarOperatorKind.LessThan: result = PerformBinaryInequality((comparison) => comparison < 0, left, right); break; case SqlBinaryScalarOperatorKind.LessThanOrEqual: result = PerformBinaryInequality((comparison) => comparison <= 0, left, right); break; case SqlBinaryScalarOperatorKind.Modulo: result = PerformBinaryNumberOperation((number1, number2) => number1 % number2, left, right); break; case SqlBinaryScalarOperatorKind.Multiply: result = PerformBinaryNumberOperation((number1, number2) => number1 * number2, left, right); break; case SqlBinaryScalarOperatorKind.NotEqual: result = PerformBinaryEquality(equals => !equals, left, right); break; case SqlBinaryScalarOperatorKind.Or: result = PerformLogicalOr(left, right); break; case SqlBinaryScalarOperatorKind.StringConcat: result = PerformBinaryStringOperation((string1, string2) => string1 + string2, left, right); break; case SqlBinaryScalarOperatorKind.Subtract: result = PerformBinaryNumberOperation((number1, number2) => number1 - number2, left, right); break; default: throw new ArgumentException($"Unknown {nameof(SqlBinaryScalarOperatorKind)}: {scalarExpression.OperatorKind}"); } return(result); }