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

Producer args not used when generating SQL diffs #81

Closed
fgabolde opened this issue Mar 30, 2016 · 9 comments
Closed

Producer args not used when generating SQL diffs #81

fgabolde opened this issue Mar 30, 2016 · 9 comments

Comments

@fgabolde
Copy link
Contributor

I'm adding a boolean column to an existing table and creating a different table with a boolean column:

    "flagged_for_deletion",
    {   data_type => "boolean",
        is_nullable => 0,
        default_value => 0,
    },

and generating the DDL via DBIx::Class:

$schema->create_ddl_dir( ['MySQL'], undef, './sql/ddl', $opt->pre_version,
                         { producer_args => { mysql_version => 5 } });

The full schema is correctly generated, both tables have "flagged_for_deletion boolean NOT NULL DEFAULT '0'" which is exactly what I expected. The diff however:

CREATE TABLE `created` (
  -- snip
  `flagged_for_deletion` enum('0','1') NOT NULL DEFAULT '0',
  -- snip
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8;

ALTER TABLE altered -- snip
                    ADD COLUMN flagged_for_deletion boolean NOT NULL DEFAULT '0',
                    -- snip

The CREATE TABLE statement has the backtick quoting (that the full schema doesn't have) and uses MySQL 3-style boolean emulation with enums. From all the way over here it looks like it's been generated by a different producer with different options, so it might be a DBIC issue instead?

@ribasushi
Copy link
Contributor

From all the way over here it looks like it's been generated by a different producer

It is the same producer, but it is geared to do things differently based on an option.

Please investigate how/why this is not getting populated.

Alternatively please write a test (even if as a CLI oneliner) that demonstrates the problem.

Thanks!

@fgabolde
Copy link
Contributor Author

@ribasushi I narrowed it down to SQL::Translator::Diff, when building an SQL::Translator object in produce_diff_sql.

It should be:

      my $translator = SQL::Translator->new(
        producer_type => $self->output_db,
        add_drop_table => 0,
        no_comments => 1,
        producer_args => $self->producer_args
      );

otherwise the SQL::Translator constructor gets mysql_version directly as an argument. Obviously it wouldn't know what to do with a MySQL-specific argument, so it just gets thrown away.

The MySQL producer's produce method is then called a few lines later with that translator instance.

With this fix I can get my boolean column. I still have backticks everywhere, which is aesthetically annoying but I can live with that. :)

@fgabolde fgabolde changed the title Inconsistent behavior of MySQL producer with boolean columns Producer args not used when generating SQL diffs Mar 31, 2016
@ilmari
Copy link
Member

ilmari commented Mar 31, 2016

The problem with changing it to producer_args => $self->producer_args is that that would break existing uses of that to pass arguments to the translator, like this test. The attribute really should have been called translator_args.

@fgabolde: Can you try changing the create_ddl_dir argument to { producer_args => { producer_args => { mysql_version => 5 } } }?

@fgabolde
Copy link
Contributor Author

@ilmari I can, but then the regular producer (generating the full schema) loses mysql_version.

@ilmari
Copy link
Member

ilmari commented Mar 31, 2016

@fgabolde D'oh, of course. I think the most backwards-compatible fix would be to change create_ddl_dir to call schema_diff with { producer_args => $sqltargs }. Can you test that locally?

@fgabolde
Copy link
Contributor Author

@ilmari Yeah, that works. It doesn't break any tests in DBIC, which is unsettling, but I get both the full schema and the diff with the right mysql_version setting.

It changes some other things as well because those SQLT args seem tailored for the full DDL and not so much for the diff, so I get no quotes (which I like) and DROP TABLE IF EXISTS statements (which I don't really care about, I dunno if someone might).

melmothx added a commit to melmothx/amusewiki that referenced this issue Jan 25, 2017
This reverts commit 4c146fe.

It's going to produce inconsistent results between deploy and upgrade.

See dbsrgits/sql-translator#81
@racke
Copy link
Contributor

racke commented Jan 25, 2017

Honestly, I can't think of a single reason why mysql_version => 5 shouldn't be the default. I can't even remember when I last used a MySQL database 4. Now we produce crappy enum columns without any warning to the hapless user.

@melmothx
Copy link

Actually, with version 4 it gives boolean as well. So by default SQLT is producing boolean datatype for mysql 3...

@rabbiveesh
Copy link
Contributor

hey all, it's a bit late (only 6 years), but I just pushed a patch changing the name of the producer_args attribute on SQLT::Diff to sqlt_args, which is better-ly self documenting.
Essentially, this is the same confusion as #138 . You need to pass producer_args as an arg to producer_args. With the new sqlt_args name, it makes a lot more sense.

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

6 participants