Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mysql2 error using mysql 5.7.9 and 5.7.10 (Fix: upgrade to 5.7.12 or later) #190

Closed
slbug opened this issue Nov 18, 2015 · 9 comments
Closed

Comments

@slbug
Copy link

slbug commented Nov 18, 2015

EXCEPTION: Mysql2::Error: You can't specify target table 'page_hierarchies' for update in FROM clause: DELETE FROM `page_hierarchies`
WHERE descendant_id IN (
  SELECT DISTINCT descendant_id
  FROM (SELECT descendant_id
    FROM `page_hierarchies`
    WHERE ancestor_id = 5
       OR descendant_id = 5
  ) AS x )
@RISCfuture
Copy link

Seems that MySQL 5.7 has gotten more strict about subselects on mutating tables. I've written a workaround that splits the query into two steps. Note that this is not as concurrent-safe and should probably not be used in high-concurrency environments.

module ClosureTree
  module HierarchyMaintenance
    def delete_hierarchy_references
      _ct.with_advisory_lock do
        results = _ct.connection.execute(<<-SQL.strip_heredoc)
          SELECT DISTINCT descendant_id
            FROM #{_ct.quoted_hierarchy_table_name}
            WHERE ancestor_id = #{_ct.quote(id)}
              OR descendant_id = #{_ct.quote(id)}
        SQL

        ids = Array.new
        results.each { |(descendant_id)| ids << descendant_id }

        _ct.connection.execute <<-SQL.strip_heredoc
          DELETE FROM #{_ct.quoted_hierarchy_table_name}
            WHERE descendant_id IN (#{ids.join(',')})
        SQL
      end
    end
  end
end

@tism
Copy link

tism commented Feb 26, 2016

You can do this in one pass, the DISTINCT currently in the query is one level too high.

module ClosureTree
  module HierarchyMaintenance
    def delete_hierarchy_references
      _ct.with_advisory_lock do
        _ct.connection.execute <<-SQL.strip_heredoc
          DELETE FROM #{_ct.quoted_hierarchy_table_name}
          WHERE descendant_id IN (
            SELECT descendant_id
            FROM (SELECT DISTINCT descendant_id
              FROM #{_ct.quoted_hierarchy_table_name}
              WHERE ancestor_id = #{_ct.quote(id)}
                 OR descendant_id = #{_ct.quote(id)}
            ) AS x )
        SQL
      end
    end
  end
end

I'll have a look at a PR, still need to confirm this doesn't now break things on <5.7.

sanghyukkang added a commit to UJET/closure_tree that referenced this issue Mar 4, 2016
Move `DISTINCT` keyword to inner query to force the derived table to be
materialized in the query deleting hierarchy references.

Issue:
ClosureTree#190

Same issue in Rails:
rails/rails#19281

Related MySQL reference:
http://dev.mysql.com/doc/refman/5.7/en/upgrading-from-previous-series.html
@ghost
Copy link

ghost commented Sep 20, 2016

I just ran into this error, as well. Mysql 5.7.10

@gsmetal
Copy link

gsmetal commented Nov 22, 2016

FYI: I have the same error on Mysql 5.7.10 and have no error on Mysql 5.7.12.

@ghost
Copy link

ghost commented Nov 22, 2016

Follow up: I haven't seen the issue and am currently using mysql version 5.7.16 , I wonder what changed and then unchanged between mysql patch versions.

@mceachen
Copy link
Collaborator

How do people feel we should handle this? A note on the README, or a warning message in the code?

Thanks, @pskrz and @gsmetal for the updates!

@mceachen mceachen changed the title Mysql2 error using mysql 5.7.9 Mysql2 error using mysql 5.7.9 (Fix: upgrade to 5.7.10 or later) Nov 22, 2016
@mceachen mceachen changed the title Mysql2 error using mysql 5.7.9 (Fix: upgrade to 5.7.10 or later) Mysql2 error using mysql 5.7.9 and 5.7.10 (Fix: upgrade to 5.7.12 or later) Nov 22, 2016
@ghost
Copy link

ghost commented Nov 22, 2016

Both, the README is easy enough, it'd be nice to add a why and what changed to cause the failure and what changed that the failure no longer happens.

I don't know where you would put the warning message though, when adding the gem and bundle installing?

@mceachen
Copy link
Collaborator

I'm assuming the MySQL query parser was changed--and it wouldn't be the first time a patch release to MySQL caused heartache. Their versioning has been maddening since I started using it in pre-5.x times.

@mceachen
Copy link
Collaborator

Updated the README. Thanks again for your reports.

mceachen added a commit that referenced this issue Nov 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants