From 96625951d5cb2a655485551e66c8978d32179e86 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Wed, 29 May 2024 10:59:13 +0100 Subject: [PATCH 1/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 3dfe35bbe..5ca0d01ac 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -33,7 +33,35 @@ def visit_Arel_Nodes_UpdateStatement(o, collector) if o.orders.any? && o.limit.nil? o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) end - super + + + + collector.retryable = false + # o = prepare_update_statement(o) + + collector << "UPDATE " + + + visit o.relation.left, collector + + collect_nodes_for o.values, collector, " SET " + + collector << " FROM " + visit o.relation.left, collector + + collector << " " + collector = visit o.relation.right, collector + + collect_nodes_for o.wheres, collector, " WHERE ", " AND " + collect_nodes_for o.orders, collector, " ORDER BY " + maybe_visit o.limit, collector + + + # + + + + # super end def visit_Arel_Nodes_Lock(o, collector) From 3a88a8fec126b338a619d66a3e8c282cd90cd94c Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Wed, 29 May 2024 11:21:35 +0100 Subject: [PATCH 2/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 5ca0d01ac..bfab75b99 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -34,34 +34,31 @@ def visit_Arel_Nodes_UpdateStatement(o, collector) o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) end + if o.key && o.key.size > 1 + collector.retryable = false + _visit_Arel_Nodes_UpdateStatement(o, collector) + else + super + end + end - - collector.retryable = false - # o = prepare_update_statement(o) - + def _visit_Arel_Nodes_UpdateStatement(o, collector) collector << "UPDATE " - - visit o.relation.left, collector + if has_join_sources?(o) + visit o.relation.left, collector + else + visit o.relation, collector + end collect_nodes_for o.values, collector, " SET " collector << " FROM " - visit o.relation.left, collector - - collector << " " - collector = visit o.relation.right, collector + visit o.relation, collector collect_nodes_for o.wheres, collector, " WHERE ", " AND " collect_nodes_for o.orders, collector, " ORDER BY " maybe_visit o.limit, collector - - - # - - - - # super end def visit_Arel_Nodes_Lock(o, collector) From a232dd5ad1658a51518cbe7776cbea6118ffbeae Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 4 Jun 2024 10:22:02 +0100 Subject: [PATCH 3/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index bfab75b99..856f96db7 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -30,14 +30,18 @@ def visit_Arel_Nodes_Concat(o, collector) end def visit_Arel_Nodes_UpdateStatement(o, collector) - if o.orders.any? && o.limit.nil? - o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) - end - if o.key && o.key.size > 1 + + # binding.pry if $DEBUG + + if o.key && o.key.relation.is_a?(Arel::Table) && o.key.relation.instance_variable_get(:@klass).composite_primary_key? collector.retryable = false _visit_Arel_Nodes_UpdateStatement(o, collector) else + if o.orders.any? && o.limit.nil? + o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) + end + super end end From 2fe1c67d648af77a22cb6c8902768b7c0a6b99a4 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Thu, 6 Jun 2024 19:27:43 +0100 Subject: [PATCH 4/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 47 +++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 856f96db7..39d49ade0 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -29,31 +29,54 @@ def visit_Arel_Nodes_Concat(o, collector) visit o.right, collector end + + # def prepare_update_statement(o) + # if o.offset || has_group_by_and_having?(o) || + # has_join_sources?(o) && has_limit_or_offset_or_orders?(o) + # super + # else + # o + # end + # end + def visit_Arel_Nodes_UpdateStatement(o, collector) + + + # binding.pry if $DEBUG - if o.key && o.key.relation.is_a?(Arel::Table) && o.key.relation.instance_variable_get(:@klass).composite_primary_key? - collector.retryable = false + + if has_join_sources?(o) && o.relation.left.instance_variable_get(:@klass).composite_primary_key? _visit_Arel_Nodes_UpdateStatement(o, collector) else - if o.orders.any? && o.limit.nil? - o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) - end - super end + + + # if o.key && o.key.is_a?(Arel::Attributes::Attribute) && o.key.relation.is_a?(Arel::Table) && o.key.relation.instance_variable_get(:@klass).composite_primary_key? + # collector.retryable = false + # _visit_Arel_Nodes_UpdateStatement(o, collector) + # else + # if o.orders.any? && o.limit.nil? + # o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) + # end + # + # super + # end end def _visit_Arel_Nodes_UpdateStatement(o, collector) collector << "UPDATE " - if has_join_sources?(o) + # binding.pry if $DEBUG + + # if has_join_sources?(o) visit o.relation.left, collector - else - visit o.relation, collector - end + # else + # visit o.relation, collector + # end collect_nodes_for o.values, collector, " SET " @@ -61,8 +84,8 @@ def _visit_Arel_Nodes_UpdateStatement(o, collector) visit o.relation, collector collect_nodes_for o.wheres, collector, " WHERE ", " AND " - collect_nodes_for o.orders, collector, " ORDER BY " - maybe_visit o.limit, collector + # collect_nodes_for o.orders, collector, " ORDER BY " + # maybe_visit o.limit, collector end def visit_Arel_Nodes_Lock(o, collector) From a1136b2d970cc6d7fb795ae20b5d8361d4047465 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sat, 8 Jun 2024 17:21:56 +0100 Subject: [PATCH 5/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 39d49ade0..75db4ae9d 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -51,6 +51,10 @@ def visit_Arel_Nodes_UpdateStatement(o, collector) if has_join_sources?(o) && o.relation.left.instance_variable_get(:@klass).composite_primary_key? _visit_Arel_Nodes_UpdateStatement(o, collector) else + if o.orders.any? && o.limit.nil? + o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) + end + super end From 42704807c9437512a9f5032308eaab7c67691b90 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sat, 8 Jun 2024 17:33:59 +0100 Subject: [PATCH 6/8] Cleanup --- lib/arel/visitors/sqlserver.rb | 48 +++------------------------------- 1 file changed, 3 insertions(+), 45 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 75db4ae9d..e0160d143 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -29,27 +29,9 @@ def visit_Arel_Nodes_Concat(o, collector) visit o.right, collector end - - # def prepare_update_statement(o) - # if o.offset || has_group_by_and_having?(o) || - # has_join_sources?(o) && has_limit_or_offset_or_orders?(o) - # super - # else - # o - # end - # end - def visit_Arel_Nodes_UpdateStatement(o, collector) - - - - - - # binding.pry if $DEBUG - - if has_join_sources?(o) && o.relation.left.instance_variable_get(:@klass).composite_primary_key? - _visit_Arel_Nodes_UpdateStatement(o, collector) + update_statement_using_join(o, collector) else if o.orders.any? && o.limit.nil? o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) @@ -57,39 +39,15 @@ def visit_Arel_Nodes_UpdateStatement(o, collector) super end - - - # if o.key && o.key.is_a?(Arel::Attributes::Attribute) && o.key.relation.is_a?(Arel::Table) && o.key.relation.instance_variable_get(:@klass).composite_primary_key? - # collector.retryable = false - # _visit_Arel_Nodes_UpdateStatement(o, collector) - # else - # if o.orders.any? && o.limit.nil? - # o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) - # end - # - # super - # end end - def _visit_Arel_Nodes_UpdateStatement(o, collector) + def update_statement_using_join(o, collector) collector << "UPDATE " - - # binding.pry if $DEBUG - - # if has_join_sources?(o) - visit o.relation.left, collector - # else - # visit o.relation, collector - # end - + visit o.relation.left, collector collect_nodes_for o.values, collector, " SET " - collector << " FROM " visit o.relation, collector - collect_nodes_for o.wheres, collector, " WHERE ", " AND " - # collect_nodes_for o.orders, collector, " ORDER BY " - # maybe_visit o.limit, collector end def visit_Arel_Nodes_Lock(o, collector) From cdf715279de284c1d5c980601152d2ddefb0325c Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sat, 8 Jun 2024 17:50:16 +0100 Subject: [PATCH 7/8] Update sqlserver.rb --- lib/arel/visitors/sqlserver.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index e0160d143..b5c7724b4 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -42,6 +42,8 @@ def visit_Arel_Nodes_UpdateStatement(o, collector) end def update_statement_using_join(o, collector) + collector.retryable = false + collector << "UPDATE " visit o.relation.left, collector collect_nodes_for o.values, collector, " SET " From 9807dd2feca5b50875c839fd5e28300dcd403970 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Sat, 8 Jun 2024 17:58:53 +0100 Subject: [PATCH 8/8] Handle delete for join with composite primary key --- lib/arel/visitors/sqlserver.rb | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index b5c7724b4..b4cef188d 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -30,20 +30,40 @@ def visit_Arel_Nodes_Concat(o, collector) end def visit_Arel_Nodes_UpdateStatement(o, collector) - if has_join_sources?(o) && o.relation.left.instance_variable_get(:@klass).composite_primary_key? + if has_join_and_composite_primary_key?(o) update_statement_using_join(o, collector) else - if o.orders.any? && o.limit.nil? - o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) - end + o.limit = Nodes::Limit.new(9_223_372_036_854_775_807) if o.orders.any? && o.limit.nil? super end end + def visit_Arel_Nodes_DeleteStatement(o, collector) + if has_join_and_composite_primary_key?(o) + delete_statement_using_join(o, collector) + else + super + end + end + + def has_join_and_composite_primary_key?(o) + has_join_sources?(o) && o.relation.left.instance_variable_get(:@klass).composite_primary_key? + end + + def delete_statement_using_join(o, collector) + collector.retryable = false + + collector << "DELETE " + visit o.relation.left, collector + collector << " FROM " + visit o.relation, collector + collect_nodes_for o.wheres, collector, " WHERE ", " AND " + end + def update_statement_using_join(o, collector) collector.retryable = false - + collector << "UPDATE " visit o.relation.left, collector collect_nodes_for o.values, collector, " SET "