Skip to content

Commit

Permalink
Stopping the parsing for unsupported json opaques.
Browse files Browse the repository at this point in the history
  • Loading branch information
alainjobart committed May 1, 2017
1 parent 278b9ff commit 209f09d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 23 deletions.
20 changes: 8 additions & 12 deletions go/mysqlconn/replication/binlog_event_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func printJSONValue(typ byte, data []byte, toplevel bool, result *bytes.Buffer)
case jsonTypeString:
printJSONString(data, toplevel, result)
case jsonTypeOpaque:
printJSONOpaque(data, toplevel, result)
return printJSONOpaque(data, toplevel, result)
default:
return fmt.Errorf("unknown object type in JSON: %v", typ)
}
Expand Down Expand Up @@ -345,17 +345,13 @@ func printJSONOpaque(data []byte, toplevel bool, result *bytes.Buffer) error {
return printJSONDecimal(data[pos:pos+size], toplevel, result)
}

// FIXME(alainjobart) this is broken for now. The lack of metadata
// makes the parsing fail. The MySQL source code is too obscure
// to make any sense of this.
val, pos, err := CellValue(data, pos, typ, 0, querypb.Type_INT8)
if err != nil {
return err
}
result.WriteString("CAST(")
val.EncodeSQL(result)
result.WriteString(" AS JSON)")
return nil
// Other types are encoded in somewhat weird ways. Since we
// have no metadata, it seems some types first provide the
// metadata, and then the values. But even that metadata is
// not straightforward (for instance, a bit field seems to
// have one byte as metadata, not two as would be expected).
// To be on the safer side, we just reject these cases for now.
return fmt.Errorf("opaque type %v is not supported yet, with data %v", typ, data[1:])
}

func printJSONDate(data []byte, toplevel bool, result *bytes.Buffer) error {
Expand Down
23 changes: 12 additions & 11 deletions go/mysqlconn/replication/binlog_event_json_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package replication

import "testing"
import (
"fmt"
"testing"
)

func TestJSON(t *testing.T) {
testcases := []struct {
Expand Down Expand Up @@ -99,23 +102,21 @@ func TestJSON(t *testing.T) {
data: []byte{15, 246, 8, 13, 4, 135, 91, 205, 21, 4, 210},
expected: `CAST(CAST('123456789.1234' AS DECIMAL(13,4)) AS JSON)`,
}, {
// opaque, bit field.
// FIXME(alainjobart) this is broken. It seems the '2'
// is the number of bytes (needed because there is no
// metadata), but I can't find how this works.
// So the parsing for now will produce an invalid string.
// opaque, bit field. Not yet implemented.
data: []byte{15, 16, 2, 202, 254},
expected: `CAST('' AS JSON)`,
expected: `ERROR: opaque type 16 is not supported yet, with data [2 202 254]`,
}}

for _, tcase := range testcases {
r, err := printJSONData(tcase.data)
got := ""
if err != nil {
t.Errorf("unexpected error for %v: %v", tcase.data, err)
continue
got = fmt.Sprintf("ERROR: %v", err)
} else {
got = string(r)
}
if string(r) != tcase.expected {
t.Errorf("unexpected output for %v: got %v expected %v", tcase.data, string(r), tcase.expected)
if got != tcase.expected {
t.Errorf("unexpected output for %v: got %v expected %v", tcase.data, got, tcase.expected)
}
}
}

0 comments on commit 209f09d

Please sign in to comment.