示例#1
0
        private void JoinViaIn(SqlStatement statement, SqlSelect @select)
        {
            SqlTableRef table = GetStatementTable(statement);

            SqlExpression where = GetStatementWhere(statement);
            JoinedTableRef      = table;
            PrimaryIndexMapping indexMapping = PrimaryIndexes[0];
            var columns = new List <ColumnInfo>();

            foreach (ColumnInfo columnInfo in indexMapping.PrimaryIndex.KeyColumns.Keys)
            {
                SqlSelect s = select.ShallowClone();
                foreach (ColumnInfo column in columns)
                {
                    SqlBinary ex = SqlDml.Equals(SqlDml.TableColumn(s.From, column.Name), SqlDml.TableColumn(table, column.Name));
                    s.Where = s.Where.IsNullReference() ? ex : SqlDml.And(s.Where, ex);
                }
                s.Columns.Clear();
                s.Columns.Add(SqlDml.TableColumn(s.From, columnInfo.Name));
                SqlBinary @in = SqlDml.In(SqlDml.TableColumn(table, columnInfo.Name), s);
                @where = @where.IsNullReference() ? @in : SqlDml.And(@where, @in);
                columns.Add(columnInfo);
            }
            SetStatementWhere(statement, where);
        }
示例#2
0
        private void JoinViaFrom(SqlStatement statement, SqlSelect select)
        {
            var queryRef = SqlDml.QueryRef(select, "source");

            SetStatementFrom(statement, queryRef);
            var                 sqlTableRef     = GetStatementTable(statement);
            SqlExpression       whereExpression = null;
            PrimaryIndexMapping indexMapping    = PrimaryIndexes[0];

            foreach (ColumnInfo columnInfo in indexMapping.PrimaryIndex.KeyColumns.Keys)
            {
                var leftColumn  = queryRef.Columns[columnInfo.Name];
                var rightColumn = sqlTableRef == null?GetStatementTable(statement).Columns[columnInfo.Name] : sqlTableRef.Columns[columnInfo.Name];

                if (leftColumn == null || rightColumn == null)
                {
                    throw new InvalidOperationException("Source query doesn't contain one of key columns of updated table.");
                }
                var columnEqualityExperssion = SqlDml.Equals(queryRef.Columns[columnInfo.Name], sqlTableRef.Columns[columnInfo.Name]);
                if (whereExpression == null)
                {
                    whereExpression = columnEqualityExperssion;
                }
                else
                {
                    whereExpression = SqlDml.And(whereExpression, columnEqualityExperssion);
                }
            }
            SetStatementWhere(statement, whereExpression);
        }
        public SqlExpression IntToBoolean(SqlExpression expression)
        {
            // optimization: omitting IntToBoolean(BooleanToInt(x)) sequences
            if (expression.NodeType == SqlNodeType.Cast)
            {
                var operand = ((SqlCast)expression).Operand;
                if (operand.NodeType == SqlNodeType.Case)
                {
                    var _case = (SqlCase)operand;
                    if (_case.Count == 1)
                    {
                        var firstCaseItem = _case.First();
                        var whenTrue      = firstCaseItem.Value as SqlLiteral <int>;
                        var whenFalse     = _case.Else as SqlLiteral <int>;
                        if (!ReferenceEquals(whenTrue, null) &&
                            !ReferenceEquals(whenFalse, null) &&
                            whenTrue.Value == 1 &&
                            whenFalse.Value == 0)
                        {
                            return(firstCaseItem.Key);
                        }
                    }
                }
            }

            return(SqlDml.Equals(expression, 1));
        }
