From 0e605681b23b28c284df9f2b10426f48c071e6d7 Mon Sep 17 00:00:00 2001 From: Ariel Mashraki Date: Sun, 23 Jun 2019 01:48:26 -0700 Subject: [PATCH] quote table name on DESCRIBE statement (#7) Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/7 avoid conflicting with reserved words (e.g. "groups" became reserved word in MySQL 8.x) Reviewed By: alexsn Differential Revision: D15957279 fbshipit-source-id: b6944752c7e5f6ec37119b11cc0ab8a0d7d3a7ff --- dialect/sql/builder.go | 19 +++++++++++++++++++ dialect/sql/builder_test.go | 4 ++++ dialect/sql/schema/mysql.go | 3 ++- dialect/sql/schema/mysql_test.go | 4 ++-- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go index b6296d384..1a13c8e8f 100644 --- a/dialect/sql/builder.go +++ b/dialect/sql/builder.go @@ -257,6 +257,25 @@ func (t *TableBuilder) Query() (string, []interface{}) { return t.b.String(), t.b.args } +// DescribeBuilder is a query builder for `DESCRIBE` statement. +type DescribeBuilder struct { + b Builder + name string // table name. +} + +// Describe returns a query builder for the `DESCRIBE` statement. +// +// Describe("users") +// +func Describe(name string) *DescribeBuilder { return &DescribeBuilder{b: Builder{}, name: name} } + +// Query returns query representation of a `DESCRIBE` statement. +func (t *DescribeBuilder) Query() (string, []interface{}) { + t.b.WriteString("DESCRIBE ") + t.b.Append(t.name) + return t.b.String(), nil +} + // TableAlter is a query builder for `ALTER TABLE` statement. type TableAlter struct { b Builder diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go index ef02be266..a5b100e99 100644 --- a/dialect/sql/builder_test.go +++ b/dialect/sql/builder_test.go @@ -13,6 +13,10 @@ func TestBuilder(t *testing.T) { wantQuery string wantArgs []interface{} }{ + { + input: Describe("users"), + wantQuery: "DESCRIBE `users`", + }, { input: CreateTable("users"). Columns( diff --git a/dialect/sql/schema/mysql.go b/dialect/sql/schema/mysql.go index 3021fbf8b..58f65223b 100644 --- a/dialect/sql/schema/mysql.go +++ b/dialect/sql/schema/mysql.go @@ -131,7 +131,8 @@ func (d *MySQL) exist(ctx context.Context, tx dialect.Tx, query string, args ... // table loads the current table description from the database. func (d *MySQL) table(ctx context.Context, tx dialect.Tx, name string) (*Table, error) { rows := &sql.Rows{} - if err := tx.Query(ctx, "DESCRIBE "+name, []interface{}{}, rows); err != nil { + query, args := sql.Describe(name).Query() + if err := tx.Query(ctx, query, args, rows); err != nil { return nil, fmt.Errorf("dialect/mysql: reading table description %v", err) } defer rows.Close() diff --git a/dialect/sql/schema/mysql_test.go b/dialect/sql/schema/mysql_test.go index 802cf20a2..d6e64368f 100644 --- a/dialect/sql/schema/mysql_test.go +++ b/dialect/sql/schema/mysql_test.go @@ -151,7 +151,7 @@ func TestMySQL_Create(t *testing.T) { AND TABLE_NAME = ?`)). WithArgs("users"). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) - mock.ExpectQuery("DESCRIBE users"). + mock.ExpectQuery("DESCRIBE `users`"). WillReturnRows(sqlmock.NewRows([]string{"Field", "Type", "Null", "Key", "Default", "Extra"}). AddRow("id", "int(11)", "NO", "PRI", "NULL", "auto_increment"). AddRow("name", "varchar(255)", "NO", "YES", "NULL", "")) @@ -194,7 +194,7 @@ func TestMySQL_Create(t *testing.T) { AND TABLE_NAME = ?`)). WithArgs("users"). WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1)) - mock.ExpectQuery("DESCRIBE users"). + mock.ExpectQuery("DESCRIBE `users`"). WillReturnRows(sqlmock.NewRows([]string{"Field", "Type", "Null", "Key", "Default", "Extra"}). AddRow("id", "int(11)", "NO", "PRI", "NULL", "auto_increment"). AddRow("name", "varchar(255)", "NO", "YES", "NULL", ""))