Skip to content

Commit

Permalink
Merge pull request #7637 from planetscale/sysvar-socket
Browse files Browse the repository at this point in the history
Socket system variable to return vitess mysql socket
  • Loading branch information
systay authored Mar 10, 2021
2 parents fb0b16a + b1b2e82 commit 9f5e7e5
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 15 deletions.
1 change: 1 addition & 0 deletions go/mysql/sql_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ var stateToMysqlCode = map[vterrors.State]struct {
vterrors.DbCreateExists: {num: ERDbCreateExists, state: SSUnknownSQLState},
vterrors.DbDropExists: {num: ERDbDropExists, state: SSUnknownSQLState},
vterrors.EmptyQuery: {num: EREmptyQuery, state: SSClientError},
vterrors.IncorrectGlobalLocalVar: {num: ERIncorrectGlobalLocalVar, state: SSUnknownSQLState},
vterrors.InnodbReadOnly: {num: ERInnodbReadOnly, state: SSUnknownSQLState},
vterrors.LockOrActiveTransaction: {num: ERLockOrActiveTransaction, state: SSUnknownSQLState},
vterrors.NoDB: {num: ERNoDb, state: SSNoDB},
Expand Down
22 changes: 22 additions & 0 deletions go/test/endtoend/vtgate/reservedconn/sysvar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"vitess.io/vitess/go/mysql"
Expand Down Expand Up @@ -373,3 +374,24 @@ func TestSystemVariableType(t *testing.T) {
checkedExec(t, conn, "set autocommit = true")
assertResponseMatch(t, conn, query1, query2)
}

func TestSysvarSocket(t *testing.T) {
vtParams := mysql.ConnParams{
Host: "localhost",
Port: clusterInstance.VtgateMySQLPort,
}
conn, err := mysql.Connect(context.Background(), &vtParams)
require.NoError(t, err)
defer conn.Close()

qr := checkedExec(t, conn, "select @@socket")
assert.Contains(t, fmt.Sprintf("%v", qr.Rows), "mysql.sock")

_, err = exec(t, conn, "set socket = '/any/path'")
require.Error(t, err)
sqlErr, ok := err.(*mysql.SQLError)
require.True(t, ok, "not a mysql error: %T", err)
assert.Equal(t, mysql.ERIncorrectGlobalLocalVar, sqlErr.Number())
assert.Equal(t, mysql.SSUnknownSQLState, sqlErr.SQLState())
assert.Equal(t, "Variable 'socket' is a read only variable (errno 1238) (sqlstate HY000) during query: set socket = '/any/path'", sqlErr.Error())
}
15 changes: 8 additions & 7 deletions go/vt/sqlparser/ast_rewriting.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,19 @@ func (er *expressionRewriter) sysVarRewrite(cursor *Cursor, node *ColName) {
switch lowered {
case sysvars.Autocommit.Name,
sysvars.ClientFoundRows.Name,
sysvars.SkipQueryPlanCache.Name,
sysvars.SQLSelectLimit.Name,
sysvars.TransactionMode.Name,
sysvars.Workload.Name,
sysvars.DDLStrategy.Name,
sysvars.SessionUUID.Name,
sysvars.SessionEnableSystemSettings.Name,
sysvars.TransactionMode.Name,
sysvars.ReadAfterWriteGTID.Name,
sysvars.ReadAfterWriteTimeOut.Name,
sysvars.SessionEnableSystemSettings.Name,
sysvars.SessionTrackGTIDs.Name,
sysvars.SessionUUID.Name,
sysvars.SkipQueryPlanCache.Name,
sysvars.Socket.Name,
sysvars.SQLSelectLimit.Name,
sysvars.Version.Name,
sysvars.VersionComment.Name,
sysvars.SessionTrackGTIDs.Name:
sysvars.Workload.Name:
cursor.Replace(bindVarExpression("__vt" + lowered))
er.bindVars.AddSysVar(lowered)
}
Expand Down
9 changes: 8 additions & 1 deletion go/vt/sqlparser/ast_rewriting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type myTestCase struct {
liid, db, foundRows, rowCount, rawGTID, rawTimeout, sessTrackGTID bool
ddlStrategy, sessionUUID, sessionEnableSystemSettings bool
udv int
autocommit, clientFoundRows, skipQueryPlanCache bool
autocommit, clientFoundRows, skipQueryPlanCache, socket bool
sqlSelectLimit, transactionMode, workload, version, versionComment bool
}

Expand Down Expand Up @@ -146,6 +146,10 @@ func TestRewrites(in *testing.T) {
in: "SELECT @@workload",
expected: "SELECT :__vtworkload as `@@workload`",
workload: true,
}, {
in: "SELECT @@socket",
expected: "SELECT :__vtsocket as `@@socket`",
socket: true,
}, {
in: "select (select 42) from dual",
expected: "select 42 as `(select 42 from dual)` from dual",
Expand Down Expand Up @@ -198,6 +202,7 @@ func TestRewrites(in *testing.T) {
rawGTID: true,
rawTimeout: true,
sessTrackGTID: true,
socket: true,
}, {
in: "SHOW GLOBAL VARIABLES",
expected: "SHOW GLOBAL VARIABLES",
Expand All @@ -215,6 +220,7 @@ func TestRewrites(in *testing.T) {
rawGTID: true,
rawTimeout: true,
sessTrackGTID: true,
socket: true,
}}

for _, tc := range tests {
Expand Down Expand Up @@ -251,6 +257,7 @@ func TestRewrites(in *testing.T) {
assert.Equal(tc.sessTrackGTID, result.NeedsSysVar(sysvars.SessionTrackGTIDs.Name), "should need sessTrackGTID")
assert.Equal(tc.version, result.NeedsSysVar(sysvars.Version.Name), "should need Vitess version")
assert.Equal(tc.versionComment, result.NeedsSysVar(sysvars.VersionComment.Name), "should need Vitess version")
assert.Equal(tc.socket, result.NeedsSysVar(sysvars.Socket.Name), "should need :__vtsocket")
})
}
}
Expand Down
21 changes: 15 additions & 6 deletions go/vt/sysvars/sysvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,19 @@ var (
utf8 = "'utf8'"

Autocommit = SystemVariable{Name: "autocommit", IsBoolean: true, Default: on}
Charset = SystemVariable{Name: "charset", Default: utf8, IdentifierAsString: true}
ClientFoundRows = SystemVariable{Name: "client_found_rows", IsBoolean: true, Default: off}
SessionEnableSystemSettings = SystemVariable{Name: "enable_system_settings", IsBoolean: true, Default: on}
Names = SystemVariable{Name: "names", Default: utf8, IdentifierAsString: true}
SessionUUID = SystemVariable{Name: "session_uuid", IdentifierAsString: true}
SkipQueryPlanCache = SystemVariable{Name: "skip_query_plan_cache", IsBoolean: true, Default: off}
TxReadOnly = SystemVariable{Name: "tx_read_only", IsBoolean: true, Default: off}
TransactionReadOnly = SystemVariable{Name: "transaction_read_only", IsBoolean: true, Default: off}
Socket = SystemVariable{Name: "socket", Default: off}
SQLSelectLimit = SystemVariable{Name: "sql_select_limit", Default: off}
TransactionMode = SystemVariable{Name: "transaction_mode", IdentifierAsString: true}
TransactionReadOnly = SystemVariable{Name: "transaction_read_only", IsBoolean: true, Default: off}
TxReadOnly = SystemVariable{Name: "tx_read_only", IsBoolean: true, Default: off}
Workload = SystemVariable{Name: "workload", IdentifierAsString: true}
Charset = SystemVariable{Name: "charset", Default: utf8, IdentifierAsString: true}
Names = SystemVariable{Name: "names", Default: utf8, IdentifierAsString: true}
SessionUUID = SystemVariable{Name: "session_uuid", IdentifierAsString: true}
SessionEnableSystemSettings = SystemVariable{Name: "enable_system_settings", IsBoolean: true, Default: on}

// Online DDL
DDLStrategy = SystemVariable{Name: "ddl_strategy", IdentifierAsString: true}
Version = SystemVariable{Name: "version"}
Expand Down Expand Up @@ -84,6 +86,12 @@ var (
SessionTrackGTIDs,
}

ReadOnly = []SystemVariable{
Socket,
Version,
VersionComment,
}

IgnoreThese = []SystemVariable{
{Name: "big_tables", IsBoolean: true},
{Name: "bulk_insert_buffer_size"},
Expand Down Expand Up @@ -249,5 +257,6 @@ func GetInterestingVariables() []string {
// Also add version and version comment
res = append(res, Version.Name)
res = append(res, VersionComment.Name)
res = append(res, Socket.Name)
return res
}
1 change: 1 addition & 0 deletions go/vt/vterrors/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
DataOutOfRange
EmptyQuery
ForbidSchemaChange
IncorrectGlobalLocalVar
NonUniqTable
SyntaxError
WrongGroupField
Expand Down
2 changes: 2 additions & 0 deletions go/vt/vtgate/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ func (e *Executor) addNeededBindVars(bindVarNeeds *sqlparser.BindVarNeeds, bindV
bindVars[key] = sqltypes.StringBindVariable(servenv.AppVersion.MySQLVersion())
case sysvars.VersionComment.Name:
bindVars[key] = sqltypes.StringBindVariable(servenv.AppVersion.String())
case sysvars.Socket.Name:
bindVars[key] = sqltypes.StringBindVariable(mysqlSocketPath())
}
}

Expand Down
4 changes: 3 additions & 1 deletion go/vt/vtgate/executor_select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func TestSelectSystemVariables(t *testing.T) {

sql := "select @@autocommit, @@client_found_rows, @@skip_query_plan_cache, @@enable_system_settings, " +
"@@sql_select_limit, @@transaction_mode, @@workload, @@read_after_write_gtid, " +
"@@read_after_write_timeout, @@session_track_gtids, @@ddl_strategy"
"@@read_after_write_timeout, @@session_track_gtids, @@ddl_strategy, @@socket"

result, err := executorExec(executor, sql, map[string]*querypb.BindVariable{})
wantResult := &sqltypes.Result{
Expand All @@ -334,6 +334,7 @@ func TestSelectSystemVariables(t *testing.T) {
{Name: "@@read_after_write_timeout", Type: sqltypes.Float64},
{Name: "@@session_track_gtids", Type: sqltypes.VarBinary},
{Name: "@@ddl_strategy", Type: sqltypes.VarBinary},
{Name: "@@socket", Type: sqltypes.VarBinary},
},
Rows: [][]sqltypes.Value{{
// the following are the uninitialised session values
Expand All @@ -349,6 +350,7 @@ func TestSelectSystemVariables(t *testing.T) {
sqltypes.NewFloat64(13),
sqltypes.NewVarBinary("own_gtid"),
sqltypes.NewVarBinary(""),
sqltypes.NewVarBinary(""),
}},
}
require.NoError(t, err)
Expand Down
3 changes: 3 additions & 0 deletions go/vt/vtgate/executor_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ func TestExecutorSet(t *testing.T) {
}, {
in: "set @@enable_system_settings = false",
out: &vtgatepb.Session{Autocommit: true, EnableSystemSettings: false},
}, {
in: "set @@socket = '/tmp/change.sock'",
err: "Variable 'socket' is a read only variable",
}}
for i, tcase := range testcases {
t.Run(fmt.Sprintf("%d-%s", i, tcase.in), func(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions go/vt/vtgate/planbuilder/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ func buildSetPlan(stmt *sqlparser.Set, vschema ContextVSchema) (engine.Primitive
}, nil
}

func buildSetOpReadOnly(s setting) planFunc {
return func(expr *sqlparser.SetExpr, schema ContextVSchema, _ *expressionConverter) (engine.SetOp, error) {
return nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.IncorrectGlobalLocalVar, "Variable '%s' is a read only variable", expr.Name)
}
}

func buildNotSupported(setting) planFunc {
return func(expr *sqlparser.SetExpr, schema ContextVSchema, _ *expressionConverter) (engine.SetOp, error) {
return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "%s: system setting is not supported", expr.Name)
Expand Down
1 change: 1 addition & 0 deletions go/vt/vtgate/planbuilder/system_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
)

func init() {
forSettings(sysvars.ReadOnly, buildSetOpReadOnly)
forSettings(sysvars.IgnoreThese, buildSetOpIgnore)
forSettings(sysvars.UseReservedConn, buildSetOpReservedConn)
forSettings(sysvars.CheckAndIgnore, buildSetOpCheckAndIgnore)
Expand Down
5 changes: 5 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/set_cases.txt
Original file line number Diff line number Diff line change
Expand Up @@ -522,3 +522,8 @@ Gen4 plan same as above
}
}
Gen4 plan same as above

# change read only variable
"set socket = ''"
"Variable 'socket' is a read only variable"
Gen4 plan same as above
7 changes: 7 additions & 0 deletions go/vt/vtgate/plugin_mysql_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,13 @@ func rollbackAtShutdown() {
log.Errorf("All connections did not go idle. Shutting down anyway.")
}

func mysqlSocketPath() string {
if mysqlServerSocketPath == nil {
return ""
}
return *mysqlServerSocketPath
}

func init() {
servenv.OnRun(initMySQLProtocol)
servenv.OnTermSync(shutdownMysqlProtocolAndDrain)
Expand Down

0 comments on commit 9f5e7e5

Please sign in to comment.