mirror of https://github.com/go-gorm/gorm.git
fix: 'type XXXX int' will print wrong sql to terminal (#6917)
Co-authored-by: 王泽平 <zeping.wang@yo-star.com>
This commit is contained in:
parent
0d6c5345f3
commit
956f7ce843
|
@ -34,6 +34,19 @@ var convertibleTypes = []reflect.Type{reflect.TypeOf(time.Time{}), reflect.TypeO
|
||||||
// RegEx matches only numeric values
|
// RegEx matches only numeric values
|
||||||
var numericPlaceholderRe = regexp.MustCompile(`\$\d+\$`)
|
var numericPlaceholderRe = regexp.MustCompile(`\$\d+\$`)
|
||||||
|
|
||||||
|
func isNumeric(k reflect.Kind) bool {
|
||||||
|
switch k {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return true
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return true
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ExplainSQL generate SQL string with given parameters, the generated SQL is expected to be used in logger, execute it might introduce a SQL injection vulnerability
|
// ExplainSQL generate SQL string with given parameters, the generated SQL is expected to be used in logger, execute it might introduce a SQL injection vulnerability
|
||||||
func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, avars ...interface{}) string {
|
func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, avars ...interface{}) string {
|
||||||
var (
|
var (
|
||||||
|
@ -110,6 +123,12 @@ func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, a
|
||||||
convertParams(v, idx)
|
convertParams(v, idx)
|
||||||
} else if rv.Kind() == reflect.Ptr && !rv.IsZero() {
|
} else if rv.Kind() == reflect.Ptr && !rv.IsZero() {
|
||||||
convertParams(reflect.Indirect(rv).Interface(), idx)
|
convertParams(reflect.Indirect(rv).Interface(), idx)
|
||||||
|
} else if isNumeric(rv.Kind()) {
|
||||||
|
if rv.CanInt() || rv.CanUint() {
|
||||||
|
vars[idx] = fmt.Sprintf("%d", rv.Interface())
|
||||||
|
} else {
|
||||||
|
vars[idx] = fmt.Sprintf("%.6f", rv.Interface())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, t := range convertibleTypes {
|
for _, t := range convertibleTypes {
|
||||||
if rv.Type().ConvertibleTo(t) {
|
if rv.Type().ConvertibleTo(t) {
|
||||||
|
|
|
@ -37,14 +37,18 @@ func format(v []byte, escaper string) string {
|
||||||
func TestExplainSQL(t *testing.T) {
|
func TestExplainSQL(t *testing.T) {
|
||||||
type role string
|
type role string
|
||||||
type password []byte
|
type password []byte
|
||||||
|
type intType int
|
||||||
|
type floatType float64
|
||||||
var (
|
var (
|
||||||
tt = now.MustParse("2020-02-23 11:10:10")
|
tt = now.MustParse("2020-02-23 11:10:10")
|
||||||
myrole = role("admin")
|
myrole = role("admin")
|
||||||
pwd = password("pass")
|
pwd = password("pass")
|
||||||
jsVal = []byte(`{"Name":"test","Val":"test"}`)
|
jsVal = []byte(`{"Name":"test","Val":"test"}`)
|
||||||
js = JSON(jsVal)
|
js = JSON(jsVal)
|
||||||
esVal = []byte(`{"Name":"test","Val":"test"}`)
|
esVal = []byte(`{"Name":"test","Val":"test"}`)
|
||||||
es = ExampleStruct{Name: "test", Val: "test"}
|
es = ExampleStruct{Name: "test", Val: "test"}
|
||||||
|
intVal intType = 1
|
||||||
|
floatVal floatType = 1.23
|
||||||
)
|
)
|
||||||
|
|
||||||
results := []struct {
|
results := []struct {
|
||||||
|
@ -107,6 +111,18 @@ func TestExplainSQL(t *testing.T) {
|
||||||
Vars: []interface{}{"jinzhu", 1, float32(999.99), true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, &js, &es},
|
Vars: []interface{}{"jinzhu", 1, float32(999.99), true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, &js, &es},
|
||||||
Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.99, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.""com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)),
|
Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.99, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.""com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, int_val) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
NumericRegexp: nil,
|
||||||
|
Vars: []interface{}{"jinzhu?", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, intVal},
|
||||||
|
Result: `create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, int_val) values ("jinzhu?", 1, 999.99, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.""com", "admin", "pass", 1)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, float_val) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
NumericRegexp: nil,
|
||||||
|
Vars: []interface{}{"jinzhu?", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, floatVal},
|
||||||
|
Result: `create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, float_val) values ("jinzhu?", 1, 999.99, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.""com", "admin", "pass", 1.230000)`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx, r := range results {
|
for idx, r := range results {
|
||||||
|
|
Loading…
Reference in New Issue