Repository: ariga/atlas
Pull request #2028 (2023-08-27 18:57:17)

sql/mysql: support mariadb old temporal data types comments


Patch:
diff --git a/sql/mysql/convert.go b/sql/mysql/convert.go
index 7d1bd4c5..957d34e7 100644
--- a/sql/mysql/convert.go
+++ b/sql/mysql/convert.go
@@ -161,7 +161,7 @@ func ParseType(raw string) (schema.Type, error) {
 		}
 		if len(parts) > 1 && parts[1] != "unsigned" {
 			if dt.Precision, err = strconv.Atoi(parts[1]); err != nil {
-				return nil, fmt.Errorf("parse precision %q", parts[1])
+				return nil, fmt.Errorf("parse decimal precision %q", parts[1])
 			}
 		}
 		if len(parts) > 2 && parts[2] != "unsigned" {
@@ -177,7 +177,7 @@ func ParseType(raw string) (schema.Type, error) {
 		}
 		if len(parts) > 1 && parts[1] != "unsigned" {
 			if ft.Precision, err = strconv.Atoi(parts[1]); err != nil {
-				return nil, fmt.Errorf("parse precision %q", parts[1])
+				return nil, fmt.Errorf("parse double precision %q", parts[1])
 			}
 		}
 		return ft, nil
@@ -227,7 +227,7 @@ func ParseType(raw string) (schema.Type, error) {
 		if len(parts) > 1 {
 			p, err := strconv.Atoi(parts[1])
 			if err != nil {
-				return nil, fmt.Errorf("parse precision %q", parts[1])
+				return nil, fmt.Errorf("parse timestamp precision %q", parts[1])
 			}
 			tt.Precision = &p
 		}
diff --git a/sql/mysql/inspect.go b/sql/mysql/inspect.go
index 2c785468..bb1354b6 100644
--- a/sql/mysql/inspect.go
+++ b/sql/mysql/inspect.go
@@ -592,6 +592,11 @@ func (i *inspect) myDefaultExpr(c *schema.Column, x string, attr *extraAttr) sch
 
 // parseColumn returns column parts, size and signed-info from a MySQL type.
 func parseColumn(typ string) (parts []string, size int, unsigned bool, err error) {
+	// Remove MariaDB like comments embedded in the type
+	// for compatibility. For example: /* mariadb-5.3 */.
+	if i := strings.Index(typ, "/*"); i > 0 && strings.HasSuffix(strings.TrimSpace(typ), "*/") {
+		typ = strings.TrimSpace(typ[:i])
+	}
 	switch parts = strings.FieldsFunc(typ, func(r rune) bool {
 		return r == '(' || r == ')' || r == ' ' || r == ','
 	}); parts[0] {


Test patch:
diff --git a/sql/mysql/inspect_test.go b/sql/mysql/inspect_test.go
index b2d4126d..d9dbb0bf 100644
--- a/sql/mysql/inspect_test.go
+++ b/sql/mysql/inspect_test.go
@@ -10,6 +10,7 @@ import (
 	"testing"
 
 	"ariga.io/atlas/sql/internal/sqltest"
+	"ariga.io/atlas/sql/internal/sqlx"
 	"ariga.io/atlas/sql/schema"
 
 	"github.com/DATA-DOG/go-sqlmock"
@@ -161,14 +162,17 @@ func TestDriver_InspectTable(t *testing.T) {
 				m.ExpectQuery(queryColumns).
 					WithArgs("public", "users").
 					WillReturnRows(sqltest.Rows(`
-+------------+----------------+------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
-| table_name |  column_name   | column_type                  | column_comment       | is_nullable | column_key | column_default | extra          | character_set_name | collation_name | generation_expression     |
-+------------+----------------+------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
-| users      |  id            | bigint(20)                   |                      | NO          | PRI        | NULL           |                | NULL               | NULL           | NULL                      |
-| users      |  tiny_int      | tinyint(1)                   |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
-| users      |  longtext      | longtext                     |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
-| users      |  jsonc         | longtext                     |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
-+------------+----------------+------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
++------------+----------------+-------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
+| table_name |  column_name   | column_type                   | column_comment       | is_nullable | column_key | column_default | extra          | character_set_name | collation_name | generation_expression     |
++------------+----------------+-------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
+| users      |  id            | bigint(20)                    |                      | NO          | PRI        | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  tiny_int      | tinyint(1)                    |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  longtext      | longtext                      |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  jsonc         | longtext                      |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  dt0           | datetime /* mariadb-5.3 */    |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  dt1           | datetime(6) /* mariadb-5.3 */ |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
+| users      |  dt2           | time(1) /* mariadb-5.3 */     |                      | NO          |            | NULL           |                | NULL               | NULL           | NULL                      |
++------------+----------------+-------------------------------+----------------------+-------------+------------+----------------+----------------+--------------------+----------------+---------------------------+
 `))
 				m.ExpectQuery(queryIndexes).
 					WillReturnRows(sqlmock.NewRows([]string{"table_name", "index_name", "column_name", "non_unique", "key_part", "expression"}))
@@ -192,6 +196,9 @@ func TestDriver_InspectTable(t *testing.T) {
 					{Name: "tiny_int", Type: &schema.ColumnType{Raw: "tinyint(1)", Type: &schema.BoolType{T: "bool"}}},
 					{Name: "longtext", Type: &schema.ColumnType{Raw: "longtext", Type: &schema.StringType{T: "longtext"}}},
 					{Name: "jsonc", Type: &schema.ColumnType{Raw: "json", Type: &schema.JSONType{T: "json"}}},
+					{Name: "dt0", Type: &schema.ColumnType{Raw: "datetime /* mariadb-5.3 */", Type: &schema.TimeType{T: "datetime"}}},
+					{Name: "dt1", Type: &schema.ColumnType{Raw: "datetime(6) /* mariadb-5.3 */", Type: &schema.TimeType{T: "datetime", Precision: sqlx.P(6)}}},
+					{Name: "dt2", Type: &schema.ColumnType{Raw: "time(1) /* mariadb-5.3 */", Type: &schema.TimeType{T: "time", Precision: sqlx.P(1)}}},
 				}, t.Columns)
 				require.EqualValues([]schema.Attr{
 					&schema.Check{Name: "users_chk_1", Expr: `longtext <> '\'\'""'`},