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

Fix invalid SQL generated by OrderBy().Collate() #268

Merged
merged 1 commit into from
Aug 19, 2024

Conversation

mbezhanov
Copy link
Contributor

Fixes #252

Tested with the following schemas and code:

MySQL
CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255)
);
INSERT INTO users (name) VALUES ('béatrice'), ('bérénice'), ('bernard'), ('boris');
SELECT * FROM users ORDER BY name COLLATE utf8mb4_bin ASC;
SELECT * FROM users ORDER BY name COLLATE utf8mb4_unicode_ci ASC;
ctx := context.Background()

ex, err := bob.Open("mysql", "test:test@/test?parseTime=true")
if err != nil {
  log.Fatal(err)
}

type userObj struct {
  Id   int
  Name string
}

cls := []string{"utf8mb4_bin", "utf8mb4_unicode_ci"}

for _, cl := range cls {
  q := mysql.Select(
    sm.Columns("id", "name"),
    sm.From("users"),
    sm.OrderBy(models.UserColumns.Name).Collate(cl).Asc(),
  )

  users, err := bob.All(ctx, ex, q, scan.StructMapper[userObj]())
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println()
  fmt.Println(cl)
  for _, u := range users {
    fmt.Println(u)
  }
}
PostgreSQL
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  name TEXT
);
INSERT INTO users (name) VALUES ('béatrice'), ('bérénice'), ('bernard'), ('boris');
SELECT * FROM users ORDER BY name COLLATE "C" asc;
SELECT * FROM users ORDER BY name COLLATE "fr-FR-x-icu";
ctx := context.Background()

ex, err := bob.Open("postgres", "postgres://postgres:test@localhost/test?sslmode=disable")
if err != nil {
  log.Fatal(err)
}

type userObj struct {
  Id   int
  Name string
}

cls := []string{"C", "fr-FR-x-icu"} 

for _, cl := range cls {
  q := psql.Select(
    sm.Columns("id", "name"),
    sm.From("users"),
    sm.OrderBy(models.UserColumns.Name).Collate(cl).Asc(),
  )

  users, err := bob.All(ctx, ex, q, scan.StructMapper[userObj]())
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println()
  fmt.Println(cl)
  for _, u := range users {
    fmt.Println(u)
  }
}
SQLite
CREATE TABLE users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT
);
INSERT INTO users (name) VALUES ('Béatrice'), ('Bérénice'), ('bernard'), ('boris');
SELECT * FROM users ORDER BY name COLLATE BINARY ASC;
SELECT * FROM users ORDER BY name COLLATE NOCASE ASC;
ctx := context.Background()

ex, err := bob.Open("sqlite", "file:/home/marin/Projects/GolandProjects/bob/file.db")
if err != nil {
  log.Fatal(err)
}

type userObj struct {
  Id   int
  Name string
}

cls := []string{"BINARY", "NOCASE"}

for _, cl := range cls {
  q := sqlite.Select(
    sm.Columns("id", "name"),
    sm.From("users"),
    sm.OrderBy(models.UserColumns.Name).Collate(cl).Asc(),
  )

  users, err := bob.All(ctx, ex, q, scan.StructMapper[userObj]())
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println()
  fmt.Println(cl)
  for _, u := range users {
    fmt.Println(u)
  }
}

Let me know if any adjustments are necessary.

@mbezhanov
Copy link
Contributor Author

I have no clue why the linters are failing in the GitHub Actions pipeline.

I haven't changed anything in these files, plus everything passes locally:

golangci-lint run --out-format=github-actions --verbose
INFO golangci-lint has version 1.59.1 built with go1.22.3 from 1a55854a on 2024-06-09T18:08:33Z 
INFO [config_reader] Config search paths: [./ /home/marin/Projects/GolandProjects/bob /home/marin/Projects/GolandProjects /home/marin/Projects /home/marin /home /] 
INFO [config_reader] Used config file .golangci.yml 
WARN [config_reader] The output format `github-actions` is deprecated, please use `colored-line-number` 
INFO [lintersdb] Active 28 linters: [errcheck errname errorlint gci gochecknoglobals gocyclo godox gofumpt gosec gosimple govet ineffassign maintidx misspell nakedret nestif nilerr nilnil noctx nolintlint nonamedreturns prealloc predeclared revive staticcheck thelper unparam unused] 
INFO [loader] Go packages loading at mode 575 (compiled_files|exports_file|files|name|deps|imports|types_sizes) took 34.490438048s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 11.363517ms 
INFO [linters_context/goanalysis] analyzers took 29.202710066s with top 10 stages: buildir: 3.508233577s, the_only_name: 1.048607225s, gofumpt: 1.00165496s, buildssa: 798.978833ms, gosec: 783.836463ms, gci: 708.717586ms, errorlint: 590.077327ms, unparam: 574.213133ms, unused: 414.651335ms, commentmap: 407.469924ms 
INFO [runner] Issues before processing: 2956, after processing: 0 
INFO [runner] Processors filtering stat (out/in): invalid_issue: 2535/2956, cgo: 2956/2956, skip_files: 2535/2535, identifier_marker: 2535/2535, filename_unadjuster: 2956/2956, skip_dirs: 2535/2535, exclude-rules: 0/2535, path_prettifier: 2535/2535, autogenerated_exclude: 2535/2535, exclude: 2535/2535 
INFO [runner] processing took 14.734949ms with stages: identifier_marker: 13.253394ms, path_prettifier: 813.415µs, skip_dirs: 193.463µs, exclude-rules: 168.194µs, cgo: 91.445µs, invalid_issue: 83.565µs, filename_unadjuster: 69.603µs, autogenerated_exclude: 56.857µs, nolint: 1.358µs, max_same_issues: 951ns, sort_results: 393ns, fixer: 380ns, skip_files: 304ns, max_from_linter: 292ns, uniq_by_line: 275ns, exclude: 243ns, max_per_file_from_linter: 180ns, path_shortener: 154ns, path_prefixer: 145ns, source_code: 130ns, diff: 120ns, severity-rules: 88ns 
INFO [runner] linters took 1.111818364s with stages: goanalysis_metalinter: 1.097011149s 
INFO File cache stats: 222 entries of total size 640.3KiB 
INFO Memory: 358 samples, avg is 38.6MB, max is 581.1MB 
INFO Execution took 35.617245955s     

@stephenafamo
Copy link
Owner

I have no clue why the linters are failing in the GitHub Actions pipeline

It is possible you're running a slightly older version.
I belive the GitHub action always uses the latest version.

@mbezhanov
Copy link
Contributor Author

It is possible you're running a slightly older version.

You're right. I used to run 1.59. Now I caught them with 1.60.

@stephenafamo
Copy link
Owner

Thank you for all you work this.

Please also add details of this to the CHANGELOG 🙏🏾

@mbezhanov
Copy link
Contributor Author

Please also add details of this to the CHANGELOG 🙏🏾

✔️ Done

This was referenced Aug 17, 2024
@stephenafamo
Copy link
Owner

Is it necessary to include gen/file.db in the commit?

@mbezhanov
Copy link
Contributor Author

I apologize, this is an SQLite database I used for testing. I must have committed it by mistake. I'll update the PR accordingly later today.

@mbezhanov
Copy link
Contributor Author

PR updated. Sorry for the oversight.

@stephenafamo stephenafamo merged commit 22be31a into stephenafamo:main Aug 19, 2024
8 checks passed
@mbezhanov mbezhanov deleted the collate-fix branch August 19, 2024 07:05
MSALARy688889u

This comment was marked as spam.

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.

OrderBy.Collate()) creates invalid SQL
3 participants