diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index 3e8ef3038..c7d98cdbc 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -42,10 +42,12 @@ func (m *Model) All(where ...interface{}) (Result, error) { } conditionWhere += softDeletingCondition } + // DO NOT quote the m.fields where, in case of fields like: + // DISTINCT t.user_id uid return m.doGetAll( fmt.Sprintf( "SELECT %s FROM %s%s", - m.db.QuoteString(m.fields), + m.fields, m.tables, conditionWhere+conditionExtra, ), @@ -249,7 +251,9 @@ func (m *Model) Count(where ...interface{}) (int, error) { } countFields := "COUNT(1)" if m.fields != "" && m.fields != "*" { - countFields = fmt.Sprintf(`COUNT(%s)`, m.db.QuoteString(m.fields)) + // DO NOT quote the m.fields here, in case of fields like: + // DISTINCT t.user_id uid + countFields = fmt.Sprintf(`COUNT(%s)`, m.fields) } var ( softDeletingCondition = m.getConditionForSoftDeleting() diff --git a/database/gdb/gdb_unit_z_mysql_model_test.go b/database/gdb/gdb_unit_z_mysql_model_test.go index f37a9fd61..e4cf67f2d 100644 --- a/database/gdb/gdb_unit_z_mysql_model_test.go +++ b/database/gdb/gdb_unit_z_mysql_model_test.go @@ -2297,3 +2297,30 @@ func Test_Model_Having(t *testing.T) { t.Assert(len(all), 1) }) } + +func Test_Model_Distinct(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + all, err := db.Table(table, "t").Fields("distinct t.id").Where("id > 1").Having("id > 8").All() + t.Assert(err, nil) + t.Assert(len(all), 2) + }) +} + +func Test_Model_Min_Max(t *testing.T) { + table := createInitTable() + defer dropTable(table) + + gtest.C(t, func(t *gtest.T) { + value, err := db.Table(table, "t").Fields("min(t.id)").Where("id > 1").Value() + t.Assert(err, nil) + t.Assert(value.Int(), 2) + }) + gtest.C(t, func(t *gtest.T) { + value, err := db.Table(table, "t").Fields("max(t.id)").Where("id > 1").Value() + t.Assert(err, nil) + t.Assert(value.Int(), 10) + }) +} diff --git a/errors/gerror/gerror.go b/errors/gerror/gerror.go index c9df839ec..11c6e55ba 100644 --- a/errors/gerror/gerror.go +++ b/errors/gerror/gerror.go @@ -11,15 +11,17 @@ import ( "fmt" ) +// ApiStack is the interface for Stack feature. type ApiStack interface { Stack() string } +// ApiCause is the interface for Cause feature. type ApiCause interface { Cause() error } -// New returns an error that formats as the given text. +// New creates and returns an error which is formatted from given text. func New(text string) error { if text == "" { return nil @@ -30,7 +32,7 @@ func New(text string) error { } } -// Newf returns an error that formats as the given text. +// Newf returns an error that formats as the given format and args. func Newf(format string, args ...interface{}) error { if format == "" { return nil @@ -56,7 +58,7 @@ func Wrap(err error, text string) error { // Wrapf returns an error annotating err with a stack trace // at the point Wrapf is called, and the format specifier. -// It returns nil if given err is nil. +// It returns nil if given is nil. func Wrapf(err error, format string, args ...interface{}) error { if err == nil { return nil @@ -68,7 +70,7 @@ func Wrapf(err error, format string, args ...interface{}) error { } } -// Cause returns the root cause error. +// Cause returns the root cause error of . func Cause(err error) error { if err != nil { if e, ok := err.(ApiCause); ok { @@ -79,7 +81,7 @@ func Cause(err error) error { } // Stack returns the stack callers as string. -// It returns an empty string id the does not support stacks. +// It returns an empty string if the does not support stacks. func Stack(err error) string { if err == nil { return "" diff --git a/errors/gerror/gerror_error.go b/errors/gerror/gerror_error.go index 7a743014a..43a99a172 100644 --- a/errors/gerror/gerror_error.go +++ b/errors/gerror/gerror_error.go @@ -94,7 +94,7 @@ func (err *Error) Format(s fmt.State, verb rune) { } // Stack returns the stack callers as string. -// It returns an empty string id the does not support stacks. +// It returns an empty string if the does not support stacks. func (err *Error) Stack() string { if err == nil { return "" diff --git a/errors/gerror/gerror_test.go b/errors/gerror/gerror_test.go index e89662638..9b7346ce9 100644 --- a/errors/gerror/gerror_test.go +++ b/errors/gerror/gerror_test.go @@ -15,10 +15,6 @@ import ( "github.com/gogf/gf/test/gtest" ) -func interfaceNil() interface{} { - return nil -} - func nilError() error { return nil }