question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Altering a colum to an enum with useNative: true fails, tries to create enum twice

See original GitHub issue

Environment

Knex version: 0.20.9 Database + version: Postgres 12 OS: Linux (Ubuntu)

Bug

If you attempt to alter a column to change it’s type to an enum, and you use the useNative: true enum option, knex will try to create the enum twice, which causes a “type already exists” error.

Here is an example migration which demonstrates the problem:

export async function up(knex: Knex): Promise<any> {
  return knex.schema
    .debug(true)
    .createTable("orders", (table) => {
      table.text("drink");
    })
    .alterTable("orders", (table) => {
      // This one works
      table.enum("size", ["small", "medium", "large"], {
        enumName: "drink_sizes",
        useNative: true,
      });

      // This one tries to create the enum twice
      table
        .enum("drink", ["coffee", "tea", "water"], {
          enumName: "drink_types",
          useNative: true,
        })
        .alter();
    });
}

If you look at the debug output from that migration, you will see that the first enum in the alterTable part generates the sql fine, but the second one (using .alter()) will create two identical create type sql statements, which causes Postgres to fail with ‘type “drink_types” already exists’

EDIT:

tl;dr Altering table to enum seems to try to create column type twice:

https://runkit.com/embed/xemoadwjsojw

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
elhigucommented, Feb 10, 2020

So maybe a simple flag inside the ColumnCompiler instance to keep track of whether the create type query has already been added would resolve this? Then only the first call to getColumnType() would add the query?

It sounds like a bad idea that getColumnType() creates that query as a side effect. Without looking the code to me it would make more sense to have createColumnType() and getColumnType() as a separate methods.

2reactions
mogzolcommented, Feb 10, 2020

But in this scenario I wouldn’t expect alter to delete the existing type, so that’s fine, I just don’t see why it is trying to create the type twice? This essentially makes it impossible to use .enum() with .alter() if you’re using native enums.

Is there any scenario where .alter() should create the type? It seems like the .enum() part is responsible for that, so why does alter also try to do it?

Read more comments on GitHub >

github_iconTop Results From Across the Web

knex migration creat type for enum thows type already exists
Looks like there is a bug in knex which causes create type query to be added twice when altering columns like that.
Read more >
MySQL 8.0 Reference Manual :: 11.3.5 The ENUM Type
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column...
Read more >
Postgres: Enum type fields | Hasura GraphQL Docs
You may use native Postgres enum types in your database schema, but they will essentially be treated like text fields in the generated...
Read more >
Schema Builder | Knex.js
Creates a new table on the database, with a callback function to modify the table's ... null, { useNative: true, existingType: true, enumName:...
Read more >
Enumerations - a free Hacking with Swift tutorial
If we make this an enum, it means Swift will accept only those five values – anything else will trigger an error. And...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found