fix(xugu): normalize varying column types

This commit is contained in:
t8y2 2026-06-26 15:38:01 +08:00
parent 861200d664
commit f1c4604aeb
2 changed files with 43 additions and 2 deletions

View File

@ -37,7 +37,7 @@ WHERE UPPER(s.SCHEMA_NAME) = UPPER(?)
AND UPPER(t.TABLE_NAME) = UPPER(?)
AND c.CONS_TYPE = 'P'`
const xuguListColumnsSQL = `
SELECT c.COL_NAME, c.TYPE_NAME, c.NOT_NULL, c.DEF_VAL, c.COMMENTS, c.SCALE
SELECT c.COL_NAME, c.TYPE_NAME, c.NOT_NULL, c.DEF_VAL, c.COMMENTS, c.SCALE, c."VARYING"
FROM ALL_COLUMNS c
JOIN ALL_TABLES t ON t.DB_ID = c.DB_ID AND t.TABLE_ID = c.TABLE_ID
JOIN ALL_SCHEMAS s ON s.DB_ID = t.DB_ID AND s.SCHEMA_ID = t.SCHEMA_ID
@ -879,6 +879,7 @@ func (s *server) getColumns(schema, table string) ([]columnInfo, error) {
var item columnInfo
var notNull any
var scale *int
var varying any
if err := rows.Scan(
&item.Name,
&item.DataType,
@ -886,9 +887,11 @@ func (s *server) getColumns(schema, table string) ([]columnInfo, error) {
&item.ColumnDefault,
&item.Comment,
&scale,
&varying,
); err != nil {
return nil, err
}
item.DataType = normalizeXuguColumnType(item.DataType, varying)
item.IsNullable = !truthy(notNull)
item.IsPrimaryKey = primaryKeys[strings.ToUpper(item.Name)]
item.NumericPrecision, item.NumericScale, item.CharacterMaximumLength = decodeXuguScale(item.DataType, scale)
@ -1646,6 +1649,21 @@ func decodeXuguScale(dataType string, scale *int) (*int, *int, *int) {
return nil, nil, nil
}
func normalizeXuguColumnType(dataType string, varying any) string {
upper := strings.ToUpper(strings.TrimSpace(dataType))
if !truthy(varying) {
return dataType
}
switch upper {
case "CHAR":
return "VARCHAR"
case "BINARY":
return "VARBINARY"
default:
return dataType
}
}
var quotedIdentifierRegexp = regexp.MustCompile(`"([^"]+)"`)
func parseQuotedIdentifiers(value string) []string {

View File

@ -347,7 +347,7 @@ func TestPrimaryKeySQLUsesLowPrivilegeDictionary(t *testing.T) {
func TestColumnSQLUsesLowPrivilegeDictionary(t *testing.T) {
sqlText := strings.ToUpper(xuguListColumnsSQL)
for _, want := range []string{"ALL_COLUMNS", "ALL_TABLES", "ALL_SCHEMAS", "COMMENTS"} {
for _, want := range []string{"ALL_COLUMNS", "ALL_TABLES", "ALL_SCHEMAS", "COMMENTS", `"VARYING"`} {
if !strings.Contains(sqlText, want) {
t.Fatalf("column listing should query %s, got: %s", want, xuguListColumnsSQL)
}
@ -405,6 +405,29 @@ func TestDecodeXuguScale(t *testing.T) {
}
}
func TestNormalizeXuguColumnTypeUsesVaryingFlag(t *testing.T) {
tests := []struct {
name string
dataType string
varying any
want string
}{
{name: "varying char", dataType: "CHAR", varying: true, want: "VARCHAR"},
{name: "fixed char", dataType: "CHAR", varying: false, want: "CHAR"},
{name: "varying binary", dataType: "BINARY", varying: true, want: "VARBINARY"},
{name: "fixed binary", dataType: "BINARY", varying: false, want: "BINARY"},
{name: "other varying type", dataType: "NUMERIC", varying: true, want: "NUMERIC"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := normalizeXuguColumnType(tt.dataType, tt.varying); got != tt.want {
t.Fatalf("normalizeXuguColumnType(%q, %v) = %q, want %q", tt.dataType, tt.varying, got, tt.want)
}
})
}
}
func TestAppendDDLStatement(t *testing.T) {
got := appendDDLStatement("CREATE TABLE \"T\" (\"ID\" INT)\n", "CREATE INDEX \"IDX\" ON \"T\"(\"ID\");")
want := "CREATE TABLE \"T\" (\"ID\" INT);\n\nCREATE INDEX \"IDX\" ON \"T\"(\"ID\");"