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

Allow zero (in) date when setting up internal _vt schema #12262

Merged
40 changes: 40 additions & 0 deletions go/vt/sidecardb/sidecardb.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ func Init(ctx context.Context, exec Exec) error {
return err
}

resetSQLMode, err := si.setPermissiveSQLMode()
if err != nil {
return err
}
defer resetSQLMode()

for _, table := range sidecarTables {
if err := si.ensureSchema(table); err != nil {
return err
Expand All @@ -202,6 +208,31 @@ func Init(ctx context.Context, exec Exec) error {
return nil
}

// setPermissiveSQLMode gets the current sql_mode for the session, removes any
// restrictions, and returns a function to restore it back to the original session value.
// We need to allow for the recreation of any data that currently exists in the table, such
// as e.g. allowing any zero dates that may already exist in a preexisting sidecar table.
func (si *schemaInit) setPermissiveSQLMode() (func(), error) {
rs, err := si.exec(si.ctx, `select @@session.sql_mode as sql_mode`, 1, false)
if err != nil {
return nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "could not read sql_mode: %v", err)
}
sqlMode, err := rs.Named().Row().ToString("sql_mode")
if err != nil {
return nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "could not read sql_mode: %v", err)
}

resetSQLModeFunc := func() {
restoreSQLModeQuery := fmt.Sprintf("set @@session.sql_mode='%s'", sqlMode)
_, _ = si.exec(si.ctx, restoreSQLModeQuery, 0, false)
}

if _, err := si.exec(si.ctx, "set @@session.sql_mode=''", 0, false); err != nil {
return nil, vterrors.Errorf(vtrpcpb.Code_UNKNOWN, "could not change sql_mode: %v", err)
}
return resetSQLModeFunc, nil
}

func (si *schemaInit) doesSidecarDBExist() (bool, error) {
rs, err := si.exec(si.ctx, ShowSidecarDatabasesQuery, 2, false)
if err != nil {
Expand Down Expand Up @@ -374,6 +405,15 @@ func AddSchemaInitQueries(db *fakesqldb.DB, populateTables bool) {
}
db.AddQuery(fmt.Sprintf(ShowCreateTableQuery, table.name), result)
}

sqlModeResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields(
"sql_mode",
"varchar"),
"ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION",
)
db.AddQuery("select @@session.sql_mode as sql_mode", sqlModeResult)

db.AddQuery("set @@session.sql_mode=''", &sqltypes.Result{})
}

// MatchesInitQuery returns true if query has one of the test patterns as a substring, or it matches a provided regexp.
Expand Down
9 changes: 8 additions & 1 deletion go/vt/sidecardb/sidecardb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,18 @@ import (
)

// Tests all non-error code paths in sidecardb
func TestAll(t *testing.T) {
func TestAllSidecarDB(t *testing.T) {
db := fakesqldb.New(t)
defer db.Close()
AddSchemaInitQueries(db, false)
db.AddQuery("use dbname", &sqltypes.Result{})
sqlMode := sqltypes.MakeTestResult(sqltypes.MakeTestFields(
"sql_mode",
"varchar"),
"ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION",
)
db.AddQuery("select @@session.sql_mode as sql_mode", sqlMode)
db.AddQueryPattern("set @@session.sql_mode=.*", &sqltypes.Result{})
Comment on lines +35 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't need this as it's done above in AddSchemaInitQueries().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


ctx := context.Background()
cp := db.ConnParams()
Expand Down
11 changes: 10 additions & 1 deletion go/vt/vtexplain/vtexplain_vttablet.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (vte *VTExplain) newTablet(opts *Options, t *topodatapb.Tablet) *explainTab
tsv.StartService(&target, dbcfgs, nil /* mysqld */)

// clear all the schema initialization queries out of the tablet
// to avoid clutttering the output
// to avoid cluttering the output
tablet.mysqlQueries = nil

return &tablet
Expand Down Expand Up @@ -300,6 +300,15 @@ func newTabletEnvironment(ddls []sqlparser.DDLStatement, opts *Options) (*tablet
{sqltypes.NewVarBinary("STRICT_TRANS_TABLES")},
},
},
"select @@session.sql_mode as sql_mode": {
Fields: []*querypb.Field{{
Name: "sql_mode",
Type: sqltypes.VarChar,
}},
Rows: [][]sqltypes.Value{
{sqltypes.NewVarBinary("STRICT_TRANS_TABLES")},
},
},
"select @@autocommit": {
Fields: []*querypb.Field{{
Type: sqltypes.Uint64,
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vttablet/tabletserver/schema/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (se *Engine) syncSidecarDB(ctx context.Context, conn *dbconnpool.DBConnecti
return nil, err
}
}
return conn.ExecuteFetch(query, maxRows, false)
return conn.ExecuteFetch(query, maxRows, true)
}
if err := sidecardb.Init(ctx, exec); err != nil {
log.Errorf("Error in sidecardb.Init: %+v", err)
Expand Down
18 changes: 16 additions & 2 deletions go/vt/vttest/local_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,7 @@ func (db *LocalCluster) createVTSchema() error {
return nil, err
}
}
err := db.Execute([]string{query}, "")
return &sqltypes.Result{}, err
return db.ExecuteFetch(query, "")
}

if err := sidecardb.Init(context.Background(), sidecardbExec); err != nil {
Expand Down Expand Up @@ -564,6 +563,21 @@ func (db *LocalCluster) Execute(sql []string, dbname string) error {
return err
}

// ExecuteFetch runs a SQL statement on the MySQL instance backing
// this local cluster and returns the result.
func (db *LocalCluster) ExecuteFetch(sql string, dbname string) (*sqltypes.Result, error) {
params := db.mysql.Params(dbname)
conn, err := mysql.Connect(context.Background(), &params)
if err != nil {
return nil, err
}
defer conn.Close()

log.Infof("ExecuteFetch(%s): \"%s\"", dbname, sql)
rs, err := conn.ExecuteFetch(sql, -1, true)
return rs, err
}

// Query runs a SQL query on the MySQL instance backing this local cluster and returns
// its result. This is provided for debug/introspection purposes;
// normal cluster access should be performed through the Vitess GRPC interface.
Expand Down