Correct default detection in MariaDB >= 10.2.7 (#1778)

try again ci

Signed-off-by: Andrew Thornton <art27@cantab.net>

try again ci

Signed-off-by: Andrew Thornton <art27@cantab.net>

tidy up appearance of the alreadyQuoted SQL string

Signed-off-by: Andrew Thornton <art27@cantab.net>

Merge remote-tracking branch 'origin/master' into fix-defaults-sync2-mysql

Try MariaDB 10.4

Signed-off-by: Andrew Thornton <art27@cantab.net>

fix drone

Signed-off-by: Andrew Thornton <art27@cantab.net>

Correct default detection in MariaDB >= 10.2.7

MariaDB in version 10.2.7 changed the reporting of COLUMN_DEFAULT in
INFORMATION_SCHEMA.COLUMNS to quote string values.

This PR adds a version detection test to the columns query.

References: https://jira.mariadb.org/browse/MDEV-13132
References: https://jira.mariadb.org/browse/MDEV-15390

Signed-off-by: Andrew Thornton <art27@cantab.net>

Reviewed-on: https://gitea.com/xorm/xorm/pulls/1778
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
Andrew Thornton 2020-09-02 12:37:16 +00:00 committed by Lunny Xiao
parent 76d6b9fdf5
commit f8c91ec4a3
2 changed files with 45 additions and 5 deletions

View File

@ -110,6 +110,25 @@ steps:
- push
- pull_request
- name: test-mariadb
image: golang:1.12
environment:
GO111MODULE: "on"
GOPROXY: "https://goproxy.cn"
TEST_MYSQL_HOST: mariadb
TEST_MYSQL_CHARSET: utf8mb4
TEST_MYSQL_DBNAME: xorm_test
TEST_MYSQL_USERNAME: root
TEST_MYSQL_PASSWORD:
commands:
- make test-mysql
- TEST_CACHE_ENABLE=true make test-mysql
- TEST_QUOTE_POLICY=reserved make test-mysql
when:
event:
- push
- pull_request
- name: test-postgres
pull: default
image: golang:1.12
@ -259,6 +278,18 @@ services:
- tag
- pull_request
- name: mariadb
pull: default
image: mariadb:10.4
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: xorm_test
when:
event:
- push
- tag
- pull_request
- name: pgsql
pull: default
image: postgres:9.5

View File

@ -307,8 +307,16 @@ func (db *mysql) AddColumnSQL(tableName string, col *schemas.Column) string {
func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName string) ([]string, map[string]*schemas.Column, error) {
args := []interface{}{db.uri.DBName, tableName}
alreadyQuoted := "(INSTR(VERSION(), 'maria') > 0 && " +
"(SUBSTRING_INDEX(VERSION(), '.', 1) > 10 || " +
"(SUBSTRING_INDEX(VERSION(), '.', 1) = 10 && " +
"(SUBSTRING_INDEX(SUBSTRING(VERSION(), 4), '.', 1) > 2 || " +
"(SUBSTRING_INDEX(SUBSTRING(VERSION(), 4), '.', 1) = 2 && " +
"SUBSTRING_INDEX(SUBSTRING(VERSION(), 6), '-', 1) >= 7)))))"
s := "SELECT `COLUMN_NAME`, `IS_NULLABLE`, `COLUMN_DEFAULT`, `COLUMN_TYPE`," +
" `COLUMN_KEY`, `EXTRA`,`COLUMN_COMMENT` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" +
" `COLUMN_KEY`, `EXTRA`, `COLUMN_COMMENT`, " +
alreadyQuoted + " AS NEEDS_QUOTE " +
"FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ?" +
" ORDER BY `COLUMNS`.ORDINAL_POSITION"
rows, err := queryer.QueryContext(ctx, s, args...)
@ -324,8 +332,9 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
col.Indexes = make(map[string]int)
var columnName, isNullable, colType, colKey, extra, comment string
var alreadyQuoted bool
var colDefault *string
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment)
err = rows.Scan(&columnName, &isNullable, &colDefault, &colType, &colKey, &extra, &comment, &alreadyQuoted)
if err != nil {
return nil, nil, err
}
@ -335,7 +344,7 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
col.Nullable = true
}
if colDefault != nil {
if colDefault != nil && (!alreadyQuoted || *colDefault != "NULL") {
col.Default = *colDefault
col.DefaultIsEmpty = false
} else {
@ -404,9 +413,9 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
}
if !col.DefaultIsEmpty {
if col.SQLType.IsText() {
if !alreadyQuoted && col.SQLType.IsText() {
col.Default = "'" + col.Default + "'"
} else if col.SQLType.IsTime() && col.Default != "CURRENT_TIMESTAMP" {
} else if col.SQLType.IsTime() && !alreadyQuoted && col.Default != "CURRENT_TIMESTAMP" {
col.Default = "'" + col.Default + "'"
}
}