Skip to content

Commit

Permalink
expression: do not set ParseToJSONFlag to a JSON column (#8564)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu authored Dec 12, 2018
1 parent 9bd1fb8 commit 63e7dac
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
2 changes: 1 addition & 1 deletion expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ func (c *compareFunctionClass) generateCmpSigs(ctx sessionctx.Context, args []Ex
if tp == types.ETJson {
// In compare, if we cast string to JSON, we shouldn't parse it.
for i := range args {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
}
bf.tp.Flen = 1
Expand Down
13 changes: 6 additions & 7 deletions expression/builtin_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package expression
import (
"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/types/json"
Expand Down Expand Up @@ -174,7 +173,7 @@ func (c *jsonUnquoteFunctionClass) getFunction(ctx sessionctx.Context, args []Ex
return nil, err
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETJson)
args[0].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[0])
sig := &builtinJSONUnquoteSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonUnquoteSig)
return sig, nil
Expand Down Expand Up @@ -218,7 +217,7 @@ func (c *jsonSetFunctionClass) getFunction(ctx sessionctx.Context, args []Expres
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONSetSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonSetSig)
Expand Down Expand Up @@ -258,7 +257,7 @@ func (c *jsonInsertFunctionClass) getFunction(ctx sessionctx.Context, args []Exp
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONInsertSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonInsertSig)
Expand Down Expand Up @@ -298,7 +297,7 @@ func (c *jsonReplaceFunctionClass) getFunction(ctx sessionctx.Context, args []Ex
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 2; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONReplaceSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonReplaceSig)
Expand Down Expand Up @@ -434,7 +433,7 @@ func (c *jsonObjectFunctionClass) getFunction(ctx sessionctx.Context, args []Exp
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := 1; i < len(args); i += 2 {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONObjectSig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonObjectSig)
Expand Down Expand Up @@ -497,7 +496,7 @@ func (c *jsonArrayFunctionClass) getFunction(ctx sessionctx.Context, args []Expr
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETJson, argTps...)
for i := range args {
args[i].GetType().Flag &= ^mysql.ParseToJSONFlag
DisableParseJSONFlag4Expr(args[i])
}
sig := &builtinJSONArraySig{bf}
sig.setPbCode(tipb.ScalarFuncSig_JsonArraySig)
Expand Down
12 changes: 12 additions & 0 deletions expression/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,18 @@ func GetParamExpression(ctx sessionctx.Context, v *driver.ParamMarkerExpr) (Expr
return value, nil
}

// DisableParseJSONFlag4Expr disables ParseToJSONFlag for `expr` except Column.
// We should not *PARSE* a string as JSON under some scenarios. ParseToJSONFlag
// is 0 for JSON column yet, so we can skip it. Moreover, Column.RetType refers
// to the infoschema, if we modify it, data race may happen if another goroutine
// read from the infoschema at the same time.
func DisableParseJSONFlag4Expr(expr Expression) {
if _, isColumn := expr.(*Column); isColumn {
return
}
expr.GetType().Flag &= ^mysql.ParseToJSONFlag
}

// ConstructPositionExpr constructs PositionExpr with the given ParamMarkerExpr.
func ConstructPositionExpr(p *driver.ParamMarkerExpr) *ast.PositionExpr {
return &ast.PositionExpr{P: p}
Expand Down

0 comments on commit 63e7dac

Please sign in to comment.