expression:implement function password. (#3275)
This commit is contained in:
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user