Skip to content
25 changes: 25 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8850,6 +8850,14 @@ func (s *testStaleTxnSuite) TestInvalidReadTemporaryTable(c *C) {
tk.MustExec("create global temporary table tmp1 " +
"(id int not null primary key, code int not null, value int default null, unique key code(code))" +
"on commit delete rows")
tk.MustExec("set @@tidb_enable_noop_functions=1;")
tk.MustExec("use test")
tk.MustExec("drop table if exists tmp2")
tk.MustExec("create temporary table tmp2 (id int not null primary key, code int not null, value int default null, unique key code(code));")
tk.MustExec("create table tmp3 (id int not null primary key, code int not null, value int default null, unique key code(code));")
tk.MustExec("create table tmp4 (id int not null primary key, code int not null, value int default null, unique key code(code));")
tk.MustExec("create temporary table tmp5(id int);")
tk.MustExec("create table tmp6 (id int primary key);")

// sleep 1us to make test stale
time.Sleep(time.Microsecond)
Expand Down Expand Up @@ -8890,7 +8898,14 @@ func (s *testStaleTxnSuite) TestInvalidReadTemporaryTable(c *C) {
}
return sql[0:idx] + " as of timestamp NOW(6)" + sql[idx:]
}
genLocalTemporarySQL := func(sql string) string {
return strings.Replace(sql, "tmp1", "tmp2", -1)
}

for _, query := range queries {
localSQL := genLocalTemporarySQL(query.sql)
queries = append(queries, struct{ sql string }{sql: localSQL})
}
for _, query := range queries {
sql := addStaleReadToSQL(query.sql)
if sql != "" {
Expand All @@ -8908,6 +8923,16 @@ func (s *testStaleTxnSuite) TestInvalidReadTemporaryTable(c *C) {
tk.MustExec(query.sql)
}

// Test normal table when local temporary exits.
tk.MustExec("insert into tmp6 values(1);")
tk.MustExec("set @a=now(6);")
time.Sleep(time.Microsecond)
tk.MustExec("drop table tmp6")
tk.MustExec("create table tmp6 (id int primary key);")
tk.MustQuery("select * from tmp6 as of timestamp(@a) where id=1;").Check(testkit.Rows("1"))
tk.MustQuery("select * from tmp4 as of timestamp(@a), tmp3 as of timestamp(@a) where tmp3.id=1;")
tk.MustGetErrMsg("select * from tmp4 as of timestamp(@a), tmp2 as of timestamp(@a) where tmp2.id=1;", "can not stale read temporary table")

tk.MustExec("set transaction read only as of timestamp NOW(6)")
tk.MustExec("start transaction")
for _, query := range queries {
Expand Down
21 changes: 19 additions & 2 deletions planner/core/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1585,10 +1585,27 @@ func (p *preprocessor) handleAsOfAndReadTS(node *ast.AsOfClause) {
}
if p.LastSnapshotTS != 0 {
dom := domain.GetDomain(p.ctx)
p.InfoSchema, p.err = dom.GetSnapshotInfoSchema(p.LastSnapshotTS)
if p.err != nil {
is, err := dom.GetSnapshotInfoSchema(p.LastSnapshotTS)
// if infoschema is empty, LastSnapshotTS init failed
if err != nil {
p.err = err
Comment thread
sylzd marked this conversation as resolved.
return
}
if is == nil {
p.err = fmt.Errorf("can not get any information schema based on snapshotTS: %d", p.LastSnapshotTS)
return
}
// the same as session.wrapWithTemporaryTable
if _, ok := is.(*infoschema.TemporaryTableAttachedInfoSchema); !ok {
localTmp := p.ctx.GetSessionVars().LocalTemporaryTables
if localTmp != nil {
is = &infoschema.TemporaryTableAttachedInfoSchema{
InfoSchema: is,
LocalTemporaryTables: localTmp.(*infoschema.LocalTemporaryTables),
}
}
}
p.InfoSchema = is
}
if p.flag&inPrepare == 0 {
p.ctx.GetSessionVars().StmtCtx.IsStaleness = p.IsStaleness
Expand Down