protected virtual void Write(SoqlBinaryOperator op)
        {
            switch (op)
            {
                case SoqlBinaryOperator.Add:
                    Output.Write('+');
                    break;

                case SoqlBinaryOperator.Sub:
                    Output.Write('-');
                    break;

                case SoqlBinaryOperator.Div:
                    Output.Write('/');
                    break;

                case SoqlBinaryOperator.Mul:
                    Output.Write('*');
                    break;

                case SoqlBinaryOperator.Mod:
                    Output.Write('%');
                    break;

                case SoqlBinaryOperator.Concat:
                    Output.Write("||");
                    break;
            }
        }
        protected virtual void Write(SoqlBinaryOperator op)
        {
            switch (op)
            {
            case SoqlBinaryOperator.Add:
                Output.Write('+');
                break;

            case SoqlBinaryOperator.Sub:
                Output.Write('-');
                break;

            case SoqlBinaryOperator.Div:
                Output.Write('/');
                break;

            case SoqlBinaryOperator.Mul:
                Output.Write('*');
                break;

            case SoqlBinaryOperator.Mod:
                Output.Write('%');
                break;

            case SoqlBinaryOperator.Concat:
                Output.Write("||");
                break;
            }
        }
        private static object CalcValue(SoqlBinaryOperator op, object val1, object val2)
        {
            if (val1 == null || val2 == null)
                return null;

            //
            // the type precedence is based on SQL2000 "Data Type Precedence"
            // help topic
            //

            switch (op)
            {
                case SoqlBinaryOperator.Add:
                    if (val1 is double || val2 is double)
                        return Convert.ToDouble(val1) + Convert.ToDouble(val2);
                    if (val1 is float || val2 is float)
                        return Convert.ToSingle(val1) + Convert.ToSingle(val2);
                    if (val1 is decimal || val2 is decimal)
                        return Convert.ToDecimal(val1) + Convert.ToDecimal(val2);
                    if (val1 is long || val2 is long)
                        return Convert.ToInt64(val1) + Convert.ToInt64(val2);
                    if (val1 is int || val2 is int)
                        return Convert.ToInt32(val1) + Convert.ToInt32(val2);
                    if (val1 is short || val2 is short)
                        return Convert.ToInt16(val1) + Convert.ToInt16(val2);
                    if (val1 is sbyte || val2 is sbyte)
                        return Convert.ToSByte(val1) + Convert.ToSByte(val2);
                    if (val1 is string || val2 is string)
                        return Convert.ToString(val1) + Convert.ToString(val2);
                    throw new NotSupportedException("Addition not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

                case SoqlBinaryOperator.Sub:
                    if (val1 is double || val2 is double)
                        return Convert.ToDouble(val1) - Convert.ToDouble(val2);
                    if (val1 is float || val2 is float)
                        return Convert.ToSingle(val1) - Convert.ToSingle(val2);
                    if (val1 is decimal || val2 is decimal)
                        return Convert.ToDecimal(val1) - Convert.ToDecimal(val2);
                    if (val1 is long || val2 is long)
                        return Convert.ToInt64(val1) - Convert.ToInt64(val2);
                    if (val1 is int || val2 is int)
                        return Convert.ToInt32(val1) - Convert.ToInt32(val2);
                    if (val1 is short || val2 is short)
                        return Convert.ToInt16(val1) - Convert.ToInt16(val2);
                    if (val1 is sbyte || val2 is sbyte)
                        return Convert.ToSByte(val1) - Convert.ToSByte(val2);
                    throw new NotSupportedException("Subtraction not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

                case SoqlBinaryOperator.Mul:
                    if (val1 is double || val2 is double)
                        return Convert.ToDouble(val1) * Convert.ToDouble(val2);
                    if (val1 is float || val2 is float)
                        return Convert.ToSingle(val1) * Convert.ToSingle(val2);
                    if (val1 is decimal || val2 is decimal)
                        return Convert.ToDecimal(val1) * Convert.ToDecimal(val2);
                    if (val1 is long || val2 is long)
                        return Convert.ToInt64(val1) * Convert.ToInt64(val2);
                    if (val1 is int || val2 is int)
                        return Convert.ToInt32(val1) * Convert.ToInt32(val2);
                    if (val1 is short || val2 is short)
                        return Convert.ToInt16(val1) * Convert.ToInt16(val2);
                    if (val1 is sbyte || val2 is sbyte)
                        return Convert.ToSByte(val1) * Convert.ToSByte(val2);
                    throw new NotSupportedException("Multiplication not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

                case SoqlBinaryOperator.Div:
                    if (val1 is double || val2 is double)
                        return Convert.ToDouble(val1) / Convert.ToDouble(val2);
                    if (val1 is float || val2 is float)
                        return Convert.ToSingle(val1) / Convert.ToSingle(val2);
                    if (val1 is decimal || val2 is decimal)
                        return Convert.ToDecimal(val1) / Convert.ToDecimal(val2);
                    if (val1 is long || val2 is long)
                        return Convert.ToInt64(val1) / Convert.ToInt64(val2);
                    if (val1 is int || val2 is int)
                        return Convert.ToInt32(val1) / Convert.ToInt32(val2);
                    if (val1 is short || val2 is short)
                        return Convert.ToInt16(val1) / Convert.ToInt16(val2);
                    if (val1 is sbyte || val2 is sbyte)
                        return Convert.ToSByte(val1) / Convert.ToSByte(val2);
                    throw new NotSupportedException("Division not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

                case SoqlBinaryOperator.Mod:
                    if (val1 is double || val2 is double)
                        return Convert.ToDouble(val1) % Convert.ToDouble(val2);
                    if (val1 is float || val2 is float)
                        return Convert.ToSingle(val1) % Convert.ToSingle(val2);
                    if (val1 is decimal || val2 is decimal)
                        return Convert.ToDecimal(val1) % Convert.ToDecimal(val2);
                    if (val1 is long || val2 is long)
                        return Convert.ToInt64(val1) % Convert.ToInt64(val2);
                    if (val1 is int || val2 is int)
                        return Convert.ToInt32(val1) % Convert.ToInt32(val2);
                    if (val1 is short || val2 is short)
                        return Convert.ToInt16(val1) % Convert.ToInt16(val2);
                    if (val1 is sbyte || val2 is sbyte)
                        return Convert.ToSByte(val1) % Convert.ToSByte(val2);
                    throw new NotSupportedException("Modulus not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

                case SoqlBinaryOperator.Concat:
                    return Convert.ToString(val1) + Convert.ToString(val2);

                default:
                    throw new NotSupportedException("Binary operator " + op + " is not supported.");
            }
        }
 public SoqlBinaryExpression(SoqlExpression par1, SoqlExpression par2, SoqlBinaryOperator op)
 {
     this.par1 = par1;
     this.par2 = par2;
     this.op = op;
 }
        private static object CalcValue(SoqlBinaryOperator op, object val1, object val2)
        {
            if (val1 == null || val2 == null)
            {
                return(null);
            }

            //
            // the type precedence is based on SQL2000 "Data Type Precedence"
            // help topic
            //

            switch (op)
            {
            case SoqlBinaryOperator.Add:
                if (val1 is double || val2 is double)
                {
                    return(Convert.ToDouble(val1) + Convert.ToDouble(val2));
                }
                if (val1 is float || val2 is float)
                {
                    return(Convert.ToSingle(val1) + Convert.ToSingle(val2));
                }
                if (val1 is decimal || val2 is decimal)
                {
                    return(Convert.ToDecimal(val1) + Convert.ToDecimal(val2));
                }
                if (val1 is long || val2 is long)
                {
                    return(Convert.ToInt64(val1) + Convert.ToInt64(val2));
                }
                if (val1 is int || val2 is int)
                {
                    return(Convert.ToInt32(val1) + Convert.ToInt32(val2));
                }
                if (val1 is short || val2 is short)
                {
                    return(Convert.ToInt16(val1) + Convert.ToInt16(val2));
                }
                if (val1 is sbyte || val2 is sbyte)
                {
                    return(Convert.ToSByte(val1) + Convert.ToSByte(val2));
                }
                if (val1 is string || val2 is string)
                {
                    return(Convert.ToString(val1) + Convert.ToString(val2));
                }
                throw new NotSupportedException("Addition not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

            case SoqlBinaryOperator.Sub:
                if (val1 is double || val2 is double)
                {
                    return(Convert.ToDouble(val1) - Convert.ToDouble(val2));
                }
                if (val1 is float || val2 is float)
                {
                    return(Convert.ToSingle(val1) - Convert.ToSingle(val2));
                }
                if (val1 is decimal || val2 is decimal)
                {
                    return(Convert.ToDecimal(val1) - Convert.ToDecimal(val2));
                }
                if (val1 is long || val2 is long)
                {
                    return(Convert.ToInt64(val1) - Convert.ToInt64(val2));
                }
                if (val1 is int || val2 is int)
                {
                    return(Convert.ToInt32(val1) - Convert.ToInt32(val2));
                }
                if (val1 is short || val2 is short)
                {
                    return(Convert.ToInt16(val1) - Convert.ToInt16(val2));
                }
                if (val1 is sbyte || val2 is sbyte)
                {
                    return(Convert.ToSByte(val1) - Convert.ToSByte(val2));
                }
                throw new NotSupportedException("Subtraction not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

            case SoqlBinaryOperator.Mul:
                if (val1 is double || val2 is double)
                {
                    return(Convert.ToDouble(val1) * Convert.ToDouble(val2));
                }
                if (val1 is float || val2 is float)
                {
                    return(Convert.ToSingle(val1) * Convert.ToSingle(val2));
                }
                if (val1 is decimal || val2 is decimal)
                {
                    return(Convert.ToDecimal(val1) * Convert.ToDecimal(val2));
                }
                if (val1 is long || val2 is long)
                {
                    return(Convert.ToInt64(val1) * Convert.ToInt64(val2));
                }
                if (val1 is int || val2 is int)
                {
                    return(Convert.ToInt32(val1) * Convert.ToInt32(val2));
                }
                if (val1 is short || val2 is short)
                {
                    return(Convert.ToInt16(val1) * Convert.ToInt16(val2));
                }
                if (val1 is sbyte || val2 is sbyte)
                {
                    return(Convert.ToSByte(val1) * Convert.ToSByte(val2));
                }
                throw new NotSupportedException("Multiplication not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

            case SoqlBinaryOperator.Div:
                if (val1 is double || val2 is double)
                {
                    return(Convert.ToDouble(val1) / Convert.ToDouble(val2));
                }
                if (val1 is float || val2 is float)
                {
                    return(Convert.ToSingle(val1) / Convert.ToSingle(val2));
                }
                if (val1 is decimal || val2 is decimal)
                {
                    return(Convert.ToDecimal(val1) / Convert.ToDecimal(val2));
                }
                if (val1 is long || val2 is long)
                {
                    return(Convert.ToInt64(val1) / Convert.ToInt64(val2));
                }
                if (val1 is int || val2 is int)
                {
                    return(Convert.ToInt32(val1) / Convert.ToInt32(val2));
                }
                if (val1 is short || val2 is short)
                {
                    return(Convert.ToInt16(val1) / Convert.ToInt16(val2));
                }
                if (val1 is sbyte || val2 is sbyte)
                {
                    return(Convert.ToSByte(val1) / Convert.ToSByte(val2));
                }
                throw new NotSupportedException("Division not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

            case SoqlBinaryOperator.Mod:
                if (val1 is double || val2 is double)
                {
                    return(Convert.ToDouble(val1) % Convert.ToDouble(val2));
                }
                if (val1 is float || val2 is float)
                {
                    return(Convert.ToSingle(val1) % Convert.ToSingle(val2));
                }
                if (val1 is decimal || val2 is decimal)
                {
                    return(Convert.ToDecimal(val1) % Convert.ToDecimal(val2));
                }
                if (val1 is long || val2 is long)
                {
                    return(Convert.ToInt64(val1) % Convert.ToInt64(val2));
                }
                if (val1 is int || val2 is int)
                {
                    return(Convert.ToInt32(val1) % Convert.ToInt32(val2));
                }
                if (val1 is short || val2 is short)
                {
                    return(Convert.ToInt16(val1) % Convert.ToInt16(val2));
                }
                if (val1 is sbyte || val2 is sbyte)
                {
                    return(Convert.ToSByte(val1) % Convert.ToSByte(val2));
                }
                throw new NotSupportedException("Modulus not supported for arguments of type " + val1.GetType().Name + " and " + val2.GetType().Name);

            case SoqlBinaryOperator.Concat:
                return(Convert.ToString(val1) + Convert.ToString(val2));

            default:
                throw new NotSupportedException("Binary operator " + op + " is not supported.");
            }
        }
 public SoqlBinaryExpression(SoqlExpression par1, SoqlExpression par2, SoqlBinaryOperator op)
 {
     this.par1 = par1;
     this.par2 = par2;
     this.op   = op;
 }
 protected override void Write(SoqlBinaryOperator op)
 {
     if (op == SoqlBinaryOperator.Concat)
         Output.Write(_builder.StringConcatenationOperator);
     else
         base.Write(op);
 }