From 1f771e1a8ea94d93c90743e2e08d10d4cb9cfea6 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 588cc93d49d35..200dd705c03f8 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 0dc459ab9f67d..309ad7fd704d1 100644 --- a/util/hint/hint_processor.go +++ b/util/hint/hint_processor.go @@ -598,7 +598,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 974d0b135c69581fea5775b268e2b109d2cfc923 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 200dd705c03f8..7a9772a52d231 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 ef1f69b8a76d664d4c88e233e2dafe6f9996b63e 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 309ad7fd704d1..7164390cdad69 100644 --- a/util/hint/hint_processor.go +++ b/util/hint/hint_processor.go @@ -597,8 +597,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