diff --git a/Orm/Xtensive.Orm/Sql/Dml/Collections/SqlInsertValuesCollection.cs b/Orm/Xtensive.Orm/Sql/Dml/Collections/SqlInsertValuesCollection.cs index 884487dffe..34ba8e6c42 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Collections/SqlInsertValuesCollection.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Collections/SqlInsertValuesCollection.cs @@ -123,7 +123,7 @@ internal SqlInsertValuesCollection Clone(SqlNodeCloneContext ctx) clone.rows = new List(rows.Count); foreach(var oldRow in rows) { - clone.rows.Add((SqlRow) oldRow.Clone()); + clone.rows.Add(oldRow.Clone(ctx)); } return clone; diff --git a/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlConcat.cs b/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlConcat.cs index defad72932..08d1ed909a 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlConcat.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlConcat.cs @@ -14,20 +14,14 @@ namespace Xtensive.Sql.Dml [Serializable] public class SqlConcat : SqlExpressionList { - internal override SqlConcat Clone(SqlNodeCloneContext context) - { - if (context.NodeMapping.TryGetValue(this, out var value)) { - return (SqlConcat)value; - } - - var expressionsClone = new SqlExpression[expressions.Count]; - int i = 0; - foreach (var e in expressions) - expressionsClone[i++] = e.Clone(context); - - var clone = new SqlConcat(expressionsClone); - return clone; - } + internal override SqlConcat Clone(SqlNodeCloneContext context) => + context.GetOrAdd(this, static (t, c) => { + var source = t.expressions; + var expressionsClone = new SqlExpression[source.Count]; + for (int i = 0; i < source.Count; i++) + expressionsClone[i] = source[i].Clone(c); + return new SqlConcat(expressionsClone); + }); public override void ReplaceWith(SqlExpression expression) { diff --git a/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlRow.cs b/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlRow.cs index 5e91812777..b13ae82ac6 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlRow.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Expressions/SqlRow.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Linq; using Xtensive.Core; namespace Xtensive.Sql.Dml @@ -12,10 +11,14 @@ namespace Xtensive.Sql.Dml [Serializable] public class SqlRow: SqlExpressionList { - internal override SqlRow Clone(SqlNodeCloneContext context) - { - return (context.TryGet(this) as SqlRow) ?? new(expressions.Select(e => e.Clone(context)).ToArray()); - } + internal override SqlRow Clone(SqlNodeCloneContext context) => + context.GetOrAdd(this, static (t, c) => { + var source = t.expressions; + var expressionsClone = new SqlExpression[source.Count]; + for (int i = 0; i < source.Count; i++) + expressionsClone[i] = source[i].Clone(c); + return new SqlRow(expressionsClone); + }); public override void ReplaceWith(SqlExpression expression) => expressions = ArgumentValidator.EnsureArgumentIs(expression).expressions; diff --git a/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlForceJoinOrderHint.cs b/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlForceJoinOrderHint.cs index 6c7b89b390..291aaa6f16 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlForceJoinOrderHint.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlForceJoinOrderHint.cs @@ -3,7 +3,6 @@ // See the License.txt file in the project root for more information. using System; -using System.Linq; using System.Collections.Generic; using Xtensive.Core; @@ -18,8 +17,15 @@ public class SqlForceJoinOrderHint : SqlHint public IReadOnlyList Tables { get; } internal override SqlForceJoinOrderHint Clone(SqlNodeCloneContext context) => - context.GetOrAdd(this, static (t, c) => - new SqlForceJoinOrderHint(t.Tables?.Select(table => (SqlTable) table.Clone()).ToArray())); + context.GetOrAdd(this, static (t, c) => { + if (t.Tables is null) + return new SqlForceJoinOrderHint(); + var source = t.Tables; + var tablesClone = new SqlTable[source.Count]; + for (int i = 0; i < source.Count; i++) + tablesClone[i] = (SqlTable) source[i].Clone(c); + return new SqlForceJoinOrderHint(tablesClone); + }); public override void AcceptVisitor(ISqlVisitor visitor) { diff --git a/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlJoinHint.cs b/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlJoinHint.cs index a3b76edb42..c06094321f 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlJoinHint.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Hints/SqlJoinHint.cs @@ -24,7 +24,7 @@ public class SqlJoinHint : SqlHint public SqlTable Table { get; private set; } internal override SqlJoinHint Clone(SqlNodeCloneContext context) => - context.GetOrAdd(this, static (t, c) => new(t.Method, (SqlTable) t.Table.Clone())); + context.GetOrAdd(this, static (t, c) => new(t.Method, (SqlTable) t.Table.Clone(c))); public override void AcceptVisitor(ISqlVisitor visitor) { diff --git a/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlSelect.cs b/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlSelect.cs index 16a7e15b3e..685434c9f4 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlSelect.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlSelect.cs @@ -163,8 +163,8 @@ internal override SqlSelect Clone(SqlNodeCloneContext context) => foreach (SqlOrder so in t.orderBy) clone.OrderBy.Add(so.Clone(c)); clone.Distinct = t.Distinct; - clone.Limit = t.Limit; - clone.Offset = t.Offset; + clone.Limit = t.Limit?.Clone(c); + clone.Offset = t.Offset?.Clone(c); clone.Lock = t.Lock; clone.Comment = t.Comment?.Clone(c); diff --git a/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlUpdate.cs b/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlUpdate.cs index 0fc57b5ee9..2200dbbf6e 100644 --- a/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlUpdate.cs +++ b/Orm/Xtensive.Orm/Sql/Dml/Statements/SqlUpdate.cs @@ -80,7 +80,7 @@ internal override SqlUpdate Clone(SqlNodeCloneContext context) => if (t.where is not null) clone.Where = t.where.Clone(c); if (t.limit is not null) - clone.Limit = t.where.Clone(c); + clone.Limit = t.limit.Clone(c); if (t.Hints.Count > 0) foreach (SqlHint hint in t.Hints) clone.AddHint(hint.Clone(c));