Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression: cast json_extract as bool #18948

Merged
merged 10 commits into from
Aug 7, 2020
13 changes: 12 additions & 1 deletion expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,18 @@ func toBool(sc *stmtctx.StatementContext, eType types.EvalType, buf *chunk.Colum
}
}
case types.ETJson:
return errors.Errorf("cannot convert type json.BinaryJSON to bool")
mysqljsons := buf.MysqlJSONs()
for i := range sel {
if buf.IsNull(i) {
isZero[i] = -1
} else {
if mysqljsons[i].IsZero() {
isZero[i] = 0
} else {
isZero[i] = 1
}
}
}
}
return nil
}
Expand Down
3 changes: 3 additions & 0 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,9 @@ func (d *Datum) ToBool(sc *stmtctx.StatementContext) (int64, error) {
case KindBinaryLiteral, KindMysqlBit:
val, err1 := d.GetBinaryLiteral().ToInt(sc)
isZero, err = val == 0, err1
case KindMysqlJSON:
val := d.GetMysqlJSON()
isZero = val.IsZero()
default:
return 0, errors.Errorf("cannot convert %v(type %T) to bool", d.GetValue(), d.GetValue())
}
Expand Down
22 changes: 22 additions & 0 deletions types/json/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,28 @@ func (bj BinaryJSON) marshalTo(buf []byte) ([]byte, error) {
return buf, nil
}

//IsZero return a boolean indicate whether BinaryJSON is Zero
func (bj BinaryJSON) IsZero() bool {
isZero := false
switch bj.TypeCode {
case TypeCodeString:
isZero = false
case TypeCodeLiteral:
isZero = false
SunRunAway marked this conversation as resolved.
Show resolved Hide resolved
case TypeCodeInt64:
isZero = bj.GetInt64() == 0
case TypeCodeUint64:
isZero = bj.GetUint64() == 0
case TypeCodeFloat64:
isZero = bj.GetFloat64() == 0
case TypeCodeArray:
isZero = false
case TypeCodeObject:
isZero = false
}
return isZero
}

// GetInt64 gets the int64 value.
func (bj BinaryJSON) GetInt64() int64 {
return int64(endian.Uint64(bj.Value))
Expand Down
9 changes: 9 additions & 0 deletions util/chunk/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,15 @@ func (c *Column) Times() []types.Time {
return res
}

// MysqlJSONs returns an MysqlJSONs slice stored in this Column.
func (c *Column) MysqlJSONs() []json.BinaryJSON {
SunRunAway marked this conversation as resolved.
Show resolved Hide resolved
var res []json.BinaryJSON
for i := 0; i < c.length; i++ {
res = append(res, c.GetJSON(i))
}
return res
}

// GetInt64 returns the int64 in the specific row.
func (c *Column) GetInt64(rowID int) int64 {
return *(*int64)(unsafe.Pointer(&c.data[rowID*8]))
Expand Down