private void BuildMergeSourceEnumerable(SqlMergeStatement merge) { var rows = merge.Source.SourceEnumerable !.Rows !; if (rows.Count > 0) { StringBuilder.Append("("); if (MergeSupportsSourceDirectValues) { BuildValues(merge.Source.SourceEnumerable, rows); } else { BuildValuesAsSelectsUnion(merge.Source.SourceFields, merge.Source.SourceEnumerable, rows); } StringBuilder.Append(")"); } else if (MergeEmptySourceSupported) { BuildMergeEmptySource(merge); } else { throw new LinqToDBException($"{Name} doesn't support merge with empty source"); } BuildMergeAsSourceClause(merge.Source); }
private void BuildMergeSourceEnumerable(SqlMergeStatement merge) { merge = ConvertElement(merge); var rows = merge.Source.SourceEnumerable !.BuildRows(OptimizationContext.Context); if (rows.Count > 0) { StringBuilder.Append('('); if (IsValuesSyntaxSupported) { BuildValues(merge.Source.SourceEnumerable, rows); } else { BuildValuesAsSelectsUnion(merge.Source.SourceFields, merge.Source.SourceEnumerable, rows); } StringBuilder.Append(')'); } else if (IsEmptyValuesSourceSupported) { BuildMergeEmptySource(merge); } else { throw new LinqToDBException($"{Name} doesn't support merge with empty source"); } BuildMergeAsSourceClause(merge.Source); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // MergeInto<TTarget, TSource>(IQueryable<TSource> source, ITable<TTarget> target, string hint) var sourceContext = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], new SelectQuery())); var target = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[1]) { AssociationsAsSubQueries = true }); if (target is not TableBuilder.TableContext tableContext || !tableContext.SelectQuery.IsSimple) { throw new NotImplementedException("Currently, only CTEs are supported as the target of a merge. You can fix by calling .AsCte() on the parameter before passing into .MergeInto()."); } var targetTable = tableContext.SqlTable; var merge = new SqlMergeStatement(targetTable); if (methodCall.Arguments.Count == 3) { merge.Hint = (string?)methodCall.Arguments[2].EvaluateExpression(); } target.SetAlias(merge.Target.Alias !); target.Statement = merge; var source = new TableLikeQueryContext(sourceContext); return(new MergeContext(merge, target, source)); }
protected virtual void BuildMergeOn(SqlMergeStatement mergeStatement) { StringBuilder.Append("ON ("); BuildSearchCondition(Precedence.Unknown, mergeStatement.On, wrapCondition: true); StringBuilder.AppendLine(")"); }
protected override void BuildMergeTerminator(SqlMergeStatement merge) { // for identity column insert - disable explicit insert support if (merge.HasIdentityInsert) { BuildIdentityInsert(merge.Target, false); } }
protected override void BuildMergeStatement(SqlMergeStatement merge) { if (!DB2iSeriesSqlProviderFlags.SupportsMergeStatement) { throw new LinqToDBException($"{Provider.Name} provider doesn't support SQL MERGE statement"); } base.BuildMergeStatement(merge); }
protected override void BuildMergeStatement(SqlMergeStatement merge) { // for identity column insert - enable explicit insert support if (merge.HasIdentityInsert) { BuildIdentityInsert(merge.Target, true); } base.BuildMergeStatement(merge); }
protected override void BuildMergeTerminator(SqlMergeStatement merge) { // merge command must be terminated with semicolon StringBuilder.AppendLine(";"); // for identity column insert - disable explicit insert support if (merge.HasIdentityInsert) { BuildIdentityInsert(merge.Target, false); } }
protected virtual void BuildMergeStatement(SqlMergeStatement merge) { BuildMergeInto(merge); BuildMergeSource(merge); BuildMergeOn(merge); foreach (var operation in merge.Operations) { BuildMergeOperation(operation); } BuildMergeTerminator(merge); }
protected override void BuildMergeInto(SqlMergeStatement merge) { StringBuilder.Append("MERGE "); if (merge.Hint != null) { StringBuilder .Append("{+ ") .Append(merge.Hint) .Append(" } "); } StringBuilder.Append("INTO "); BuildTableName(merge.Target, true, true); StringBuilder.AppendLine(); }
private void BuildMergeSourceEnumerable(SqlMergeStatement merge) { if (merge.Source.SourceEnumerable !.Rows.Count > 0) { StringBuilder.Append("("); if (MergeSupportsSourceDirectValues) { BuildValues(merge.Source); } else { BuildValuesAsSelectsUnion(merge.Source.SourceFields, merge.Source.SourceEnumerable); } StringBuilder.Append(")"); }
protected virtual void BuildMergeStatement(SqlMergeStatement merge) { BuildTag(merge); BuildWithClause(merge.With); BuildMergeInto(merge); BuildMergeSource(merge); BuildMergeOn(merge); foreach (var operation in merge.Operations) { BuildMergeOperation(operation); } BuildOutputSubclause(merge.Output); BuildMergeTerminator(merge); }
private void BuildMergeEmptySource(SqlMergeStatement merge) { StringBuilder .AppendLine(OpenParens) .Append("\tSELECT ") ; for (var i = 0; i < merge.Source.SourceFields.Count; i++) { var field = merge.Source.SourceFields[i]; if (i > 0) { StringBuilder.Append(InlineComma); } if (IsSqlValuesTableValueTypeRequired(merge.Source.SourceEnumerable !, Array <ISqlExpression[]> .Empty, -1, i)) { BuildTypedExpression(new SqlDataType(field), new SqlValue(field.Type, null)); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { // Merge(ITable<TTarget> target, string hint) var target = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0], new SelectQuery()) { AssociationsAsSubQueries = true }); var targetTable = ((TableBuilder.TableContext)target).SqlTable; var merge = new SqlMergeStatement(targetTable) { Hint = (string?)methodCall.Arguments[1].EvaluateExpression() }; target.SetAlias(merge.Target.Alias !); target.Statement = merge; return(new MergeContext(merge, target)); }
// TODO: both 2008 and 2012 builders inherit from same base class which leads to duplicate builder logic // I think we should have single builder with versioning support as inheritance definitely suck for this case protected override void BuildMergeInto(SqlMergeStatement merge) { StringBuilder .Append("MERGE INTO "); BuildTableName(merge.Target, true, false); StringBuilder.Append(' '); if (merge.Hint != null) { StringBuilder .Append("WITH(") .Append(merge.Hint) .Append(") "); } BuildTableName(merge.Target, false, true); StringBuilder.AppendLine(); }
protected override void BuildMergeInto(SqlMergeStatement merge) { StringBuilder.Append("MERGE"); StartStatementQueryExtensions(merge.SelectQuery); StringBuilder.Append(' '); if (merge.Hint != null) { if (HintBuilder !.Length > 0) { HintBuilder.Append(' '); } HintBuilder.Append(merge.Hint); } StringBuilder.Append("INTO "); BuildTableName(merge.Target, true, true); StringBuilder.AppendLine(); }
public MergeSourceQueryContext(SqlMergeStatement merge, IBuildContext sourceContext) : base(sourceContext, new SelectQuery { ParentSelect = sourceContext.SelectQuery }, true) { _merge = merge; _merge.Source = sourceContext is EnumerableContext enumerableSource ? new SqlMergeSourceTable() { SourceEnumerable = enumerableSource.Table } : new SqlMergeSourceTable() { SourceQuery = sourceContext.SelectQuery }; if (SubQuery is SelectContext select) { select.AllowAddDefault = false; } }
public MergeContext(SqlMergeStatement merge, IBuildContext target) : base(null, target, null) { Statement = merge; }
public override void Visit(SqlMergeStatement codeObject) { }
/// <summary> /// Allows to add text after generated merge command. E.g. to specify command terminator if provider requires it. /// </summary> protected virtual void BuildMergeTerminator(SqlMergeStatement merge) { }
public MergeContext(SqlMergeStatement merge, IBuildContext target, IBuildContext source) : base(null, new[] { target, source }, null) { Statement = merge; }
protected override void BuildMergeStatement(SqlMergeStatement merge) { throw new LinqToDBException($"{Name} provider doesn't support SQL MERGE statement"); }
public MergeContext(SqlMergeStatement merge, IBuildContext target, TableLikeQueryContext source) : base(null, new[] { target, source }, null) { Statement = merge; merge.Source = source.Source; }