GORM Playground Link

https://github.com/go-gorm/playground/pull/614

Description

We see here that the expected output (according to the tests) when building a clause.Table{Table: "table", Alias: "alias"} using a Statement as the Builder is table alias or `table` `alias`, as produced by gorm.Statement.QuoteTo here, but that isn't actually what the SQL should look like as far as I can tell.

Rather, it should produce table AS alias or `table` AS `alias`, which would be usable in the case of e.g. clause.Insert{Table: clause.Table{Name: "table", Alias: "alias"}}, which would then produce the working SQL INSERT INTO table AS alias or INSERT INTO `table` AS `alias` as opposed to the non-functional INSERT INTO table alias or INSERT INTO `table` `alias`, which is what it currently does. In fact, we can see that this is how aliases work for columns (as opposed to tables) only several lines above in the tests.

What I expect to see

When I run

package main

import (
  "database/sql"
  "fmt"
  "time"

  "gorm.io/driver/sqlite"
  "gorm.io/gorm"
  "gorm.io/gorm/clause"
)

type User struct {
  ID           uint
  Name         string
  Email        *string
  Age          uint8
  Birthday     *time.Time
  MemberNumber sql.NullString
  ActivatedAt  sql.NullTime
  CreatedAt    time.Time
  UpdatedAt    time.Time
}

func main() {
  db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }
  insertWithTableAliasDemo(db)
}

func insertWithTableAliasDemo(db *gorm.DB) {
  // Migrate the schema
  db.AutoMigrate(&User{})

  stmt := db.Session(&gorm.Session{DryRun: true}).Clauses(clause.Insert{Table: clause.Table{Name: "Users", Alias: "u"}}).Create(&User{}).Statement
  fmt.Printf("SQL:\n%s\n", stmt.SQL.String())
}

I expect to see:

SQL:
INSERT INTO `Users` AS `u` (`name`,`email`,`age`,`birthday`,`member_number`,`activated_at`,`created_at`,`updated_at`) VALUES (?,?,?,?,?,?,?,?) RETURNING `id`

which is functional SQL that would allow the use of the alias u in other parts of the statement.

What I see instead

Instead, I see:

SQL:
INSERT INTO `Users` `u` (`name`,`email`,`age`,`birthday`,`member_number`,`activated_at`,`created_at`,`updated_at`) VALUES (?,?,?,?,?,?,?,?) RETURNING `id`

which is simply non-functional SQL.

My specific use case is that I want to be able to use the table alias in clause.OnConflict.DoUpdates because the table names I'm working with are mixed case, which means I need to manually quote them to reference them directly in the expressions for those updates when I'm using postgres (and I have to use a table name or alias to disambiguate the column from the row that failed to insert, which is available as excluded), which I do not want to do.

Comment From: tempoz

Note that I am more than willing to create a PR for this, but when I go to do so, the option to do it is grayed out: Gorm gorm.Statement.QuoteTo(writer clause.Writer, field interface{}) doesn't do what I would expect for a clause.Table with an Alias field

Comment From: xEricL

@tempoz the option is grayed out because you need to select two different branches to open a pull request Gorm gorm.Statement.QuoteTo(writer clause.Writer, field interface{}) doesn't do what I would expect for a clause.Table with an Alias field