expression:implement function password. (#3275)

This commit is contained in:
louishust
2017-06-02 15:08:40 +08:00
committed by Shen Li
parent 01dd725090
commit e294500a17
4 changed files with 49 additions and 1 deletions

View File

@ -28,6 +28,7 @@ import (
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/encrypt"
"github.com/pingcap/tidb/util/types"
)
@ -395,7 +396,29 @@ type builtinPasswordSig struct {
// eval evals a builtinPasswordSig.
// See https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_password
func (b *builtinPasswordSig) eval(row []types.Datum) (d types.Datum, err error) {
return d, errFunctionNotExists.GenByArgs("PASSWORD")
args, err := b.evalArgs(row)
if err != nil {
return d, errors.Trace(err)
}
arg := args[0]
if arg.IsNull() {
d.SetString("")
return d, nil
}
pass, err := args[0].ToString()
if err != nil {
return d, errors.Trace(err)
}
if len(pass) == 0 {
d.SetString("")
return d, nil
}
d.SetString(util.EncodePassword(pass))
return d, nil
}
type randomBytesFunctionClass struct {

View File

@ -300,3 +300,24 @@ func (s *testEvaluatorSuite) TestUncompressLength(c *C) {
c.Assert(out.GetInt64(), Equals, test.expect)
}
}
func (s *testEvaluatorSuite) TestPassword(c *C) {
defer testleak.AfterTest(c)()
tests := []struct {
in interface{}
expect interface{}
}{
{nil, string("")},
{string(""), string("")},
{string("abc"), string("*0D3CED9BEC10A777AEC23CCC353A8C08A633045E")},
}
fc := funcs[ast.PasswordFunc]
for _, test := range tests {
arg := types.NewDatum(test.in)
f, err := fc.getFunction(datumsToConstants([]types.Datum{arg}), s.ctx)
c.Assert(err, IsNil)
out, err := f.eval(nil)
c.Assert(err, IsNil)
c.Assert(out.GetString(), Equals, test.expect)
}
}

View File

@ -431,6 +431,9 @@ func (v *typeInferrer) handleFuncCallExpr(x *ast.FuncCallExpr) {
tp = x.Args[0].GetType()
case ast.RowFunc:
tp = x.Args[0].GetType()
case ast.PasswordFunc:
tp = types.NewFieldType(mysql.TypeVarString)
chs = v.defaultCharset
default:
tp = types.NewFieldType(mysql.TypeUnspecified)
}

View File

@ -329,6 +329,7 @@ func (ts *testTypeInferrerSuite) TestInferType(c *C) {
{`inet6_ntoa(inet6_aton('FE80::AAAA:0000:00C2:0002'))`, mysql.TypeVarString,
charset.CharsetUTF8, 0},
{`is_ipv4_mapped(c_varbinary)`, mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag},
{`password("abc")`, mysql.TypeVarString, charset.CharsetUTF8, 0},
{`json_type('3')`, mysql.TypeVarString, charset.CharsetUTF8, 0},
}
for _, tt := range tests {