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

Add basic vector support for MySQL 9.x #16464

Merged
merged 4 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions go/mysql/binlog/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ const (
// TypeTime2 is MYSQL_TYPE_TIME2
TypeTime2 = 19

// TypeVector is MYSQL_TYPE_VECTOR
TypeVector = 242

// TypeJSON is MYSQL_TYPE_JSON
TypeJSON = 245

Expand Down
6 changes: 3 additions & 3 deletions go/mysql/binlog/rbr.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func CellLength(data []byte, pos int, typ byte, metadata uint16) (int, error) {
return intg0*4 + dig2bytes[intg0x] + frac0*4 + dig2bytes[frac0x], nil
case TypeEnum, TypeSet:
return int(metadata & 0xff), nil
case TypeJSON, TypeTinyBlob, TypeMediumBlob, TypeLongBlob, TypeBlob, TypeGeometry:
case TypeJSON, TypeTinyBlob, TypeMediumBlob, TypeLongBlob, TypeBlob, TypeGeometry, TypeVector:
// Of the Blobs, only TypeBlob is used in binary logs,
// but supports others just in case.
switch metadata {
Expand Down Expand Up @@ -652,8 +652,8 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, field *querypb.F
return sqltypes.MakeTrusted(querypb.Type_SET,
data[pos:pos+l]), l, nil

case TypeJSON, TypeTinyBlob, TypeMediumBlob, TypeLongBlob, TypeBlob:
// Only TypeBlob is used in binary logs,
case TypeJSON, TypeTinyBlob, TypeMediumBlob, TypeLongBlob, TypeBlob, TypeVector:
// Only TypeBlob and TypeVector is used in binary logs,
// but supports others just in case.
l := 0
switch metadata {
Expand Down
7 changes: 4 additions & 3 deletions go/mysql/binlog_event_rbr.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
tableMapEnumAndSetDefaultCharset
tableMapEnumAndSetColumnCharset
tableMapColumnVisibility
tableMapVectorDimensionality
)

// This byte in the optional metadata indicates that we should
Expand Down Expand Up @@ -136,7 +137,7 @@ func metadataLength(typ byte) int {
// No data here.
return 0

case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry:
case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry, binlog.TypeVector:
// One byte.
return 1

Expand Down Expand Up @@ -172,7 +173,7 @@ func metadataRead(data []byte, pos int, typ byte) (uint16, int, error) {
// No data here.
return 0, pos, nil

case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry:
case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry, binlog.TypeVector:
// One byte.
return uint16(data[pos]), pos + 1, nil

Expand All @@ -198,7 +199,7 @@ func metadataWrite(data []byte, pos int, typ byte, value uint16) int {
// No data here.
return pos

case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry:
case binlog.TypeFloat, binlog.TypeDouble, binlog.TypeTimestamp2, binlog.TypeDateTime2, binlog.TypeTime2, binlog.TypeJSON, binlog.TypeTinyBlob, binlog.TypeMediumBlob, binlog.TypeLongBlob, binlog.TypeBlob, binlog.TypeGeometry, binlog.TypeVector:
// One byte.
data[pos] = byte(value)
return pos + 1
Expand Down
2 changes: 1 addition & 1 deletion go/mysql/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ func (c *Conn) parseStmtArgs(data []byte, typ querypb.Type, pos int) (sqltypes.V
return sqltypes.NULL, 0, false
}
case sqltypes.Decimal, sqltypes.Text, sqltypes.Blob, sqltypes.VarChar, sqltypes.VarBinary, sqltypes.Year, sqltypes.Char,
sqltypes.Bit, sqltypes.Enum, sqltypes.Set, sqltypes.Geometry, sqltypes.Binary, sqltypes.TypeJSON:
sqltypes.Bit, sqltypes.Enum, sqltypes.Set, sqltypes.Geometry, sqltypes.Binary, sqltypes.TypeJSON, sqltypes.Vector:
val, pos, ok := readLenEncStringAsBytesCopy(data, pos)
return sqltypes.MakeTrusted(sqltypes.VarBinary, val), pos, ok
default:
Expand Down
3 changes: 3 additions & 0 deletions go/mysql/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ func TestQueries(t *testing.T) {
// Skip TUPLE, not possible in Result.
{Name: "Type_GEOMETRY ", Type: querypb.Type_GEOMETRY, Charset: collations.CollationBinaryID, Flags: uint32(querypb.MySqlFlag_BINARY_FLAG | querypb.MySqlFlag_BLOB_FLAG)},
{Name: "Type_JSON ", Type: querypb.Type_JSON, Charset: collations.CollationUtf8mb4ID},
{Name: "Type_VECTOR ", Type: querypb.Type_VECTOR, Charset: collations.CollationBinaryID},
},
Rows: [][]sqltypes.Value{
{
Expand Down Expand Up @@ -492,6 +493,7 @@ func TestQueries(t *testing.T) {
sqltypes.MakeTrusted(querypb.Type_SET, []byte("Type_SET")),
sqltypes.MakeTrusted(querypb.Type_GEOMETRY, []byte("Type_GEOMETRY")),
sqltypes.MakeTrusted(querypb.Type_JSON, []byte("Type_JSON")),
sqltypes.MakeTrusted(querypb.Type_VECTOR, []byte("Type_VECTOR")),
},
{
sqltypes.NULL,
Expand Down Expand Up @@ -523,6 +525,7 @@ func TestQueries(t *testing.T) {
sqltypes.NULL,
sqltypes.NULL,
sqltypes.NULL,
sqltypes.NULL,
},
},
})
Expand Down
2 changes: 2 additions & 0 deletions go/mysql/sqlerror/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ const (
ERDupIndex = ErrorCode(1831)
ERInnodbReadOnly = ErrorCode(1874)

ERVectorConversion = ErrorCode(6138)

// already exists
ERDbCreateExists = ErrorCode(1007)
ERTableExists = ErrorCode(1050)
Expand Down
1 change: 1 addition & 0 deletions go/mysql/sqlerror/sql_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ var stateToMysqlCode = map[vterrors.State]mysqlCode{
vterrors.KillDeniedError: {num: ERKillDenied, state: SSUnknownSQLState},
vterrors.BadNullError: {num: ERBadNullError, state: SSConstraintViolation},
vterrors.InvalidGroupFuncUse: {num: ERInvalidGroupFuncUse, state: SSUnknownSQLState},
vterrors.VectorConversion: {num: ERVectorConversion, state: SSUnknownSQLState},
}

func getStateToMySQLState(state vterrors.State) mysqlCode {
Expand Down
3 changes: 3 additions & 0 deletions go/sqltypes/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const (
HexVal = querypb.Type_HEXVAL
Tuple = querypb.Type_TUPLE
BitNum = querypb.Type_BITNUM
Vector = querypb.Type_VECTOR
)

// bit-shift the mysql flags by two byte so we
Expand Down Expand Up @@ -219,6 +220,7 @@ var mysqlToType = map[byte]querypb.Type{
17: Timestamp,
18: Datetime,
19: Time,
242: Vector,
245: TypeJSON,
246: Decimal,
247: Enum,
Expand Down Expand Up @@ -331,6 +333,7 @@ var typeToMySQL = map[querypb.Type]struct {
Datetime: {typ: 12, flags: mysqlBinary},
Year: {typ: 13, flags: mysqlUnsigned},
Bit: {typ: 16, flags: mysqlUnsigned},
Vector: {typ: 242},
TypeJSON: {typ: 245},
Decimal: {typ: 246},
Text: {typ: 252},
Expand Down
34 changes: 20 additions & 14 deletions go/vt/proto/query/query.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions go/vt/sqlparser/ast_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ func SQLTypeToQueryType(typeName string, unsigned bool) querypb.Type {
return sqltypes.Set
case JSON:
return sqltypes.TypeJSON
case VECTOR:
return sqltypes.Vector
case GEOMETRY:
return sqltypes.Geometry
case POINT:
Expand Down
1 change: 1 addition & 0 deletions go/vt/sqlparser/keywords.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ var keywords = []keyword{
{"varcharacter", UNUSED},
{"variance", VARIANCE},
{"varying", UNUSED},
{"vector", VECTOR},
{"vexplain", VEXPLAIN},
{"vgtid_executed", VGTID_EXECUTED},
{"virtual", VIRTUAL},
Expand Down
7 changes: 7 additions & 0 deletions go/vt/sqlparser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,9 @@ var (
input: "select /* bool in order by */ * from t order by a is null or b asc",
}, {
input: "select /* string in case statement */ if(max(case a when 'foo' then 1 else 0 end) = 1, 'foo', 'bar') as foobar from t",
}, {
input: "select 1 as vector",
output: "select 1 as `vector` from dual",
}, {
input: "/*!show databases*/",
output: "show databases",
Expand Down Expand Up @@ -5924,6 +5927,10 @@ partition by range (YEAR(purchased)) subpartition by hash (TO_DAYS(purchased))
input: "create table t (id int, s varchar(255) default 'foo\"bar')",
output: "create table t (\n\tid int,\n\ts varchar(255) default 'foo\"bar'\n)",
},
{
input: "create table t (id int, vec VECTOR(4))",
output: "create table t (\n\tid int,\n\tvec VECTOR(4)\n)",
},
}
parser := NewTestParser()
for _, test := range createTableQueries {
Expand Down
Loading
Loading