sqlc icon indicating copy to clipboard operation
sqlc copied to clipboard

Capital letters in table alias causes generation to fail

Open mlucic opened this issue 1 year ago • 1 comments

Version

1.25.0

What happened?

Trying to generate a query where there is a table alias with capital letters causes the generation to fail with the error column "id" does not exist. Changing the alias to have only lowercase letters fixes the problem. Both are valid for MySQL, so sqlc should not be erroring when there are capital letters in the alias.

Relevant log output

$ sqlc generate
# package sqlc
query.sql:16:5: column "id" does not exist

Database schema

CREATE TABLE `blue` (
  `id` int NOT NULL AUTO_INCREMENT
  PRIMARY KEY (`id`)
);

SQL queries

SELECT
    `A`.`id`
FROM
    blue AS `A`;

Configuration

version: "2"
sql:
  - engine: "mysql"
    queries: "query.sql"
    schema: "schema.sql"
    gen:
      go:
        package: "sqlc"
        out: "sqlc"

Playground URL

No response

What operating system are you using?

Linux

What database engines are you using?

MySQL

What type of code are you generating?

Go

mlucic avatar Mar 11 '24 16:03 mlucic

Just found that the same error happens at runtime when using sqlc.embed where the table has a capital letter in it

e.g.

SELECT sqlc.embed(blueTable)
FROM blueTable;

mlucic avatar Mar 11 '24 22:03 mlucic

I am also running into this issue when using embeds, current work around is to just use lower case table names.

Migrations:

CREATE TABLE IF NOT EXISTS Users 
(
    id BIGINT NOT NULL,
    username VARCHAR(30) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS Posts
(
    id BIGINT NOT NULL,
    user_id BIGINT NOT NULL,
    created_at TIMESTAMP NOT NULL,
    title VARCHAR(100) NOT NULL,
    description VARCHAR(100) NOT NULL,
    markdown_url VARCHAR(100) NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (user_id) REFERENCES Users(id) ON DELETE CASCADE
);

Query:

-- name: GetUserAndPostsByIDPaged :many
SELECT sqlc.embed(Users), sqlc.embed(Posts) FROM Users 
LEFT JOIN Posts ON Users.id = Posts.user_id
WHERE Users.id = ? AND Posts.created_at > sqlc.arg(created_after) 
ORDER BY Posts.created_at ASC
LIMIT ?;

This generates the prepared statement:

const getUserAndPostsByIDPaged = `-- name: GetUserAndPostsByIDPaged :many
SELECT users.id, users.username, posts.id, posts.user_id, posts.created_at, posts.title, posts.description, posts.markdown_url FROM Users 
LEFT JOIN Posts ON Users.id = Posts.user_id
WHERE Users.id = ? AND Posts.created_at > ? 
ORDER BY Posts.created_at ASC
LIMIT ?
`

You can see here that when the embedding is expanded the casing is not respected

harrydayexe avatar Jan 24 '25 16:01 harrydayexe