Skip to content

Commit

Permalink
parser: parse decimal literal instead of float literal (pingcap#2044)
Browse files Browse the repository at this point in the history
Improves MySQL compatibility.
  • Loading branch information
coocood authored Nov 21, 2016
1 parent 8475658 commit 91050ff
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 7 deletions.
5 changes: 4 additions & 1 deletion ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,10 @@ func getDefaultValue(ctx context.Context, c *ast.ColumnOption, tp byte, fsp int)
if err != nil {
return nil, errors.Trace(err)
}
return v.GetValue(), nil
if v.IsNull() {
return nil, nil
}
return v.ToString()
}

func removeOnUpdateNowFlag(c *table.Column) {
Expand Down
2 changes: 1 addition & 1 deletion executor/show_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (s *testSuite) TestShow(c *C) {
c.Check(result.Rows(), HasLen, 1)
row = result.Rows()[0]
expectedRow = []interface{}{
"ptest", "CREATE TABLE `ptest` (\n `a` int(11) NOT NULL,\n `b` double NOT NULL DEFAULT '2',\n `c` varchar(10) NOT NULL,\n `d` time DEFAULT NULL,\n `e` timestamp NULL DEFAULT NULL,\n PRIMARY KEY (`a`),\n UNIQUE KEY `d` (`d`)\n) ENGINE=InnoDB"}
"ptest", "CREATE TABLE `ptest` (\n `a` int(11) NOT NULL,\n `b` double NOT NULL DEFAULT '2.0',\n `c` varchar(10) NOT NULL,\n `d` time DEFAULT NULL,\n `e` timestamp NULL DEFAULT NULL,\n PRIMARY KEY (`a`),\n UNIQUE KEY `d` (`d`)\n) ENGINE=InnoDB"}
for i, r := range row {
c.Check(r, Equals, expectedRow[i])
}
Expand Down
11 changes: 10 additions & 1 deletion parser/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ func (s *Scanner) Lex(v *yySymType) int {
return toInt(s, v, lit)
case floatLit:
return toFloat(s, v, lit)
case decLit:
return toDecimal(s, v, lit)
case hexLit:
return toHex(s, v, lit)
case bitLit:
Expand Down Expand Up @@ -520,9 +522,16 @@ func (s *Scanner) scanFloat(beg *Pos) (tok int, pos Pos, lit string) {
}
if ch0 == 'e' || ch0 == 'E' {
s.r.inc()
ch0 = s.r.peek()
if ch0 == '-' || ch0 == '+' {
s.r.inc()
}
s.scanDigits()
tok = floatLit
} else {
tok = decLit
}
tok, pos, lit = floatLit, *beg, s.r.data(beg)
pos, lit = *beg, s.r.data(beg)
return
}

Expand Down
6 changes: 4 additions & 2 deletions parser/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ package parser

import (
"fmt"
"unicode"

. "github.com/pingcap/check"
"github.com/pingcap/tidb/util/testleak"
"unicode"
)

var _ = Suite(&testLexerSuite{})
Expand Down Expand Up @@ -92,8 +92,10 @@ func (s *testLexerSuite) TestLiteral(c *C) {
{`""a""`, stringLit},
{`\'a\'`, int('\\')},
{`\"a\"`, int('\\')},
{"0.2314", floatLit},
{"0.2314", decLit},
{"132.313", decLit},
{"132.3e231", floatLit},
{"132.3e-231", floatLit},
{"23416", intLit},
{"123test", identifier},
{"123" + string(unicode.ReplacementChar) + "xxx", identifier},
Expand Down
3 changes: 3 additions & 0 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ import (
%token <item>

/*yy:token "1.%d" */ floatLit "floating-point literal"
/*yy:token "1.%d" */ decLit "decimal literal"
/*yy:token "%d" */ intLit "integer literal"
/*yy:token "%x" */ hexLit "hexadecimal literal"
/*yy:token "%b" */ bitLit "bit literal"
Expand Down Expand Up @@ -1276,6 +1277,7 @@ SignedLiteral:
NumLiteral:
intLit
| floatLit
| decLit


CreateIndexStmt:
Expand Down Expand Up @@ -2192,6 +2194,7 @@ Literal:
$$ = int64(1)
}
| floatLit
| decLit
| intLit
| stringLit
{
Expand Down
11 changes: 11 additions & 0 deletions parser/yy_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/hack"
)

// Error instances.
Expand Down Expand Up @@ -151,6 +152,16 @@ func toInt(l yyLexer, lval *yySymType, str string) int {
return intLit
}

func toDecimal(l yyLexer, lval *yySymType, str string) int {
dec := new(mysql.MyDecimal)
err := dec.FromString(hack.Slice(str))
if err != nil {
l.Errorf("decimal literal: %v", err)
}
lval.item = dec
return decLit
}

func toFloat(l yyLexer, lval *yySymType, str string) int {
n, err := strconv.ParseFloat(str, 64)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion server/driver_tidb.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (tc *TiDBContext) Auth(user string, auth []byte, salt []byte) bool {

// FieldList implements IContext FieldList method.
func (tc *TiDBContext) FieldList(table string) (colums []*ColumnInfo, err error) {
rs, err := tc.Execute("SELECT * FROM " + table + " LIMIT 0")
rs, err := tc.Execute("SELECT * FROM `" + table + "` LIMIT 0")
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
2 changes: 1 addition & 1 deletion util/types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ func (d *Datum) convertToMysqlDecimal(target *FieldType) (Datum, error) {
case KindString, KindBytes:
err = dec.FromString(d.GetBytes())
case KindMysqlDecimal:
dec = d.GetMysqlDecimal()
*dec = *d.GetMysqlDecimal()
case KindMysqlTime:
dec = d.GetMysqlTime().ToNumber()
case KindMysqlDuration:
Expand Down

0 comments on commit 91050ff

Please sign in to comment.