jhthorsen / mojo-mysql

Mojolicious and Async MySQL

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SQL::Abstract::mysql overrides random parts of the SQL::Abstract internals and will almost certainly break with the next SQL::Abstract release

shadowcat-mst opened this issue · comments

If you want additional features in SQL::Abstract please contact the SQL::Abstract development team via irc.perl.org #dbix-class - ping 'mst' or 'ilmari' specifically.

The SQL::Abstract::mysql shipped as part of Mojo::mysql is incredibly fragile and since nobody bothered talking to us before writing it, relies on things that are unstable, unsupported and will almost certainly be broken by the next release of SQL::Abstract.

The current code should never have been released to cpan as a stable release and I'm really quite sad that, unlike sri (the author of Mojo::Pg), it didn't occur to whoever perpetrated this that co-operating with the developers of other cpan modules is a good idea, especially if you're going to override undocumented and unsupported parts of the internals and then have that talk to other people's production databases.

-- mst

@Tekki: Is this something you have time to fix in a stable way? If not, then I think I have to mark SQL::Abstract::mysql as DEPRECATED, and make a release with a huge warning. I find the SQLA code very difficult to navigate and override, so I don't see how I can find time to fix it myself.

I will however have a second look if nobody else can.

To every user of Mojo::mysql: I'm very sorry that I accepted changes that would get delete(), insert() and select() into the state they are now. query() is not affected though, so if you craft your own SQL, then you have nothing to worry about.

Note to self: Do not accept pull requests where the code override private methods and/or methods marked as experimental, without talking to the maintainers.

OK. I believe I have mostly figured this out. I have no idea at all what the _METHOD_for_refkind crap was in aid of but here's how you do it without that:

diff --git a/lib/SQL/Abstract/mysql.pm b/lib/SQL/Abstract/mysql.pm
index f97a1a2..39927dc 100644
--- a/lib/SQL/Abstract/mysql.pm
+++ b/lib/SQL/Abstract/mysql.pm
@@ -5,12 +5,11 @@ BEGIN { *puke = \&SQL::Abstract::puke }
 
 sub insert {
   my $self    = shift;
-  my $table   = $self->_table(shift);
-  my $data    = shift || return;
-  my $options = shift || {};
+  my $table   = $self->_table($_[0]);
+  my $data    = $_[1] || return;
+  my $options = $_[2] || {};
 
-  my $method = $self->_METHOD_FOR_refkind('_insert', $data);
-  my ($sql, @bind) = $self->$method($data);
+  my ($sql, @bind) = $self->SUPER::insert(@_);
   my $command;
 
   # options
@@ -26,11 +25,9 @@ sub insert {
     else {
       $command = $commands{$on_conflict} or puke qq{on_conflict value "$on_conflict" is not allowed};
     }
+    my $replace = $self->_sqlcase($command);
+    $sql =~ s/^(\w+)/$replace/;
   }
-  else {
-    $command = 'insert';
-  }
-  $sql = join ' ', $self->_sqlcase("$command into"), $table, $sql;
 
   return wantarray ? ($sql, @bind) : $sql;
 }

Additionally, t/sql.t is utter bollocks in that it uses is_deeply so it's sensitive to minor whitespace changes and minor paren changes which means it was always a ticking timebomb even without the other problems.

The solution to this is to use http://p3rl.org/SQL::Abstract::Test - which you can see in action in Mojo::Pg's test suite here: https://metacpan.org/source/SRI/Mojo-Pg-4.18/t/sql.t

If you apply the patch I've supplied and rewrite the offending test, you should be fine. You can test this by doing 'cpanm --dev SQL::Abstract' to install the current dev release - assuming I've not fucked up anything else (which, well, y'know, always possible) once those changes are in the code should pass against both and be basically fine for the moment.

Note that I would've much rather helped make these changes before they shipped into production, and that's the part that my original issue filing comment was so unhappy about, but so long as we get it fixed, fuck it.

Note also I'm fairly sure that ->insert($table, @values) which is a documented SQL::Abstract API was broken by the original egregious hack and my patch should restore that to functioning - I'd recommend once t/sql.t is using SQL::Abstract::Test that somebody adds a test for that one just to be sure and gives me a kick if I'm wrong and I didnb't fix it.

As a final note, @Tekki you didn't do that badly with the code, just copy-pasting parts of the SQLA sources and editing them isn't really a robust way to subclass and next time you plan something that clever, please do have a go but also please please please talk to me or ilmari before it hits cpan so we can help make sure there's no unnecessary footguns in there.

I'd note that when I wrote the original issue text, this was the third thing that had broken the build of the customer project I was working on in the same day so even though I knew that and did my best to tone down my language it still came across a bit more forceful than was strictly necessary. So, sorry for that, and just, y'know, talk to me first next time <3

I've taken the t/sql.t changes @jhthorsen added to his now-closed PR and combined them with my patch and #77 is the result.

This works with

cpanm SQL::Abstract@1.86;
perl -Ilib t/sql.t

and also

cpanm --dev SQL::Abstract
perl -Ilib t/sql.t

so I believe is a correct update to get everything solid again.

Further changes may or may not be desireable but thanks to the test work I believe we have a completely suitable fix for the current problems.

Thanks @shadowcat-mst! I really appreciate it <3

commented

@jhthorsen and @shadowcat-mst: sorry, I had no time to look into this during the last week. There are a lot of Whys in this thread, so maybe I should clarify a bit: This was one of my first pull requests to this repo and at the beginning I even didn't have a login on cpan. I started with imitating what mojo-pg is doing and suddenly we needed more and more functionality. I was never happy with the way I had to deal with SQL::Abstract (or what I thought is the way) and I complained several times about it. Just, nobody told me I could do it differently. @shadowcast-mst, I'm really happy that now we know who to contact about SQL::Abstract and that you made time to improve the code. And I hope you are no longer sad about the fragile code that we uploaded to cpan last year.