From ac27642e3ba47ef85d6c08d0fabaf392dc4fd162 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Sun, 10 Sep 2023 17:30:56 +0800 Subject: [PATCH 1/3] hint: fix panic when query block not found in prepare statement Signed-off-by: Jack Yu --- executor/prepared_test.go | 13 +++++++++++++ util/hint/hint_processor.go | 4 +++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index 69c54b26af783..d3e4f53c6e1a1 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -98,6 +98,19 @@ func TestPreparedStmtWithHint(t *testing.T) { tk.MustQuery("execute stmt").Check(testkit.Rows("1")) } +func TestPreparedCTEStmtWithHint(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + sv := server.CreateMockServer(t, store) + sv.SetDomain(dom) + defer sv.Close() + + conn1 := server.CreateMockConn(t, sv) + tk := testkit.NewTestKitWithSession(t, store, conn1.Context().Session) + + tk.MustExec("use test") + tk.MustExec("create table t (i int)") + tk.MustExec("prepare stmt from 'with a as (select /*+ qb_name(qb1) */ * from t) select /*+ leading(@qb1)*/ * from a;'") +} func TestPreparedNullParam(t *testing.T) { store := testkit.CreateMockStore(t) flags := []bool{false, true} diff --git a/util/hint/hint_processor.go b/util/hint/hint_processor.go index be1a1a4e7fc4c..14b41aa8a274a 100644 --- a/util/hint/hint_processor.go +++ b/util/hint/hint_processor.go @@ -596,7 +596,9 @@ func (p *BlockHintProcessor) GetCurrentStmtHints(hints []*ast.TableOptimizerHint offset := p.GetHintOffset(hint.QBName, currentOffset) if offset < 0 || !p.checkTableQBName(hint.Tables) { hintStr := RestoreTableOptimizerHint(hint) - p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Hint %s is ignored due to unknown query block name", hintStr)) + if p.Ctx != nil { + p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Hint %s is ignored due to unknown query block name", hintStr)) + } continue } p.QbHints[offset] = append(p.QbHints[offset], hint) From 9383ca9b0c95b507079979af939b7443648a6d6f Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Sun, 10 Sep 2023 21:57:44 +0800 Subject: [PATCH 2/3] address comments Signed-off-by: Jack Yu --- executor/prepared_test.go | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/executor/prepared_test.go b/executor/prepared_test.go index d3e4f53c6e1a1..a266ebe29f787 100644 --- a/executor/prepared_test.go +++ b/executor/prepared_test.go @@ -96,21 +96,13 @@ func TestPreparedStmtWithHint(t *testing.T) { go dom.ExpensiveQueryHandle().SetSessionManager(sv).Run() tk.MustExec("prepare stmt from \"select /*+ max_execution_time(100) */ sleep(10)\"") tk.MustQuery("execute stmt").Check(testkit.Rows("1")) -} - -func TestPreparedCTEStmtWithHint(t *testing.T) { - store, dom := testkit.CreateMockStoreAndDomain(t) - sv := server.CreateMockServer(t, store) - sv.SetDomain(dom) - defer sv.Close() - - conn1 := server.CreateMockConn(t, sv) - tk := testkit.NewTestKitWithSession(t, store, conn1.Context().Session) + // see https://github.com/pingcap/tidb/issues/46817 tk.MustExec("use test") - tk.MustExec("create table t (i int)") + tk.MustExec("create table if not exists t (i int)") tk.MustExec("prepare stmt from 'with a as (select /*+ qb_name(qb1) */ * from t) select /*+ leading(@qb1)*/ * from a;'") } + func TestPreparedNullParam(t *testing.T) { store := testkit.CreateMockStore(t) flags := []bool{false, true} From da806e27a4f8d0ef6a47352103149ad756d1de85 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Mon, 11 Sep 2023 10:38:37 +0800 Subject: [PATCH 3/3] tiny change Signed-off-by: Jack Yu --- util/hint/hint_processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/hint/hint_processor.go b/util/hint/hint_processor.go index 14b41aa8a274a..7494d55d4481c 100644 --- a/util/hint/hint_processor.go +++ b/util/hint/hint_processor.go @@ -595,8 +595,8 @@ func (p *BlockHintProcessor) GetCurrentStmtHints(hints []*ast.TableOptimizerHint } offset := p.GetHintOffset(hint.QBName, currentOffset) if offset < 0 || !p.checkTableQBName(hint.Tables) { - hintStr := RestoreTableOptimizerHint(hint) if p.Ctx != nil { + hintStr := RestoreTableOptimizerHint(hint) p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Hint %s is ignored due to unknown query block name", hintStr)) } continue