From 7aff5dd6932468a2369504a48b3293e58be6e2ae Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 24 Jun 2020 21:00:48 +0800 Subject: [PATCH 1/5] unsigned --- dialects/sqlite3.go | 34 ++++++++++++++++++++++++++++++++++ integrations/types_test.go | 22 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/dialects/sqlite3.go b/dialects/sqlite3.go index 62a38397..fb38ebf6 100644 --- a/dialects/sqlite3.go +++ b/dialects/sqlite3.go @@ -149,6 +149,40 @@ var ( Suffix: '`', IsReserved: schemas.AlwaysReserve, } + + sqlite3Types = map[string]int{ + "INT": schemas.NUMERIC_TYPE, + "INTEGER": schemas.NUMERIC_TYPE, + "TINYINT": schemas.NUMERIC_TYPE, + "SMALLINT": schemas.NUMERIC_TYPE, + "MEDIUMINT": schemas.NUMERIC_TYPE, + "BIGINT": schemas.NUMERIC_TYPE, + "UNSIGNED BIG INT": schemas.NUMERIC_TYPE, + "INT2": schemas.NUMERIC_TYPE, + "INT8": schemas.NUMERIC_TYPE, + + "REAL": schemas.NUMERIC_TYPE, + "DOUBLE": schemas.NUMERIC_TYPE, + "DOUBLE PRECISION": schemas.NUMERIC_TYPE, + "FLOAT": schemas.NUMERIC_TYPE, + "NUMERIC": schemas.NUMERIC_TYPE, + "DECIMAL": schemas.NUMERIC_TYPE, + "BOOLEAN": schemas.NUMERIC_TYPE, + + "CHARACTER": schemas.TEXT_TYPE, + "VARCHAR": schemas.TEXT_TYPE, + "VARYING CHARACTER": schemas.TEXT_TYPE, + "NCHAR": schemas.TEXT_TYPE, + "NATIVE CHARACTER": schemas.TEXT_TYPE, + "NVARCHAR": schemas.TEXT_TYPE, + "TEXT": schemas.TEXT_TYPE, + "CLOB": schemas.TEXT_TYPE, + + "BLOB": schemas.BLOB_TYPE, + + "DATE": schemas.TIME_TYPE, + "DATETIME": schemas.TIME_TYPE, + } ) type sqlite3 struct { diff --git a/integrations/types_test.go b/integrations/types_test.go index 112308f3..1a4faa42 100644 --- a/integrations/types_test.go +++ b/integrations/types_test.go @@ -375,3 +375,25 @@ func TestCustomType2(t *testing.T) { fmt.Println(users) } + +func TestUnsigned(t *testing.T) { + type MyUnsignedStruct struct { + Id uint64 + } + + assert.NoError(t, PrepareEngine()) + assertSync(t, new(MyUnsignedStruct)) + + tables, err := testEngine.DBMetas() + assert.NoError(t, err) + assert.EqualValues(t, 1, len(tables)) + assert.EqualValues(t, 1, len(tables[0].Columns())) + + switch testEngine.Dialect().URI().DBType { + case schemas.SQLITE: + assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name) + case schemas.MYSQL: + assert.EqualValues(t, "unsigned int", tables[0].Columns()[0].SQLType.Name) + } + +} -- 2.40.1 From 3ea0cca87f32d435dff1445c251b88e894275aeb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 10 Apr 2021 10:50:15 +0800 Subject: [PATCH 2/5] Fix tests --- dialects/mssql.go | 4 ++-- dialects/mysql.go | 29 ++++++++++++++++++--------- dialects/postgres.go | 4 ++-- dialects/sqlite3.go | 37 ++--------------------------------- integrations/types_test.go | 9 +++++++-- schemas/type.go | 40 +++++++++++++++++++++++--------------- 6 files changed, 57 insertions(+), 66 deletions(-) diff --git a/dialects/mssql.go b/dialects/mssql.go index 083fb65d..15d1cd06 100644 --- a/dialects/mssql.go +++ b/dialects/mssql.go @@ -284,7 +284,7 @@ func (db *mssql) SQLType(c *schemas.Column) string { case schemas.TimeStampz: res = "DATETIMEOFFSET" c.Length = 7 - case schemas.MediumInt: + case schemas.MediumInt, schemas.UnsignedInt: res = schemas.Int case schemas.Text, schemas.MediumText, schemas.TinyText, schemas.LongText, schemas.Json: res = db.defaultVarchar + "(MAX)" @@ -296,7 +296,7 @@ func (db *mssql) SQLType(c *schemas.Column) string { case schemas.TinyInt: res = schemas.TinyInt c.Length = 0 - case schemas.BigInt: + case schemas.BigInt, schemas.UnsignedBigInt: res = schemas.BigInt c.Length = 0 case schemas.NVarchar: diff --git a/dialects/mysql.go b/dialects/mysql.go index 769e30b1..2b530daf 100644 --- a/dialects/mysql.go +++ b/dialects/mysql.go @@ -254,6 +254,10 @@ func (db *mysql) SQLType(c *schemas.Column) string { c.Length = 40 case schemas.Json: res = schemas.Text + case schemas.UnsignedInt: + res = schemas.Int + case schemas.UnsignedBigInt: + res = schemas.BigInt default: res = t } @@ -271,6 +275,11 @@ func (db *mysql) SQLType(c *schemas.Column) string { } else if hasLen1 { res += "(" + strconv.Itoa(c.Length) + ")" } + + if c.SQLType.Name == schemas.UnsignedBigInt || c.SQLType.Name == schemas.UnsignedInt { + res += " UNSIGNED" + } + return res } @@ -331,16 +340,16 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName col := new(schemas.Column) col.Indexes = make(map[string]int) - var columnName, isNullable, colType, colKey, extra, comment string - var alreadyQuoted bool + var columnName, nullableStr, colType, colKey, extra, comment string + var alreadyQuoted, isUnsigned bool var colDefault *string - err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted) + err = rows.Scan(&columnName, &nullableStr, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted) if err != nil { return nil, nil, err } col.Name = strings.Trim(columnName, "` ") col.Comment = comment - if "YES" == isNullable { + if nullableStr == "YES" { col.Nullable = true } @@ -351,6 +360,11 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName col.DefaultIsEmpty = true } + fields := strings.Fields(colType) + if len(fields) == 2 && fields[1] == "unsigned" { + isUnsigned = true + } + colType = fields[0] cts := strings.Split(colType, "(") colName := cts[0] // Remove the /* mariadb-5.3 */ suffix from coltypes @@ -389,11 +403,8 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName } } } - if colType == "FLOAT UNSIGNED" { - colType = "FLOAT" - } - if colType == "DOUBLE UNSIGNED" { - colType = "DOUBLE" + if isUnsigned { + colType = "UNSIGNED " + colType } col.Length = len1 col.Length2 = len2 diff --git a/dialects/postgres.go b/dialects/postgres.go index a2c0de74..6c07ba6a 100644 --- a/dialects/postgres.go +++ b/dialects/postgres.go @@ -833,12 +833,12 @@ func (db *postgres) SQLType(c *schemas.Column) string { case schemas.Bit: res = schemas.Boolean return res - case schemas.MediumInt, schemas.Int, schemas.Integer: + case schemas.MediumInt, schemas.Int, schemas.Integer, schemas.UnsignedInt: if c.IsAutoIncrement { return schemas.Serial } return schemas.Integer - case schemas.BigInt: + case schemas.BigInt, schemas.UnsignedBigInt: if c.IsAutoIncrement { return schemas.BigSerial } diff --git a/dialects/sqlite3.go b/dialects/sqlite3.go index fb38ebf6..82683606 100644 --- a/dialects/sqlite3.go +++ b/dialects/sqlite3.go @@ -149,40 +149,6 @@ var ( Suffix: '`', IsReserved: schemas.AlwaysReserve, } - - sqlite3Types = map[string]int{ - "INT": schemas.NUMERIC_TYPE, - "INTEGER": schemas.NUMERIC_TYPE, - "TINYINT": schemas.NUMERIC_TYPE, - "SMALLINT": schemas.NUMERIC_TYPE, - "MEDIUMINT": schemas.NUMERIC_TYPE, - "BIGINT": schemas.NUMERIC_TYPE, - "UNSIGNED BIG INT": schemas.NUMERIC_TYPE, - "INT2": schemas.NUMERIC_TYPE, - "INT8": schemas.NUMERIC_TYPE, - - "REAL": schemas.NUMERIC_TYPE, - "DOUBLE": schemas.NUMERIC_TYPE, - "DOUBLE PRECISION": schemas.NUMERIC_TYPE, - "FLOAT": schemas.NUMERIC_TYPE, - "NUMERIC": schemas.NUMERIC_TYPE, - "DECIMAL": schemas.NUMERIC_TYPE, - "BOOLEAN": schemas.NUMERIC_TYPE, - - "CHARACTER": schemas.TEXT_TYPE, - "VARCHAR": schemas.TEXT_TYPE, - "VARYING CHARACTER": schemas.TEXT_TYPE, - "NCHAR": schemas.TEXT_TYPE, - "NATIVE CHARACTER": schemas.TEXT_TYPE, - "NVARCHAR": schemas.TEXT_TYPE, - "TEXT": schemas.TEXT_TYPE, - "CLOB": schemas.TEXT_TYPE, - - "BLOB": schemas.BLOB_TYPE, - - "DATE": schemas.TIME_TYPE, - "DATETIME": schemas.TIME_TYPE, - } ) type sqlite3 struct { @@ -227,7 +193,8 @@ func (db *sqlite3) SQLType(c *schemas.Column) string { case schemas.Char, schemas.Varchar, schemas.NVarchar, schemas.TinyText, schemas.Text, schemas.MediumText, schemas.LongText, schemas.Json: return schemas.Text - case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int, schemas.Integer, schemas.BigInt: + case schemas.Bit, schemas.TinyInt, schemas.SmallInt, schemas.MediumInt, schemas.Int, schemas.Integer, schemas.BigInt, + schemas.UnsignedBigInt, schemas.UnsignedInt: return schemas.Integer case schemas.Float, schemas.Double, schemas.Real: return schemas.Real diff --git a/integrations/types_test.go b/integrations/types_test.go index 1a4faa42..d0357d6b 100644 --- a/integrations/types_test.go +++ b/integrations/types_test.go @@ -393,7 +393,12 @@ func TestUnsigned(t *testing.T) { case schemas.SQLITE: assert.EqualValues(t, "INTEGER", tables[0].Columns()[0].SQLType.Name) case schemas.MYSQL: - assert.EqualValues(t, "unsigned int", tables[0].Columns()[0].SQLType.Name) + assert.EqualValues(t, "UNSIGNED BIGINT", tables[0].Columns()[0].SQLType.Name) + case schemas.POSTGRES: + assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name) + case schemas.MSSQL: + assert.EqualValues(t, "BIGINT", tables[0].Columns()[0].SQLType.Name) + default: + assert.False(t, true, "Unsigned is not implemented") } - } diff --git a/schemas/type.go b/schemas/type.go index f0ede296..040bd942 100644 --- a/schemas/type.go +++ b/schemas/type.go @@ -73,13 +73,15 @@ func (s *SQLType) IsXML() bool { } var ( - Bit = "BIT" - TinyInt = "TINYINT" - SmallInt = "SMALLINT" - MediumInt = "MEDIUMINT" - Int = "INT" - Integer = "INTEGER" - BigInt = "BIGINT" + Bit = "BIT" + TinyInt = "TINYINT" + SmallInt = "SMALLINT" + MediumInt = "MEDIUMINT" + Int = "INT" + Integer = "INTEGER" + BigInt = "BIGINT" + UnsignedInt = "UNSIGNED INT" + UnsignedBigInt = "UNSIGNED BIGINT" Enum = "ENUM" Set = "SET" @@ -136,13 +138,15 @@ var ( Array = "ARRAY" SqlTypes = map[string]int{ - Bit: NUMERIC_TYPE, - TinyInt: NUMERIC_TYPE, - SmallInt: NUMERIC_TYPE, - MediumInt: NUMERIC_TYPE, - Int: NUMERIC_TYPE, - Integer: NUMERIC_TYPE, - BigInt: NUMERIC_TYPE, + Bit: NUMERIC_TYPE, + TinyInt: NUMERIC_TYPE, + SmallInt: NUMERIC_TYPE, + MediumInt: NUMERIC_TYPE, + Int: NUMERIC_TYPE, + Integer: NUMERIC_TYPE, + BigInt: NUMERIC_TYPE, + UnsignedInt: NUMERIC_TYPE, + UnsignedBigInt: NUMERIC_TYPE, Enum: TEXT_TYPE, Set: TEXT_TYPE, @@ -280,10 +284,14 @@ var ( // Type2SQLType generate SQLType acorrding Go's type func Type2SQLType(t reflect.Type) (st SQLType) { switch k := t.Kind(); k { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: st = SQLType{Int, 0, 0} - case reflect.Int64, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: + st = SQLType{UnsignedInt, 0, 0} + case reflect.Int64: st = SQLType{BigInt, 0, 0} + case reflect.Uint64: + st = SQLType{UnsignedBigInt, 0, 0} case reflect.Float32: st = SQLType{Float, 0, 0} case reflect.Float64: -- 2.40.1 From 8c2807fa886e461f445be8abcad396d857091245 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 10 Apr 2021 13:13:39 +0800 Subject: [PATCH 3/5] Upgrade mssql --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index b9eec3a0..5e073207 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module xorm.io/xorm -go 1.11 +go 1.13 require ( - github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc + github.com/denisenkom/go-mssqldb v0.9.0 github.com/go-sql-driver/mysql v1.5.0 github.com/lib/pq v1.7.0 github.com/mattn/go-sqlite3 v1.14.6 diff --git a/go.sum b/go.sum index 7c72c699..230c16aa 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGq gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg= -github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk= +github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= -- 2.40.1 From 2c6d47ca37204f31e59d3b9933902bc9cc4c9c14 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 10 Apr 2021 13:52:17 +0800 Subject: [PATCH 4/5] Fix tidb test --- schemas/type.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/schemas/type.go b/schemas/type.go index 040bd942..6b50d184 100644 --- a/schemas/type.go +++ b/schemas/type.go @@ -74,13 +74,14 @@ func (s *SQLType) IsXML() bool { var ( Bit = "BIT" + UnsignedBit = "UNSIGNED BIT" TinyInt = "TINYINT" SmallInt = "SMALLINT" MediumInt = "MEDIUMINT" Int = "INT" + UnsignedInt = "UNSIGNED INT" Integer = "INTEGER" BigInt = "BIGINT" - UnsignedInt = "UNSIGNED INT" UnsignedBigInt = "UNSIGNED BIGINT" Enum = "ENUM" @@ -139,13 +140,14 @@ var ( SqlTypes = map[string]int{ Bit: NUMERIC_TYPE, + UnsignedBit: NUMERIC_TYPE, TinyInt: NUMERIC_TYPE, SmallInt: NUMERIC_TYPE, MediumInt: NUMERIC_TYPE, Int: NUMERIC_TYPE, + UnsignedInt: NUMERIC_TYPE, Integer: NUMERIC_TYPE, BigInt: NUMERIC_TYPE, - UnsignedInt: NUMERIC_TYPE, UnsignedBigInt: NUMERIC_TYPE, Enum: TEXT_TYPE, -- 2.40.1 From dc379b5c3a7bdd391d18ea454699c63e00e62e6c Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 11 Apr 2021 14:02:39 +0800 Subject: [PATCH 5/5] Fix cockroach test --- dialects/postgres.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dialects/postgres.go b/dialects/postgres.go index 6c07ba6a..2b234c66 100644 --- a/dialects/postgres.go +++ b/dialects/postgres.go @@ -1052,6 +1052,10 @@ WHERE n.nspname= s.table_schema AND c.relkind = 'r'::char AND c.relname = $1%s A } } + if colDefault != nil && *colDefault == "unique_rowid()" { // ignore the system column added by cockroach + continue + } + col.Name = strings.Trim(colName, `" `) if colDefault != nil { -- 2.40.1