示例#4
0
        public void Test026()
        {
            string nativeSql = @"SELECT 
                                  p.CustomerId,
                                  p.Commission
                           FROM
                                  invoice p
                           WHERE
                                  p.Commission = (SELECT MIN(Commission) AS LowestCommission FROM invoice)";

            SqlTableRef invoice1 = SqlDml.TableRef(schema.Tables["invoice"], "p1");
            SqlTableRef invoice2 = SqlDml.TableRef(schema.Tables["invoice"], "p2");

            SqlSelect innerSelect = SqlDml.Select(invoice2);

            innerSelect.Columns.Add(SqlDml.Min(invoice2["Commission"]));

            SqlSelect select = SqlDml.Select(invoice1);

            select.Columns.Add(invoice1["CustomerId"]);
            select.Columns.Add(invoice1["Commission"]);

            select.Where = SqlDml.Equals(invoice1["Commission"], innerSelect);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
        public void Test026()
        {
            string nativeSql = @"SELECT 
                                  p.customer_id,
                                  p.amount
                                FROM
                                  payment p
                                WHERE
                                  p.amount = (SELECT MAX(amount) AS LowestPayment FROM payment)";

            SqlTableRef payment1 = SqlDml.TableRef(schema.Tables["payment"], "p1");
            SqlTableRef payment2 = SqlDml.TableRef(schema.Tables["payment"], "p2");

            SqlSelect innerSelect = SqlDml.Select(payment2);

            innerSelect.Columns.Add(SqlDml.Max(payment2["amount"]));

            SqlSelect select = SqlDml.Select(payment1);

            select.Columns.Add(payment1["customer_id"]);
            select.Columns.Add(payment1["amount"]);

            select.Where = SqlDml.Equals(payment1["amount"], innerSelect);

            Assert.IsTrue(CompareExecuteDataReader(nativeSql, select));
        }
        private void JoinViaIn(SqlStatement statement, SqlSelect select)
        {
            var table = GetStatementTable(statement);

            var where      = GetStatementWhere(statement);
            JoinedTableRef = table;
            var indexMapping = PrimaryIndexes[0];
            var columns      = new List <ColumnInfo>();

            foreach (var columnInfo in indexMapping.PrimaryIndex.KeyColumns.Keys)
            {
                var s = (SqlSelect)select.Clone();
                foreach (var column in columns)
                {
                    var ex = SqlDml.Equals(s.From.Columns[column.Name], table.Columns[column.Name]);
                    s.Where = s.Where.IsNullReference() ? ex : SqlDml.And(s.Where, ex);
                }
                var existingColumns = s.Columns.ToChainedBuffer();
                s.Columns.Clear();
                var columnToAdd = existingColumns.First(c => c.Name.Equals(columnInfo.Name, StringComparison.Ordinal));
                s.Columns.Add(columnToAdd);
                var @in = SqlDml.In(SqlDml.TableColumn(table, columnInfo.Name), s);
                where = where.IsNullReference() ? @in : SqlDml.And(where, @in);
                columns.Add(columnInfo);
            }

            SetStatementWhere(statement, where);
        }
        public static SqlExpression EnumHasFlag(SqlExpression _this,
                                                [Type(typeof(Enum))] SqlExpression value)
        {
            var right = GetSqlLiterExpression(value);
            var a     = right is SqlLiteral <bool>;

            return(SqlDml.Equals(SqlDml.BitAnd(GetSqlLiterExpression(_this), right), right));
        }
示例#8
0
        public void DeleteTest02()
        {
            var tableRef = SqlDml.TableRef(Catalog.DefaultSchema.Tables["Department"]);
            var update   = SqlDml.Delete(tableRef);

            update.Where = SqlDml.Equals(tableRef.Columns["Name"], SqlDml.Literal("Human Resources Department"));
            Console.WriteLine(Driver.Compile(update).GetCommandText());
            using (var command = Connection.CreateCommand(update)) {
                command.ExecuteNonQuery();
            }
        }
示例#9
0
        public void UpdateTest04()
        {
            var tableRef = SqlDml.TableRef(Catalog.DefaultSchema.Tables["Department"]);
            var update   = SqlDml.Update(tableRef);

            update.Values.Add(tableRef.Columns["ModifiedDate"], SqlDml.Literal(DateTime.Now.Date));
            update.Where = SqlDml.Equals(tableRef.Columns["Name"], SqlDml.Literal("Human Resources Department"));
            update.Limit = SqlDml.Native("100");
            Console.WriteLine(Driver.Compile(update).GetCommandText());
            using (var command = Connection.CreateCommand(update)) {
                command.ExecuteNonQuery();
            }
        }
        private SqlExpression TryTranslateEqualitySpecialCases(SqlExpression left, SqlExpression right)
        {
            if (right.NodeType == SqlNodeType.Null || emptyStringIsNull && IsEmptyStringLiteral(right))
            {
                return(SqlDml.IsNull(left));
            }

            object id = null;

            if (right.NodeType == SqlNodeType.Placeholder)
            {
                id = ((SqlPlaceholder)right).Id;
            }
            else if (right.NodeType == SqlNodeType.Cast && ((SqlCast)(right)).Operand.NodeType == SqlNodeType.Placeholder)
            {
                id = ((SqlPlaceholder)((SqlCast)(right)).Operand).Id;
            }
            if (id != null)
            {
                return(SqlDml.Variant(id, SqlDml.Equals(left, right), SqlDml.IsNull(left)));
            }

            return(null);
        }
        private SqlExpression TryTranslateCompareExpression(BinaryExpression expression)
        {
            bool isGoodExpression =
                expression.Left.NodeType == ExpressionType.Call && expression.Right.NodeType == ExpressionType.Constant ||
                expression.Right.NodeType == ExpressionType.Call && expression.Left.NodeType == ExpressionType.Constant;

            if (!isGoodExpression)
            {
                return(null);
            }

            MethodCallExpression callExpression;
            ConstantExpression   constantExpression;
            bool swapped;

            if (expression.Left.NodeType == ExpressionType.Call)
            {
                callExpression     = (MethodCallExpression)expression.Left;
                constantExpression = (ConstantExpression)expression.Right;
                swapped            = false;
            }
            else
            {
                callExpression     = (MethodCallExpression)expression.Right;
                constantExpression = (ConstantExpression)expression.Left;
                swapped            = true;
            }

            var method     = (MethodInfo)callExpression.Method.GetInterfaceMember() ?? callExpression.Method;
            var methodType = method.DeclaringType;

            // There no methods in IComparable except CompareTo so checking only DeclatingType.
            bool isCompareTo = methodType == typeof(IComparable) ||
                               methodType.IsGenericType && methodType.GetGenericTypeDefinition() == typeof(IComparable <>);

            bool isVbStringCompare = method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" &&
                                     method.Name == "CompareString" &&
                                     method.GetParameters().Length == 3 &&
                                     method.IsStatic;

            bool isCompare = method.Name == "Compare" && method.GetParameters().Length == 2 && method.IsStatic;

            if (!isCompareTo && !isCompare && !isVbStringCompare)
            {
                return(null);
            }

            if (constantExpression.Value == null)
            {
                return(null);
            }

            if (!(constantExpression.Value is int))
            {
                return(null);
            }

            var constant = (int)constantExpression.Value;

            SqlExpression leftComparand  = null;
            SqlExpression rightComparand = null;

            if (isCompareTo)
            {
                leftComparand  = Visit(callExpression.Object);
                rightComparand = Visit(callExpression.Arguments[0]);
            }

            if (isCompare || isVbStringCompare)
            {
                leftComparand  = Visit(callExpression.Arguments[0]);
                rightComparand = Visit(callExpression.Arguments[1]);
            }

            if (swapped)
            {
                var tmp = leftComparand;
                leftComparand  = rightComparand;
                rightComparand = tmp;
            }

            if (constant > 0)
            {
                switch (expression.NodeType)
                {
                case ExpressionType.Equal:
                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:
                    return(SqlDml.GreaterThan(leftComparand, rightComparand));

                case ExpressionType.NotEqual:
                case ExpressionType.LessThanOrEqual:
                case ExpressionType.LessThan:
                    return(SqlDml.LessThanOrEquals(leftComparand, rightComparand));

                default:
                    return(null);
                }
            }

            if (constant < 0)
            {
                switch (expression.NodeType)
                {
                case ExpressionType.NotEqual:
                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:
                    return(SqlDml.GreaterThanOrEquals(leftComparand, rightComparand));

                case ExpressionType.Equal:
                case ExpressionType.LessThanOrEqual:
                case ExpressionType.LessThan:
                    return(SqlDml.LessThan(leftComparand, rightComparand));

                default:
                    return(null);
                }
            }

            switch (expression.NodeType)
            {
            case ExpressionType.GreaterThan:
                return(SqlDml.GreaterThan(leftComparand, rightComparand));

            case ExpressionType.GreaterThanOrEqual:
                return(SqlDml.GreaterThanOrEquals(leftComparand, rightComparand));

            case ExpressionType.Equal:
                return(SqlDml.Equals(leftComparand, rightComparand));

            case ExpressionType.NotEqual:
                return(SqlDml.NotEquals(leftComparand, rightComparand));

            case ExpressionType.LessThanOrEqual:
                return(SqlDml.LessThanOrEquals(leftComparand, rightComparand));

            case ExpressionType.LessThan:
                return(SqlDml.LessThan(leftComparand, rightComparand));

            default:
                return(null);
            }
        }
        protected override SqlExpression VisitBinary(BinaryExpression expression)
        {
            // handle x.CompareTo(y) > 0 and similar comparisons
            SqlExpression result = TryTranslateCompareExpression(expression);

            if (!result.IsNullReference())
            {
                return(result);
            }

            SqlExpression left;
            SqlExpression right;

            bool isEqualityCheck =
                expression.NodeType == ExpressionType.Equal ||
                expression.NodeType == ExpressionType.NotEqual;

            bool isBooleanFixRequired = fixBooleanExpressions &&
                                        (isEqualityCheck || expression.NodeType == ExpressionType.Coalesce) &&
                                        (IsBooleanExpression(expression.Left) || IsBooleanExpression(expression.Right));

            if (IsCharToIntConvert(expression.Left) && IsCharToIntConvert(expression.Right))
            {
                // chars are compared as integers, but we store them as strings and should compare them like strings.
                left  = Visit(GetOperand(expression.Left), isEqualityCheck);
                right = Visit(GetOperand(expression.Right), isEqualityCheck);
            }
            else if (IsCharToIntConvert(expression.Left) && IsIntConstant(expression.Right))
            {
                // another case of char comparison
                left  = Visit(GetOperand(expression.Left), isEqualityCheck);
                right = ConvertIntConstantToSingleCharString(expression.Right);
            }
            else if (IsIntConstant(expression.Left) && IsCharToIntConvert(expression.Right))
            {
                // another case of char comparison
                left  = ConvertIntConstantToSingleCharString(expression.Left);
                right = Visit(GetOperand(expression.Right), isEqualityCheck);
            }
            else
            {
                // regular case
                left  = Visit(expression.Left, isEqualityCheck);
                right = Visit(expression.Right, isEqualityCheck);
            }
            if (isBooleanFixRequired)
            {
                // boolean expressions should be compared as integers.
                // additional check is required because some type information might be lost.
                // we assume they already have correct format in that case.
                if (IsBooleanExpression(expression.Left))
                {
                    left = booleanExpressionConverter.BooleanToInt(left);
                }
                if (IsBooleanExpression(expression.Right))
                {
                    right = booleanExpressionConverter.BooleanToInt(right);
                }
            }

            //handle SQLite DateTime comparsion
            if (dateTimeEmulation &&
                left.NodeType != SqlNodeType.Null &&
                right.NodeType != SqlNodeType.Null &&
                IsComparisonExpression(expression) &&
                (IsDateTimeExpression(expression.Left) || IsDateTimeExpression(expression.Right)))
            {
                left  = SqlDml.Cast(left, SqlType.DateTime);
                right = SqlDml.Cast(right, SqlType.DateTime);
            }

            //handle SQLite DateTimeOffset comparsion
            if (dateTimeOffsetEmulation &&
                left.NodeType != SqlNodeType.Null &&
                right.NodeType != SqlNodeType.Null &&
                IsComparisonExpression(expression) &&
                (IsDateTimeOffsetExpression(expression.Left) || IsDateTimeOffsetExpression(expression.Right)))
            {
                left  = SqlDml.Cast(left, SqlType.DateTimeOffset);
                right = SqlDml.Cast(right, SqlType.DateTimeOffset);
            }

            // handle special cases
            result = TryTranslateBinaryExpressionSpecialCases(expression, left, right);
            if (!result.IsNullReference())
            {
                return(result);
            }

            // handle overloaded operators
            if (expression.Method != null)
            {
                return(CompileMember(expression.Method, null, left, right));
            }

            //handle wrapped enums
            SqlContainer container = left as SqlContainer;

            if (container != null)
            {
                left = TryUnwrapEnum(container);
            }
            container = right as SqlContainer;
            if (container != null)
            {
                right = TryUnwrapEnum(container);
            }

            switch (expression.NodeType)
            {
            case ExpressionType.Add:
            case ExpressionType.AddChecked:
                return(SqlDml.Add(left, right));

            case ExpressionType.And:
                return(IsBooleanExpression(expression.Left)
          ? SqlDml.And(left, right)
          : SqlDml.BitAnd(left, right));

            case ExpressionType.AndAlso:
                return(SqlDml.And(left, right));

            case ExpressionType.Coalesce:
                SqlExpression coalesce = SqlDml.Coalesce(left, right);
                if (isBooleanFixRequired)
                {
                    coalesce = booleanExpressionConverter.IntToBoolean(coalesce);
                }
                return(coalesce);

            case ExpressionType.Divide:
                return(SqlDml.Divide(left, right));

            case ExpressionType.Equal:
                return(SqlDml.Equals(left, right));

            case ExpressionType.ExclusiveOr:
                return(SqlDml.BitXor(left, right));

            case ExpressionType.GreaterThan:
                return(SqlDml.GreaterThan(left, right));

            case ExpressionType.GreaterThanOrEqual:
                return(SqlDml.GreaterThanOrEquals(left, right));

            case ExpressionType.LessThan:
                return(SqlDml.LessThan(left, right));

            case ExpressionType.LessThanOrEqual:
                return(SqlDml.LessThanOrEquals(left, right));

            case ExpressionType.Modulo:
                return(SqlDml.Modulo(left, right));

            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
                return(SqlDml.Multiply(left, right));

            case ExpressionType.NotEqual:
                return(SqlDml.NotEquals(left, right));

            case ExpressionType.Or:
                return(IsBooleanExpression(expression.Left)
          ? SqlDml.Or(left, right)
          : SqlDml.BitOr(left, right));

            case ExpressionType.OrElse:
                return(SqlDml.Or(left, right));

            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
                return(SqlDml.Subtract(left, right));

            default:
                throw new ArgumentOutOfRangeException("expression");
            }
        }
示例#13
0
 public static SqlExpression StringOperatorEquality(SqlExpression left, SqlExpression right)
 {
     return(SqlDml.Equals(left, right));
 }