drizzle-orm icon indicating copy to clipboard operation
drizzle-orm copied to clipboard

[BUG]: .default() does not work on boolean pg types

Open codesfromshad opened this issue 1 year ago • 2 comments

What version of drizzle-orm are you using?

0.31.2

What version of drizzle-kit are you using?

0.22.7

Describe the Bug

When I set .default(sql'FALSE').notNull() or .default(false).notNull(), manually entering a row does not result in FALSE by default.

Check the snapshot: image

The CHECK() constraint, using sql magic operator also doesn't work. I am aware the drizzle did not implement this yet.

Please check the code snippet below for understanding what I am trying to achieve:

export const trackers = createTable(
  "tracker",
  {
    id: uuid("id").primaryKey(),
    createdAt: timestamp("created_at", {
      mode: "date",
      withTimezone: true,
    }).default(sql`CURRENT_TIMESTAMP`).notNull(),
    hashedId: varchar("hashed_id", { length: 255 }).notNull(),
    country: varchar("country", { length: 2 }).notNull(),
    isMalicious: boolean("is_malicious").default(sql`FALSE`).notNull(),
    canBypassProtection: boolean("can_bypass_protection").default(sql`FALSE`).notNull(),
  },
  (tracker) => ({
    hashedIdIdx: index("tacker_hashedId_idx").on(tracker.hashedId),
    canBypassProtectionCstr:
      sql`CHECK (can_bypass_protection = FALSE OR (can_bypass_protection = TRUE AND is_malicious = TRUE))`, // <-- DOESN'T WORK
  })
);

Expected behavior

It should be FALSE by default.

Environment & setup

No response

codesfromshad avatar Jun 26 '24 11:06 codesfromshad

same here! been driving me crazy

raydelvecchio avatar Jul 09 '24 20:07 raydelvecchio

What is the createTable function? It would be awesome if you could send a full repro example, so I can add it to the test cases and fix it if needed

AndriiSherman avatar Aug 07 '24 13:08 AndriiSherman

@codesfromshad Is this issue specific to Drizzle Studio or are you encountering this issue while running a query with the ORM?

L-Mario564 avatar Aug 28 '24 17:08 L-Mario564

Same thing here.

export const blogs = createTable(
  "blogs",
  {
    id: serial("id").primaryKey(),
    author: varchar("author")
      .notNull()
      .references(() => userTable.username),
    title: varchar("title", { length: 255 }).notNull(),
    active: boolean("active").notNull().default(false),
    createdAt: timestamp("created_at")
      .default(sql`CURRENT_TIMESTAMP`)
      .notNull(),
    updatedAt: timestamp("updated_at").$onUpdate(() => new Date()),
    deletedAt: timestamp("deleted_at"),
  },
  (table) => ({
    blogTitleUniqueIdx: uniqueIndex("blog_title_uniqueIdx").on(table.title),
    /* Only force uniqueness on author's "current" blog (don't include deleted ones) */
    authorBlogUniqueIdx: uniqueIndex("author_blog_uniqueIdx")
      .on(table.author)
      .where(sql`"deleted_at" IS NULL`),
  })
);

.default(false) does not apply - therefore when "active" boolean isn't explicitly supplied, the entry isn't created due to the notNull() constraint.

I could explicitly include active: false on every DB insert, but you'd at least expect stuff to work? Or not take months of being swept under the rug? Isn't this a pretty huge deal?

Also, createTable is just an affix prepend helper for multi-project schema. export const createTable = pgTableCreator((name) =>vertexblog_${name});

MGSimard avatar Sep 14 '24 20:09 MGSimard

.default(false) does not apply

@MGSimard What do you mean by that? That the default value statement isn't being generated in migrations or that inside an insert query the default value isn't being applied?

I tried both anyways and both behave as expected in the latest version of ORM and Kit (v0.33.0 and v0.24.2 respectively). If it's an issue with an insert statement, I'm curious to know what driver you're using and how you've defined the query that's causing the issue.

L-Mario564 avatar Sep 16 '24 19:09 L-Mario564

.default(false) does not apply

@MGSimard What do you mean by that? That the default value statement isn't being generated in migrations or that inside an insert query the default value isn't being applied?

I tried both anyways and both behave as expected in the latest version of ORM and Kit (v0.33.0 and v0.24.2 respectively). If it's an issue with an insert statement, I'm curious to know what driver you're using and how you've defined the query that's causing the issue.

I mean it's intrinsically both isn't it? When you db:push this table schema, the default(false) constraint doesn't actually get applied to the column, which inherently means that whether you run an insert query or attempt to create a row manually in drizzle studio, the "active" column will default to null rather than false, which will obviously throw an error because of notNull(). You're being forced to supply an explicit true/false boolean on every insert or update, because default(false) isn't actually being applied on table creation, so any insert will not default to false. The exact context supplied by both the issue's OP and myself. Neither default(false) or default(sqlFALSE) work. This is on latest.

This behaviour can be observed simply by attempting to add an entry in drizzle studio, the untouched "active" column which is supposed to have a default(false) constraint actually says "NULL" instead of "DEFAULT". This is on the exact table described by the above schema.

image

I haven't tested on a non multi-project schema yet, but considering that if your testing of boolean .default() does indeed work on your end, and the fact that OP is using syntax indicating they're also doing multi-project schema -- could this possibly be yet another bug introduced by the use of multi-project schema, somehow? Same as this other issue introduced a few months ago?

MGSimard avatar Sep 20 '24 11:09 MGSimard

@codesfromshad @raydelvecchio @MGSimard Hey! This should be fixed.

RomanNabukhotnyi avatar Sep 25 '24 08:09 RomanNabukhotnyi