Merge pull request #449 from pingcap/qiuyesuifeng/fix-382

Fix #382
This commit is contained in:
qiuyesuifeng
2015-10-26 21:36:22 +08:00
3 changed files with 65 additions and 4 deletions

View File

@ -310,14 +310,41 @@ func (t Time) RoundFrac(fsp int) (Time, error) {
return Time{Time: nt, Type: t.Type, Fsp: fsp}, nil
}
func parseDateFormat(format string) []string {
format = strings.TrimSpace(format)
start := 0
seps := []string{}
for i := 0; i < len(format); i++ {
// Date fromat must start and end with number.
if i == 0 || i == len(format)-1 {
if !unicode.IsNumber(rune(format[i])) {
return nil
}
continue
}
// Seperator is a single none-number char.
if !unicode.IsNumber(rune(format[i])) {
if !unicode.IsNumber(rune(format[i-1])) {
return nil
}
seps = append(seps, format[start:i])
start = i + 1
}
}
seps = append(seps, format[start:])
return seps
}
func parseDatetime(str string, fsp int) (Time, error) {
// Try to split str with delimiter.
// TODO: only punctuation can be the delimiter for date parts or time parts.
// But only space and T can be the delimiter between the date and time part.
seps := strings.FieldsFunc(str, func(c rune) bool {
return !unicode.IsNumber(c)
})
var (
year int
month int
@ -330,6 +357,9 @@ func parseDatetime(str string, fsp int) (Time, error) {
err error
)
seps := parseDateFormat(str)
switch len(seps) {
case 1:
// No delimiter.

View File

@ -671,3 +671,26 @@ func (s *testTimeSuite) TestDurationClock(c *C) {
c.Assert(d.MicroSecond(), Equals, t.MicroSecond)
}
}
func (s *testTimeSuite) TestParseDateFormat(c *C) {
tbl := []struct {
Input string
Result []string
}{
{"2011-11-11 10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{" 2011-11-11 10:10:10.123456 ", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"2011-11-11 10", []string{"2011", "11", "11", "10"}},
{"2011-11-11T10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"2011:11:11T10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"xx2011-11-11 10:10:10", nil},
{"T10:10:10", nil},
{"2011-11-11x", nil},
{"2011-11-11 10:10:10", nil},
{"xxx 10:10:10", nil},
}
for _, t := range tbl {
r := parseDateFormat(t.Input)
c.Assert(r, DeepEquals, t.Result)
}
}

View File

@ -1245,6 +1245,14 @@ func (s *testSessionSuite) TestResultType(c *C) {
c.Assert(fs[0].Col.FieldType.Tp, Equals, mysql.TypeString)
}
func (s *testSessionSuite) TestBuiltin(c *C) {
store := newStore(c, s.dbName)
se := newSession(c, store, s.dbName)
// Testcase for https://github.com/pingcap/tidb/issues/382
mustExecFailed(c, se, `select cast("xxx 10:10:10" as datetime)`)
}
func newSession(c *C, store kv.Storage, dbName string) Session {
se, err := CreateSession(store)
c.Assert(err, IsNil)