When I do nested join I got weird error, after some playing around, it seems that there's a column name lenght limited.
type Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa struct {
tableName struct{} `sql:"a"`
ID uint64
}
type Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb struct {
tableName struct{} `sql:"b"`
ID uint64
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaID uint64 `sql:",notnull"`
}
type Cccccccccccccccccccccccccccccccccccccccccccccccccc struct {
tableName struct{} `sql:"c"`
ID uint64
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb *Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
BbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbID uint64 `sql:",notnull"`
}
type Ddd struct {
tableName struct{} `sql:"d"`
ID uint64
Cccccccccccccccccccccccccccccccccccccccccccccccccc *Cccccccccccccccccccccccccccccccccccccccccccccccccc
CcccccccccccccccccccccccccccccccccccccccccccccccccID uint64 `sql:",notnull"`
}
When I do simple select
err = db.Conn.Model(&ts).Column("Cccccccccccccccccccccccccccccccccccccccccccccccccc.Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.id").Select()
I got error:
ERROR #42712 table name "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbb" specified more than once
But SQL log shows, that everything should be OK
SELECT "ddd"."id",
"ddd"."cccccccccccccccccccccccccccccccccccccccccccccccccc_id",
"cccccccccccccccccccccccccccccccccccccccccccccccccc"."id" AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__id",
"cccccccccccccccccccccccccccccccccccccccccccccccccc"."bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id" AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id",
"cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."id" AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__id",
"cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id" AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id",
"cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"."id" AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa__id"
FROM d AS "ddd"
LEFT JOIN c AS "cccccccccccccccccccccccccccccccccccccccccccccccccc"
ON "cccccccccccccccccccccccccccccccccccccccccccccccccc"."id" =
"ddd"."cccccccccccccccccccccccccccccccccccccccccccccccccc_id"
LEFT JOIN b AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
ON "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."id" =
"cccccccccccccccccccccccccccccccccccccccccccccccccc"."bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id"
LEFT JOIN a AS "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
ON "cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"."id" =
"cccccccccccccccccccccccccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id"
So shorter column names:
type Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa struct {
tableName struct{} `sql:"a"`
ID uint64
}
type Bbbbbbbbbbbbbbbbbbbbbbbbbbbbb struct {
tableName struct{} `sql:"b"`
ID uint64
Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaID uint64 `sql:",notnull"`
}
type Ccccccccccccccccccccccccccc struct {
tableName struct{} `sql:"c"`
ID uint64
Bbbbbbbbbbbbbbbbbbbbbbbbbbbbb *Bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
BbbbbbbbbbbbbbbbbbbbbbbbbbbbbID uint64 `sql:",notnull"`
}
type Ddd struct {
tableName struct{} `sql:"d"`
ID uint64
Ccccccccccccccccccccccccccc *Ccccccccccccccccccccccccccc
CccccccccccccccccccccccccccID uint64 `sql:",notnull"`
}
Error:
pg: can't find column=ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaa in model=Ddd (try discard_unknown_columns)
This is the one that I got in my production!
SQL seems still OK
SELECT "ddd"."id",
"ddd"."ccccccccccccccccccccccccccc_id",
"ccccccccccccccccccccccccccc"."id" AS "ccccccccccccccccccccccccccc__id",
"ccccccccccccccccccccccccccc"."bbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id" AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id",
"ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."id" AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__id",
"ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id" AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id",
"ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"."id" AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa__id"
FROM d AS "ddd"
LEFT JOIN c AS "ccccccccccccccccccccccccccc"
ON "ccccccccccccccccccccccccccc"."id" = "ddd"."ccccccccccccccccccccccccccc_id"
LEFT JOIN b AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
ON "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."id" =
"ccccccccccccccccccccccccccc"."bbbbbbbbbbbbbbbbbbbbbbbbbbbbb_id"
LEFT JOIN a AS "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
ON "ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"."id" =
"ccccccccccccccccccccccccccc__bbbbbbbbbbbbbbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_id"
So when I shorten column names even more:
type Aaaaaaaaaaaaaaaaaaaaaaa struct {
tableName struct{} `sql:"a"`
ID uint64
}
type Bbbbbbbbbbbbbbbbb struct {
tableName struct{} `sql:"b"`
ID uint64
Aaaaaaaaaaaaaaaaaaaaaaa *Aaaaaaaaaaaaaaaaaaaaaaa
AaaaaaaaaaaaaaaaaaaaaaaID uint64 `sql:",notnull"`
}
type Ccccccccccccccc struct {
tableName struct{} `sql:"c"`
ID uint64
Bbbbbbbbbbbbbbbbb *Bbbbbbbbbbbbbbbbb
BbbbbbbbbbbbbbbbbID uint64 `sql:",notnull"`
}
type Ddd struct {
tableName struct{} `sql:"d"`
ID uint64
Ccccccccccccccc *Ccccccccccccccc
CccccccccccccccID uint64 `sql:",notnull"`
}
Everything just works, generated SQL:
SELECT "ddd"."id",
"ddd"."ccccccccccccccc_id",
"ccccccccccccccc"."id" AS "ccccccccccccccc__id",
"ccccccccccccccc"."bbbbbbbbbbbbbbbbb_id" AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb_id",
"ccccccccccccccc__bbbbbbbbbbbbbbbbb"."id" AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb__id",
"ccccccccccccccc__bbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaa_id" AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaa_id",
"ccccccccccccccc__bbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaa"."id" AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaa__id"
FROM d AS "ddd"
LEFT JOIN c AS "ccccccccccccccc" ON "ccccccccccccccc"."id" = "ddd"."ccccccccccccccc_id"
LEFT JOIN b AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb"
ON "ccccccccccccccc__bbbbbbbbbbbbbbbbb"."id" = "ccccccccccccccc"."bbbbbbbbbbbbbbbbb_id"
LEFT JOIN a AS "ccccccccccccccc__bbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaa"
ON "ccccccccccccccc__bbbbbbbbbbbbbbbbb__aaaaaaaaaaaaaaaaaaaaaaa"."id" =
"ccccccccccccccc__bbbbbbbbbbbbbbbbb"."aaaaaaaaaaaaaaaaaaaaaaa_id"
63 characters seems to be maximum
I don't have long column names but when I do nested joins over multiple tables that easily max out the character length.
EDIT: Version is 6.15.1
This is a PostgreSQL limit - https://til.hashrocket.com/posts/8f87c65a0a-postgresqls-max-identifier-length-is-63-bytes
Note that if it becomes too annoying we could try to use different strategy to construct shorter relation names.
No need at the moment, the workaround for this is something like this:
Ccccccccccccccc *Ccccccccccccccc `sql:"c"`
this will generate shorter names