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

CreateTableQuery: use correct VARCHAR length #738

Merged
merged 7 commits into from
Jan 5, 2023

Conversation

bevzzz
Copy link
Collaborator

@bevzzz bevzzz commented Dec 28, 2022

This PR fixes the handling of VARCHAR length in CREATE TABLE, see #736.

Changes:

  • Dialect implementations now need to have DefaultVarcharLen() uint, so that we wouldn't need to hardcode the default lengths in the dialect-specific types
  • Minor refactor of CreateAlterTable.appendSQLType
  • Since VARCHAR can only have positive length, the signature of CreateAlterTable.Varchar is changed to Varchar(n uint).
    This commit , therefore, has a BREAKING CHANGE ❗, as this would no longer compile:
var n int = 4
db.NewCreateTable().Model(...).Varchar(n)

Edit: breaking changes were reverted, see this commit instead.

This change is not necessary for the fix, I only propose this for the sake of additional "type safety" in the queries. It feels more transparent than something like n = max(0, n). However, if such API change is not acceptable, we could also return an error for q.varchar <= 0 or just revert this commit entirely.

The snapshot diff will show difference in case (got VARCHAR(255), want varchar(10)).
 That's not the bug and only done because CreateTableQuery.appendSQLType currently
 appends lowercase "varchar".
@bevzzz bevzzz force-pushed the fix/varchar_length branch 2 times, most recently from f8e4404 to 327f8de Compare December 28, 2022 15:02
…pe definition

+ use strings.EqualFold() for case-insensitive string comparison (SQL is case-insensitive)
+ Dialect interface now requires `DefaultVarcharLen()`
+ CreateTableQuery uses the length set in .Varchar() also for `bun:",type:varchar"`
@bevzzz bevzzz force-pushed the fix/varchar_length branch from 327f8de to 6003beb Compare December 28, 2022 15:07
@vmihailenco
Copy link
Member

@bevzzz looks good, thanks.

Could you clarify what happens when a dialect returns varchar=0 and CreateTableQuery does not specify Varchar length either? Do we have a test in query_test for such a case?

However, if such API change is not acceptable, we could also return an error for q.varchar <= 0 or just revert this commit entirely.

Let's not break the existing API. Instead, let's return an error like you suggested or just panic if returning an error is complicated.

Also, len(slice) can return only positive values too, but the return type is int, not uint. Just saying :)

@bevzzz
Copy link
Collaborator Author

bevzzz commented Dec 29, 2022

what happens when a dialect returns varchar=0 and CreateTableQuery does not specify Varchar length either?

We initialize q.varchar with the dialect's default length (see here), so if no other Varchar is specified (q.varchar == 0), we do not append anything in the parenthesis and the type stays VARCHAR .

Yes, there's a test case for that:

func(db *bun.DB) schema.QueryAppender {
    return db.NewCreateTable().Model(new(Model))
}

It's one of the older ones (no regressions ✌️ ), and for PG, which has default 0, it generates this query:

CREATE TABLE "models" ("id" BIGSERIAL NOT NULL, "str" VARCHAR, PRIMARY KEY ("id"))

Let's not break the existing API

Agreed. Good point about len(slice) too👍

@bevzzz bevzzz force-pushed the fix/varchar_length branch from a287d98 to 3335e0b Compare December 29, 2022 10:26
@vmihailenco vmihailenco merged commit 84e97c9 into uptrace:master Jan 5, 2023
@vmihailenco
Copy link
Member

Thanks 👍

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

Successfully merging this pull request may close these issues.

2 participants