|
|
@@ -174,6 +174,40 @@ func TestMySQLUnsigned(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// TestMySQLBool BOOLEAN 只能从 COLUMN_TYPE 认出来。
|
|
|
+//
|
|
|
+// MySQL 的 BOOLEAN 就是 tinyint(1): information_schema 报的 DATA_TYPE 是
|
|
|
+// "tinyint"、COLUMN_TYPE 是 "tinyint(1)" —— 只看 DATA_TYPE 会走 TINYINT 分支
|
|
|
+// 收成 Int8, 而 sqltype.go 的 "BOOLEAN"/"BOOL" 分支对 MySQL 源永远不可达。
|
|
|
+// 宽度不是 1 的 tinyint 是真·小整数, tinyint(1) unsigned 能装 0..255,
|
|
|
+// 都不是真假语义, 不特判。
|
|
|
+func TestMySQLBool(t *testing.T) {
|
|
|
+ cases := []struct {
|
|
|
+ name string
|
|
|
+ dataType, columnType string
|
|
|
+ charBytes, numPrec, numScale int64
|
|
|
+ want types.FieldType
|
|
|
+ }{
|
|
|
+ // BOOLEAN 列: DATA_TYPE 只报 tinyint, 靠 COLUMN_TYPE 特判成 Bool
|
|
|
+ {"boolean", "tinyint", "tinyint(1)", 0, 3, 0, types.FieldType_Bool},
|
|
|
+ // 宽度不是 1 的 tinyint 是真·小整数
|
|
|
+ {"tinyint(4)", "tinyint", "tinyint(4)", 0, 3, 0, types.FieldType_Int8},
|
|
|
+ // tinyint(1) unsigned 能装 0..255, 不是真假语义
|
|
|
+ {"tinyint(1) unsigned", "tinyint", "tinyint(1) unsigned", 0, 3, 0, types.FieldType_Uint8},
|
|
|
+ }
|
|
|
+ for _, c := range cases {
|
|
|
+ decl := mysqlColumnDecl(c.dataType, mysqlUnsigned(c.columnType), c.charBytes, c.numPrec, c.numScale)
|
|
|
+ if mysqlBool(c.columnType) {
|
|
|
+ decl = "boolean"
|
|
|
+ }
|
|
|
+ ft, _ := inferSQLType(decl, true)
|
|
|
+ if ft != c.want {
|
|
|
+ t.Errorf("%s: COLUMN_TYPE=%q → decl %q → %v, 期望 %v",
|
|
|
+ c.name, c.columnType, decl, ft, c.want)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// TestMySQLColumnDeclUnsigned 无符号后缀必须真的走到 inferSQLType,
|
|
|
// 而且不能污染第一个括号里的容量 / 精度参数。
|
|
|
func TestMySQLColumnDeclUnsigned(t *testing.T) {
|