private IExprMergeMatched?BuildWhenMatched(IReadOnlyList <ExprColumnName> keys, IReadOnlyList <ExprColumnName> allColumns) { if (!this._whenMatched.HasValue) { return(null); } var when = this._whenMatched.Value; if (!when.IsDelete) { IReadOnlyList <ColumnValueUpdateMap>?extraMaps = null; if (when.Mapping != null) { var mergeUpdateSetter = new MergerUpdateSetter <TTable>(this._table, this._sourceTableAlias); when.Mapping.Invoke(mergeUpdateSetter); extraMaps = mergeUpdateSetter.Maps; } var updateColNum = allColumns.Count - keys.Count; if (updateColNum == 0 && extraMaps == null) { throw new SqExpressException("'WHEN MATCH THEN UPDATE..' should have at least one assignment"); } ExprColumnSetClause[] sets = new ExprColumnSetClause[updateColNum + (extraMaps?.Count ?? 0)]; for (int i = keys.Count; i < allColumns.Count; i++) { sets[i - keys.Count] = new ExprColumnSetClause(allColumns[i].WithSource(this._table.Alias), allColumns[i].WithSource(this._sourceTableAlias)); } if (extraMaps != null && extraMaps.Count > 0) { for (int i = updateColNum; i < sets.Length; i++) { var extraMap = extraMaps[i - updateColNum]; sets[i] = new ExprColumnSetClause(extraMap.Column.WithSource(this._table.Alias), extraMap.Value); } } HashSet <ExprColumn> duplicateChecker = new HashSet <ExprColumn>(); for (int i = 0; i < sets.Length; i++) { if (!duplicateChecker.Add(sets[i].Column)) { throw new SqExpressException($"The column name '{sets[i].Column.ColumnName.Name}' is specified more than once in the SET clause"); } } return(new ExprMergeMatchedUpdate(when.And, sets)); } return(new ExprMergeMatchedDelete(when.And)); }
private IExprMergeNotMatched?BuildWhenNotMatchedByTarget(IReadOnlyList <ExprColumnName> keys, IReadOnlyList <ExprColumnName> allColumns) { if (!this._whenNotMatchedByTarget.HasValue) { return(null); } var when = this._whenNotMatchedByTarget.Value; if (!when.IsDefaultValues) { IReadOnlyList <ColumnValueUpdateMap>?extraMaps = null; if (when.Mapping != null) { var mergeUpdateSetter = new MergerUpdateSetter <TTable>(this._table, this._sourceTableAlias); when.Mapping(mergeUpdateSetter); extraMaps = mergeUpdateSetter.Maps; } var actualColumns = when.ExcludeKeys ? new ReadOnlyListSegment <ExprColumnName>(allColumns, keys.Count) : new ReadOnlyListSegment <ExprColumnName>(allColumns); int totalCount = actualColumns.Count + (extraMaps?.Count ?? 0); var insertColumns = new List <ExprColumnName>(totalCount); var insertValues = new List <IExprAssigning>(totalCount); for (int i = 0; i < actualColumns.Count; i++) { var coll = actualColumns[i]; if (when.Exclude != null && when.Exclude.Contains(coll)) { continue; } insertColumns.Add(coll); insertValues.Add(coll.WithSource(this._sourceTableAlias)); } if (extraMaps != null && extraMaps.Count > 0) { for (int i = actualColumns.Count; i < totalCount; i++) { var m = extraMaps[i - actualColumns.Count]; insertColumns.Add(m.Column); insertValues.Add(m.Value); } } HashSet <ExprColumnName> duplicateChecker = new HashSet <ExprColumnName>(); for (int i = 0; i < insertColumns.Count; i++) { if (!duplicateChecker.Add(insertColumns[i])) { throw new SqExpressException($"The column name '{insertColumns[i].Name}' is specified more than once in the column list of an INSERT"); } } return(new ExprExprMergeNotMatchedInsert(when.And, insertColumns, insertValues)); } return(new ExprExprMergeNotMatchedInsertDefault(when.And)); }