예제 #1
0
        public bool Equals(ISqlExpression?other)
        {
            if (this == other)
            {
                return(true);
            }

            if (!(other is SqlGroupingSet otherSet))
            {
                return(false);
            }

            if (Items.Count != otherSet.Items.Count)
            {
                return(false);
            }

            for (int i = 0; i < Items.Count; i++)
            {
                if (!Items[i].Equals(otherSet.Items[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #2
0
        // These are both nullable refs, but by construction either _column or _row is set.

        public SqlSetExpression(ISqlExpression column, ISqlExpression?expression)
        {
            Column     = column;
            Expression = expression;

            ValidateColumnExpression(column, expression);
        }
예제 #3
0
 public Like(ISqlExpression exp1, bool isNot, ISqlExpression exp2, ISqlExpression?escape, string?functionName = null)
     : base(exp1, isNot, SqlQuery.Precedence.Comparison)
 {
     Expr2        = exp2;
     Escape       = escape;
     FunctionName = functionName;
 }
예제 #4
0
 public Like(ISqlExpression exp1, bool isNot, ISqlExpression exp2, ISqlExpression?escape, bool isSqlLike)
     : base(exp1, isNot, SqlQuery.Precedence.Comparison)
 {
     Expr2     = exp2;
     Escape    = escape;
     IsSqlLike = isSqlLike;
 }
예제 #5
0
        ISqlExpression?ISqlExpressionWalkable.Walk(WalkOptions options, Func <ISqlExpression, ISqlExpression> func)
        {
            if (!options.SkipColumnDeclaration)
            {
                for (var i = 0; i < Columns.Count; i++)
                {
                    var col  = Columns[i];
                    var expr = col.Walk(options, func);

                    if (expr is SqlColumn column)
                    {
                        Columns[i] = column;
                    }
                    else
                    {
                        Columns[i] = new SqlColumn(col.Parent, expr, col.Alias);
                    }
                }
            }

            TakeValue = TakeValue?.Walk(options, func);
            SkipValue = SkipValue?.Walk(options, func);

            return(null);
        }
예제 #6
0
            protected override void Walk(WalkOptions options, Func <ISqlExpression, ISqlExpression> func)
            {
                base.Walk(options, func);
                Expr2 = Expr2.Walk(options, func) !;

                Escape = Escape?.Walk(options, func);
            }
예제 #7
0
        private void RefineDbParameter(ISqlExpression column, ISqlExpression?value)
        {
            if (value is SqlParameter p && column is SqlField field)
            {
                if (field.ColumnDescriptor != null && p.Type.SystemType != typeof(object))
                {
                    if (field.ColumnDescriptor.DataType != DataType.Undefined && p.Type.DataType == DataType.Undefined)
                    {
                        p.Type = p.Type.WithDataType(field.ColumnDescriptor.DataType);
                    }

                    if (field.ColumnDescriptor.DbType != null && p.Type.DbType == null)
                    {
                        p.Type = p.Type.WithDbType(field.ColumnDescriptor.DbType);
                    }
                    if (field.ColumnDescriptor.Length != null && p.Type.Length == null)
                    {
                        p.Type = p.Type.WithLength(field.ColumnDescriptor.Length);
                    }
                    if (field.ColumnDescriptor.Precision != null && p.Type.Precision == null)
                    {
                        p.Type = p.Type.WithPrecision(field.ColumnDescriptor.Precision);
                    }
                    if (field.ColumnDescriptor.Scale != null && p.Type.Scale == null)
                    {
                        p.Type = p.Type.WithScale(field.ColumnDescriptor.Scale);
                    }
                }
            }
        }
예제 #8
0
 internal SqlSelectClause(bool isDistinct, ISqlExpression?takeValue, TakeHints?takeHints, ISqlExpression?skipValue, IEnumerable <SqlColumn> columns)
     : base(null)
 {
     IsDistinct = isDistinct;
     TakeValue  = takeValue;
     TakeHints  = takeHints;
     SkipValue  = skipValue;
     Columns.AddRange(columns);
 }
예제 #9
0
            public override ISqlExpression GetSubQuery(IBuildContext?context)
            {
                if (_subQuerySql == null)
                {
                    var cond = new SqlCondition(
                        _methodCall.Method.Name.StartsWith("All"),
                        new SqlPredicate.FuncLike(SqlFunction.CreateExists(SelectQuery)));

                    _subQuerySql = new SqlSearchCondition(cond);
                }

                return(_subQuerySql);
            }
예제 #10
0
        public bool Equals(ISqlExpression?other, Func <ISqlExpression, ISqlExpression, bool> comparer)
        {
            if (this == other)
            {
                return(true);
            }

            return
                (other is SqlBinaryExpression expr &&
                 Operation == expr.Operation &&
                 SystemType == expr.SystemType &&
                 Expr1.Equals(expr.Expr1, comparer) &&
                 Expr2.Equals(expr.Expr2, comparer) &&
                 comparer(this, other));
        }
예제 #11
0
            Expression BuildExpression(int fieldIndex, ISqlExpression?sqlExpression)
            {
                Expression expr;

                if (SequenceHelper.UnwrapSubqueryContext(Sequence) is DefaultIfEmptyBuilder.DefaultIfEmptyContext defaultIfEmpty)
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                    if (defaultIfEmpty.DefaultValue != null && expr is ConvertFromDataReaderExpression convert)
                    {
                        var generator = new ExpressionGenerator();
                        expr = convert.MakeNullable();
                        if (expr.Type.IsNullable())
                        {
                            var exprVar      = generator.AssignToVariable(expr, "nullable");
                            var defaultValue = defaultIfEmpty.DefaultValue;
                            if (defaultValue.Type != expr.Type)
                            {
                                var convertLambda = Builder.MappingSchema.GenerateSafeConvert(defaultValue.Type, expr.Type);
                                defaultValue = InternalExtensions.ApplyLambdaToExpression(convertLambda, defaultValue);
                            }

                            var resultVar = generator.AssignToVariable(defaultValue, "result");

                            generator.AddExpression(Expression.IfThen(
                                                        Expression.NotEqual(exprVar, ExpressionInstances.UntypedNull),
                                                        Expression.Assign(resultVar, Expression.Convert(exprVar, resultVar.Type))));

                            generator.AddExpression(resultVar);

                            expr = generator.Build();
                        }
                    }
                }
                else
                if (_methodName == "Sum" || _returnType.IsNullableType())
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                }
                else
                {
                    expr = Expression.Block(
                        Expression.Call(null, MemberHelper.MethodOf(() => CheckNullValue(false, null !)), Expression.Call(ExpressionBuilder.DataReaderParam, Methods.ADONet.IsDBNull, ExpressionInstances.Constant0), Expression.Constant(_methodName)),
                        Builder.BuildSql(_returnType, fieldIndex, sqlExpression));
                }

                return(expr);
            }
예제 #12
0
            Expression BuildExpression(int fieldIndex, ISqlExpression?sqlExpression)
            {
                Expression expr;

                if (_returnType.IsClass || _methodName == "Sum" || _returnType.IsNullable())
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                }
                else
                {
                    expr = Expression.Block(
                        Expression.Call(null, MemberHelper.MethodOf(() => CheckNullValue(null !, null !)), ExpressionBuilder.DataReaderParam, Expression.Constant(_methodName)),
                        Builder.BuildSql(_returnType, fieldIndex, sqlExpression));
                }

                return(expr);
            }
예제 #13
0
            public override SqlInfo[] ConvertToIndex(Expression?expression, int level, ConvertFlags flags)
            {
                switch (flags)
                {
                case ConvertFlags.Field:
                {
                    var result = _index ??= new[]
                    {
                        new SqlInfo
                        {
                            Query = Parent !.SelectQuery,
                            Index = Parent.SelectQuery.Select.Add(Sql !),
                            Sql   = Sql !,
                        }
                    };

                    return(result);
                }
                }
예제 #14
0
        private void ValidateColumnExpression(ISqlExpression column, ISqlExpression?expression)
        {
            if (column is SqlRow row)
            {
                // The length-checks _should_ never failed thanks to C# type-checking.
                // We do them in case someone attempts to build invalid expressions with unsafe casts or similar.

                if (expression is SelectQuery subquery)
                {
                    var columns = subquery.Select.Columns;
                    if (columns.Count != row.Values.Length)
                    {
                        throw new LinqToDBException("Arity of row expression and subquery do not match.");
                    }
                    for (int i = 0; i < row.Values.Length; i++)
                    {
                        RefineDbParameter(row.Values[i], columns[i].Expression);
                    }
                }
                else if (expression is SqlRow sqlRow)
                {
                    var values = sqlRow.Values;
                    if (values.Length != row.Values.Length)
                    {
                        throw new LinqToDBException("Arity of row expressions do not match.");
                    }
                    for (int i = 0; i < values.Length; i++)
                    {
                        RefineDbParameter(values[i], values[i]);
                    }
                }
                else if (expression != null)
                {
                    throw new ArgumentException("An array of expressions can only be SET to a subquery or row expression", nameof(expression));
                }
            }
            else
            {
                RefineDbParameter(column, expression);
            }
        }
예제 #15
0
            Expression BuildExpression(int fieldIndex, ISqlExpression?sqlExpression)
            {
                Expression expr;

                if (Sequence is DefaultIfEmptyBuilder.DefaultIfEmptyContext defaultIfEmpty)
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                    if (defaultIfEmpty.DefaultValue != null && expr is ConvertFromDataReaderExpression convert)
                    {
                        var generator = new ExpressionGenerator();
                        expr = convert.MakeNullable();
                        if (expr.Type.IsNullable())
                        {
                            var exprVar   = generator.AssignToVariable(expr, "nullable");
                            var resultVar = generator.AssignToVariable(defaultIfEmpty.DefaultValue, "result");

                            generator.AddExpression(Expression.IfThen(
                                                        Expression.NotEqual(exprVar, Expression.Constant(null)),
                                                        Expression.Assign(resultVar, Expression.Convert(exprVar, resultVar.Type))));

                            generator.AddExpression(resultVar);

                            expr = generator.Build();
                        }
                    }
                }
                else
                if (_returnType.IsClass || _methodName == "Sum" || _returnType.IsNullable())
                {
                    expr = Builder.BuildSql(_returnType, fieldIndex, sqlExpression);
                }
                else
                {
                    expr = Expression.Block(
                        Expression.Call(null, MemberHelper.MethodOf(() => CheckNullValue(false, null !)), Expression.Call(ExpressionBuilder.DataReaderParam, Methods.ADONet.IsDBNull, Expression.Constant(0)), Expression.Constant(_methodName)),
                        Builder.BuildSql(_returnType, fieldIndex, sqlExpression));
                }

                return(expr);
            }
예제 #16
0
            SqlField RegisterCteField(ISqlExpression?baseExpression, ISqlExpression expression, int index, string?alias)
            {
                if (expression == null)
                {
                    throw new ArgumentNullException(nameof(expression));
                }

                var cteField = _cte.RegisterFieldMapping(index, () =>
                {
                    var f = QueryHelper.GetUnderlyingField(baseExpression ?? expression);

                    var newField = f == null
                                                ? new SqlField(expression.SystemType !, alias, expression.CanBeNull)
                                                : new SqlField(f);

                    if (alias != null)
                    {
                        newField.Name = alias;
                    }

                    newField.PhysicalName = newField.Name;
                    return(newField);
                });
예제 #17
0
        public SqlSetExpression(ISqlExpression column, ISqlExpression?expression)
        {
            Column     = column;
            Expression = expression;

            if (expression is SqlParameter p)
            {
                if (column is SqlField field)
                {
                    if (field.ColumnDescriptor != null && p.Type.SystemType != typeof(object))
                    {
                        if (field.ColumnDescriptor.DataType != DataType.Undefined && p.Type.DataType == DataType.Undefined)
                        {
                            p.Type = p.Type.WithDataType(field.ColumnDescriptor.DataType);
                        }

                        if (field.ColumnDescriptor.DbType != null && p.Type.DbType == null)
                        {
                            p.Type = p.Type.WithDbType(field.ColumnDescriptor.DbType);
                        }
                        if (field.ColumnDescriptor.Length != null && p.Type.Length == null)
                        {
                            p.Type = p.Type.WithLength(field.ColumnDescriptor.Length);
                        }
                        if (field.ColumnDescriptor.Precision != null && p.Type.Precision == null)
                        {
                            p.Type = p.Type.WithPrecision(field.ColumnDescriptor.Precision);
                        }
                        if (field.ColumnDescriptor.Scale != null && p.Type.Scale == null)
                        {
                            p.Type = p.Type.WithScale(field.ColumnDescriptor.Scale);
                        }
                    }
                }
            }
        }
예제 #18
0
            public override ISqlExpression GetSubQuery(IBuildContext?context)
            {
                if (_subQuerySql == null)
                {
                    var args      = _methodCall.Method.GetGenericArguments();
                    var param     = Expression.Parameter(args[0], "param");
                    var expr      = _methodCall.Arguments[1];
                    var condition = Expression.Lambda(ExpressionBuilder.Equal(Builder.MappingSchema, param, expr), param);

                    IBuildContext ctx = new ExpressionContext(Parent, Sequence, condition);

                    ctx = Builder.GetContext(ctx, expr) ?? ctx;

                    Builder.ReplaceParent(ctx, this);

                    SqlCondition cond;

                    if ((Sequence.SelectQuery != SelectQuery || _buildInStatement) &&
                        (ctx.IsExpression(expr, 0, RequestFor.Field).Result ||
                         ctx.IsExpression(expr, 0, RequestFor.Expression).Result))
                    {
                        Sequence.ConvertToIndex(null, 0, ConvertFlags.All);
                        var ex = Builder.ConvertToSql(ctx, _methodCall.Arguments[1]);
                        cond = new SqlCondition(false, new SqlPredicate.InSubQuery(ex, false, SelectQuery));
                    }
                    else
                    {
                        var sequence = Builder.BuildWhere(Parent, Sequence, condition, true);
                        cond = new SqlCondition(false, new SqlPredicate.FuncLike(SqlFunction.CreateExists(sequence.SelectQuery)));
                    }

                    _subQuerySql = new SqlSearchCondition(cond);
                }

                return(_subQuerySql);
            }
예제 #19
0
 public override ISqlExpression EscapeLikeCharacters(ISqlExpression expression, ref ISqlExpression?escape)
 {
     throw new LinqException("Access does not support `Replace` function which is required for such query.");
 }
예제 #20
0
 public bool Equals(ISqlExpression?other)
 {
     return(other != null && other.GetType() == GetType());
 }
예제 #21
0
 public SqlSelectClause Take(ISqlExpression?value, TakeHints?hints)
 {
     TakeHints = hints;
     TakeValue = value;
     return(this);
 }
예제 #22
0
 ISqlExpression?ISqlExpressionWalkable.Walk(WalkOptions options, Func <ISqlExpression, ISqlExpression> func)
 {
     Column     = Column.Walk(options, func) !;
     Expression = Expression?.Walk(options, func);
     return(null);
 }
예제 #23
0
 bool IEquatable <ISqlExpression> .Equals(ISqlExpression?other)
 {
     return(this == other);
 }
예제 #24
0
 public Expression BuildSql(Type type, int idx, ISqlExpression?sourceExpression)
 {
     return(BuildSql(type, idx, QueryHelper.GetValueConverter(sourceExpression)));
 }
예제 #25
0
 ISqlExpression?ISqlExpressionWalkable.Walk <TContext>(WalkOptions options, TContext context, Func <TContext, ISqlExpression, ISqlExpression> func)
 {
     Column     = Column.Walk(options, context, func) !;
     Expression = Expression?.Walk(options, context, func);
     return(null);
 }
예제 #26
0
 public bool GetIsSkipSupportedFlag(ISqlExpression?takeExpression, ISqlExpression?skipExpression)
 {
     return(IsSkipSupported || IsSkipSupportedIfTake && takeExpression != null);
 }
예제 #27
0
 bool IEquatable <ISqlExpression> .Equals(ISqlExpression?other)
 {
     return(Equals(other, DefaultComparer));
 }
예제 #28
0
 bool IEquatable <ISqlExpression> .Equals(ISqlExpression?other)
 {
     throw new NotImplementedException();
 }