protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var table = SequenceHelper.GetTableContext(sequence) ?? throw new LinqToDBException($"Cannot get table context from {sequence.GetType()}"); var value = methodCall.Arguments.Count == 1 && methodCall.Method.Name == nameof(TableExtensions.IsTemporary) ? true : methodCall.Arguments[1].EvaluateExpression(); switch (methodCall.Method.Name) { case nameof(LinqExtensions.TableName): table.SqlTable.PhysicalName = (string)value !; break; case nameof(LinqExtensions.ServerName): table.SqlTable.Server = (string?)value; break; case nameof(LinqExtensions.DatabaseName): table.SqlTable.Database = (string?)value; break; case nameof(LinqExtensions.SchemaName): table.SqlTable.Schema = (string?)value; break; case nameof(TableExtensions.TableOptions): table.SqlTable.TableOptions = (TableOptions)value !; break; case nameof(TableExtensions.IsTemporary): table.SqlTable.Set((bool)value !, TableOptions.IsTemporary); break; } return(sequence); }
public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags) { expression = SequenceHelper.CorrectExpression(expression, this, Context); var indexes = SubQuery .ConvertToIndex(expression, level, flags) .ToArray(); var result = indexes .Select(idx => new SqlInfo(idx.MemberChain, idx.Index < 0 ? idx.Sql : SubQuery.SelectQuery.Select.Columns[idx.Index], idx.Index)) .ToArray(); return(result); }
public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags) { expression = SequenceHelper.CorrectExpression(expression, this, SubQuery); return(SubQuery .ConvertToIndex(expression, level, flags) .Select(info => { var expr = (info.Sql is SqlColumn column) ? column.Expression : info.Sql; var field = RegisterSourceField(expr, expr, info.Index, info.MemberChain.LastOrDefault()); return new SqlInfo(info.MemberChain, field); }) .ToArray()); }
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); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var table = SequenceHelper.GetTableContext(sequence) ?? throw new LinqToDBException($"Cannot get table context from {sequence.GetType()}"); var value = (string)methodCall.Arguments[1].EvaluateExpression() !; table.SqlTable.SqlTableType = SqlTableType.Expression; table.SqlTable.TableArguments = Array <ISqlExpression> .Empty; switch (methodCall.Method.Name) { case "With": table.SqlTable.Name = $"{{0}} {{1}} WITH ({value})"; break; case "WithTableExpression": table.SqlTable.Name = value; break; } return(sequence); }
public override SqlInfo[] ConvertToSql(Expression?expression, int level, ConvertFlags flags) { var queryContext = GetQueryContext(); if (queryContext == null) { return(base.ConvertToSql(expression, level, flags)); } var baseInfos = base.ConvertToSql(null, 0, ConvertFlags.All); if (flags != ConvertFlags.All && _cte.Fields !.Length == 0 && queryContext.SelectQuery.Select.Columns.Count > 0) { // it means that queryContext context already has columns and we need all of them. For example for Distinct. ConvertToSql(null, 0, ConvertFlags.All); } expression = SequenceHelper.CorrectExpression(expression, this, queryContext); var infos = queryContext.ConvertToIndex(expression, level, flags); var result = infos .Select(info => { var baseInfo = baseInfos.FirstOrDefault(bi => bi.CompareMembers(info)); var alias = flags == ConvertFlags.Field ? GenerateAlias(expression) : null; if (alias == null) { alias = baseInfo?.MemberChain.LastOrDefault()?.Name ?? info.MemberChain.LastOrDefault()?.Name; } var field = RegisterCteField(baseInfo?.Sql, info.Sql, info.Index, alias); return(new SqlInfo(info.MemberChain, field)); }) .ToArray(); return(result); }
public override Expression BuildExpression(Expression?expression, int level, bool enforceServerSide) { expression = SequenceHelper.CorrectExpression(expression, this, Sequence); var expr = Sequence.BuildExpression(expression, level, enforceServerSide); if (!Disabled && expression == null) { var q = from col in SelectQuery.Select.Columns where !col.CanBeNull select SelectQuery.Select.Columns.IndexOf(col); var idx = q.DefaultIfEmpty(-1).First(); if (idx == -1) { idx = SelectQuery.Select.Add(new SqlValue((int?)1)); SelectQuery.Select.Columns[idx].RawAlias = "is_empty"; } var n = ConvertToParentIndex(idx, this); Expression e = Expression.Call( ExpressionBuilder.DataReaderParam, ReflectionHelper.DataReader.IsDBNull, ExpressionInstances.Int32Array(n)); var defaultValue = DefaultValue ?? new DefaultValueExpression(Builder.MappingSchema, expr.Type); if (expr.NodeType == ExpressionType.Parameter) { var par = (ParameterExpression)expr; var pidx = Builder.BlockVariables.IndexOf(par); if (pidx >= 0) { var ex = Builder.BlockExpressions[pidx]; if (ex.NodeType == ExpressionType.Assign) { var bex = (BinaryExpression)ex; if (bex.Left == expr) { if (bex.Right.NodeType != ExpressionType.Conditional) { Builder.BlockExpressions[pidx] = Expression.Assign( bex.Left, Expression.Condition(e, defaultValue, bex.Right)); } } } } } expr = Expression.Condition(e, defaultValue, expr); } return(expr); }
public override IBuildContext?GetContext(Expression?expression, int level, BuildInfo buildInfo) { expression = SequenceHelper.CorrectExpression(expression, this, Sequence); return(Sequence.GetContext(expression, level, buildInfo)); }
public override IsExpressionResult IsExpression(Expression?expression, int level, RequestFor requestFlag) { expression = SequenceHelper.CorrectExpression(expression, this, Sequence); return(Sequence.IsExpression(expression, level, requestFlag)); }
public override SqlInfo[] ConvertToIndex(Expression?expression, int level, ConvertFlags flags) { expression = SequenceHelper.CorrectExpression(expression, this, Sequence); return(Sequence.ConvertToIndex(expression, level, flags)); }