From a8f56ee851f18e68065ddb9de09519bc1cd74a70 Mon Sep 17 00:00:00 2001
From: Chengpeng Yan <41809508+Reminiscent@users.noreply.github.com>
Date: Mon, 14 Nov 2022 12:01:54 +0800
Subject: [PATCH] planner: support the view hint (#38653)
close pingcap/tidb#37887
---
executor/infoschema_reader.go | 2 +-
executor/show.go | 2 +-
parser/hintparser.go | 616 +++++----
parser/hintparser.y | 39 +
planner/core/integration_test.go | 69 +
planner/core/logical_plan_builder.go | 81 +-
.../core/testdata/integration_suite_in.json | 67 +
.../core/testdata/integration_suite_out.json | 1192 +++++++++++++++++
util/hint/hint_processor.go | 93 +-
9 files changed, 1872 insertions(+), 289 deletions(-)
diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go
index 6d4e10c3a72a7..b3b881c1f65fa 100644
--- a/executor/infoschema_reader.go
+++ b/executor/infoschema_reader.go
@@ -835,7 +835,7 @@ func (e *hugeMemTableRetriever) dataForColumnsInTable(ctx context.Context, sctx
if err := runWithSystemSession(internalCtx, sctx, func(s sessionctx.Context) error {
planBuilder, _ := plannercore.NewPlanBuilder().Init(s, is, &hint.BlockHintProcessor{})
var err error
- viewLogicalPlan, err = planBuilder.BuildDataSourceFromView(ctx, schema.Name, tbl)
+ viewLogicalPlan, err = planBuilder.BuildDataSourceFromView(ctx, schema.Name, tbl, nil, nil)
return errors.Trace(err)
}); err != nil {
sctx.GetSessionVars().StmtCtx.AppendWarning(err)
diff --git a/executor/show.go b/executor/show.go
index 105dec9c54f7f..8ec62eac26c08 100644
--- a/executor/show.go
+++ b/executor/show.go
@@ -2020,7 +2020,7 @@ func tryFillViewColumnType(ctx context.Context, sctx sessionctx.Context, is info
// Retrieve view columns info.
planBuilder, _ := plannercore.NewPlanBuilder(
plannercore.PlanBuilderOptNoExecution{}).Init(s, is, &hint.BlockHintProcessor{})
- if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl); err == nil {
+ if viewLogicalPlan, err := planBuilder.BuildDataSourceFromView(ctx, dbName, tbl, nil, nil); err == nil {
viewSchema := viewLogicalPlan.Schema()
viewOutputNames := viewLogicalPlan.OutputNames()
for _, col := range tbl.Columns {
diff --git a/parser/hintparser.go b/parser/hintparser.go
index 4fc34fff27770..1b14e7d292e1e 100644
--- a/parser/hintparser.go
+++ b/parser/hintparser.go
@@ -124,95 +124,95 @@ const (
hintUseToja = 57401
yyhintMaxDepth = 200
- yyhintTabOfs = -188
+ yyhintTabOfs = -193
)
var (
yyhintXLAT = map[int]int{
- 41: 0, // ')' (138x)
- 57379: 1, // hintAggToCop (130x)
- 57394: 2, // hintBCJoin (130x)
- 57355: 3, // hintBKA (130x)
- 57357: 4, // hintBNL (130x)
- 57406: 5, // hintForceIndex (130x)
- 57381: 6, // hintHashAgg (130x)
- 57359: 7, // hintHashJoin (130x)
- 57360: 8, // hintHashJoinBuild (130x)
- 57361: 9, // hintHashJoinProbe (130x)
- 57384: 10, // hintIgnoreIndex (130x)
- 57380: 11, // hintIgnorePlanCache (130x)
- 57365: 12, // hintIndexMerge (130x)
- 57385: 13, // hintInlHashJoin (130x)
- 57386: 14, // hintInlJoin (130x)
- 57387: 15, // hintInlMergeJoin (130x)
- 57351: 16, // hintJoinFixedOrder (130x)
- 57352: 17, // hintJoinOrder (130x)
- 57353: 18, // hintJoinPrefix (130x)
- 57354: 19, // hintJoinSuffix (130x)
- 57408: 20, // hintLeading (130x)
- 57405: 21, // hintLimitToCop (130x)
- 57375: 22, // hintMaxExecutionTime (130x)
- 57388: 23, // hintMemoryQuota (130x)
- 57363: 24, // hintMerge (130x)
- 57382: 25, // hintMpp1PhaseAgg (130x)
- 57383: 26, // hintMpp2PhaseAgg (130x)
- 57367: 27, // hintMRR (130x)
- 57356: 28, // hintNoBKA (130x)
- 57358: 29, // hintNoBNL (130x)
- 57410: 30, // hintNoDecorrelate (130x)
- 57362: 31, // hintNoHashJoin (130x)
- 57369: 32, // hintNoICP (130x)
- 57366: 33, // hintNoIndexMerge (130x)
- 57364: 34, // hintNoMerge (130x)
- 57368: 35, // hintNoMRR (130x)
- 57370: 36, // hintNoRangeOptimization (130x)
- 57374: 37, // hintNoSemijoin (130x)
- 57372: 38, // hintNoSkipScan (130x)
- 57389: 39, // hintNoSwapJoinInputs (130x)
- 57404: 40, // hintNthPlan (130x)
- 57378: 41, // hintQBName (130x)
- 57390: 42, // hintQueryType (130x)
- 57391: 43, // hintReadConsistentReplica (130x)
- 57392: 44, // hintReadFromStorage (130x)
- 57377: 45, // hintResourceGroup (130x)
- 57373: 46, // hintSemijoin (130x)
- 57409: 47, // hintSemiJoinRewrite (130x)
- 57376: 48, // hintSetVar (130x)
- 57395: 49, // hintShuffleJoin (130x)
- 57371: 50, // hintSkipScan (130x)
- 57393: 51, // hintSMJoin (130x)
- 57407: 52, // hintStraightJoin (130x)
- 57396: 53, // hintStreamAgg (130x)
- 57397: 54, // hintSwapJoinInputs (130x)
- 57402: 55, // hintTimeRange (130x)
- 57403: 56, // hintUseCascades (130x)
- 57399: 57, // hintUseIndex (130x)
- 57398: 58, // hintUseIndexMerge (130x)
- 57400: 59, // hintUsePlanCache (130x)
- 57401: 60, // hintUseToja (130x)
- 44: 61, // ',' (128x)
- 57420: 62, // hintDupsWeedOut (108x)
- 57421: 63, // hintFirstMatch (108x)
- 57422: 64, // hintLooseScan (108x)
- 57423: 65, // hintMaterialization (108x)
- 57415: 66, // hintTiFlash (108x)
- 57414: 67, // hintTiKV (108x)
- 57416: 68, // hintFalse (107x)
- 57411: 69, // hintOLAP (107x)
- 57412: 70, // hintOLTP (107x)
- 57417: 71, // hintTrue (107x)
- 57419: 72, // hintGB (106x)
- 57418: 73, // hintMB (106x)
- 57347: 74, // hintIdentifier (105x)
- 57349: 75, // hintSingleAtIdentifier (90x)
+ 41: 0, // ')' (146x)
+ 57379: 1, // hintAggToCop (133x)
+ 57394: 2, // hintBCJoin (133x)
+ 57355: 3, // hintBKA (133x)
+ 57357: 4, // hintBNL (133x)
+ 57406: 5, // hintForceIndex (133x)
+ 57381: 6, // hintHashAgg (133x)
+ 57359: 7, // hintHashJoin (133x)
+ 57360: 8, // hintHashJoinBuild (133x)
+ 57361: 9, // hintHashJoinProbe (133x)
+ 57384: 10, // hintIgnoreIndex (133x)
+ 57380: 11, // hintIgnorePlanCache (133x)
+ 57365: 12, // hintIndexMerge (133x)
+ 57385: 13, // hintInlHashJoin (133x)
+ 57386: 14, // hintInlJoin (133x)
+ 57387: 15, // hintInlMergeJoin (133x)
+ 57351: 16, // hintJoinFixedOrder (133x)
+ 57352: 17, // hintJoinOrder (133x)
+ 57353: 18, // hintJoinPrefix (133x)
+ 57354: 19, // hintJoinSuffix (133x)
+ 57408: 20, // hintLeading (133x)
+ 57405: 21, // hintLimitToCop (133x)
+ 57375: 22, // hintMaxExecutionTime (133x)
+ 57388: 23, // hintMemoryQuota (133x)
+ 57363: 24, // hintMerge (133x)
+ 57382: 25, // hintMpp1PhaseAgg (133x)
+ 57383: 26, // hintMpp2PhaseAgg (133x)
+ 57367: 27, // hintMRR (133x)
+ 57356: 28, // hintNoBKA (133x)
+ 57358: 29, // hintNoBNL (133x)
+ 57410: 30, // hintNoDecorrelate (133x)
+ 57362: 31, // hintNoHashJoin (133x)
+ 57369: 32, // hintNoICP (133x)
+ 57366: 33, // hintNoIndexMerge (133x)
+ 57364: 34, // hintNoMerge (133x)
+ 57368: 35, // hintNoMRR (133x)
+ 57370: 36, // hintNoRangeOptimization (133x)
+ 57374: 37, // hintNoSemijoin (133x)
+ 57372: 38, // hintNoSkipScan (133x)
+ 57389: 39, // hintNoSwapJoinInputs (133x)
+ 57404: 40, // hintNthPlan (133x)
+ 57378: 41, // hintQBName (133x)
+ 57390: 42, // hintQueryType (133x)
+ 57391: 43, // hintReadConsistentReplica (133x)
+ 57392: 44, // hintReadFromStorage (133x)
+ 57377: 45, // hintResourceGroup (133x)
+ 57373: 46, // hintSemijoin (133x)
+ 57409: 47, // hintSemiJoinRewrite (133x)
+ 57376: 48, // hintSetVar (133x)
+ 57395: 49, // hintShuffleJoin (133x)
+ 57371: 50, // hintSkipScan (133x)
+ 57393: 51, // hintSMJoin (133x)
+ 57407: 52, // hintStraightJoin (133x)
+ 57396: 53, // hintStreamAgg (133x)
+ 57397: 54, // hintSwapJoinInputs (133x)
+ 57402: 55, // hintTimeRange (133x)
+ 57403: 56, // hintUseCascades (133x)
+ 57399: 57, // hintUseIndex (133x)
+ 57398: 58, // hintUseIndexMerge (133x)
+ 57400: 59, // hintUsePlanCache (133x)
+ 57401: 60, // hintUseToja (133x)
+ 44: 61, // ',' (130x)
+ 57420: 62, // hintDupsWeedOut (110x)
+ 57421: 63, // hintFirstMatch (110x)
+ 57422: 64, // hintLooseScan (110x)
+ 57423: 65, // hintMaterialization (110x)
+ 57415: 66, // hintTiFlash (110x)
+ 57414: 67, // hintTiKV (110x)
+ 57416: 68, // hintFalse (109x)
+ 57411: 69, // hintOLAP (109x)
+ 57412: 70, // hintOLTP (109x)
+ 57417: 71, // hintTrue (109x)
+ 57419: 72, // hintGB (108x)
+ 57418: 73, // hintMB (108x)
+ 57347: 74, // hintIdentifier (107x)
+ 57349: 75, // hintSingleAtIdentifier (93x)
93: 76, // ']' (84x)
- 57413: 77, // hintPartition (78x)
- 46: 78, // '.' (74x)
+ 46: 77, // '.' (83x)
+ 57413: 78, // hintPartition (78x)
61: 79, // '=' (74x)
40: 80, // '(' (69x)
- 57344: 81, // $end (24x)
- 57444: 82, // QueryBlockOpt (17x)
- 57436: 83, // Identifier (13x)
+ 57344: 81, // $end (25x)
+ 57444: 82, // QueryBlockOpt (20x)
+ 57436: 83, // Identifier (15x)
57346: 84, // hintIntLit (8x)
57350: 85, // hintStringLit (5x)
57426: 86, // CommaOpt (4x)
@@ -235,21 +235,23 @@ var (
57453: 103, // TableOptimizerHintOpt (2x)
57455: 104, // UnsupportedIndexLevelOptimizerHintName (2x)
57456: 105, // UnsupportedTableLevelOptimizerHintName (2x)
- 57428: 106, // HintQueryType (1x)
- 57431: 107, // HintStorageTypeAndTableList (1x)
- 57435: 108, // HintTrueOrFalse (1x)
- 57437: 109, // IndexNameList (1x)
- 57438: 110, // IndexNameListOpt (1x)
- 57441: 111, // OptimizerHintList (1x)
- 57442: 112, // PartitionList (1x)
- 57445: 113, // Start (1x)
- 57448: 114, // SubqueryStrategies (1x)
- 57449: 115, // SubqueryStrategiesOpt (1x)
- 57454: 116, // UnitOfBytes (1x)
- 57457: 117, // Value (1x)
- 57424: 118, // $default (0x)
- 57345: 119, // error (0x)
- 57348: 120, // hintInvalid (0x)
+ 57458: 106, // ViewName (2x)
+ 57428: 107, // HintQueryType (1x)
+ 57431: 108, // HintStorageTypeAndTableList (1x)
+ 57435: 109, // HintTrueOrFalse (1x)
+ 57437: 110, // IndexNameList (1x)
+ 57438: 111, // IndexNameListOpt (1x)
+ 57441: 112, // OptimizerHintList (1x)
+ 57442: 113, // PartitionList (1x)
+ 57445: 114, // Start (1x)
+ 57448: 115, // SubqueryStrategies (1x)
+ 57449: 116, // SubqueryStrategiesOpt (1x)
+ 57454: 117, // UnitOfBytes (1x)
+ 57457: 118, // Value (1x)
+ 57459: 119, // ViewNameList (1x)
+ 57424: 120, // $default (0x)
+ 57345: 121, // error (0x)
+ 57348: 122, // hintInvalid (0x)
}
yyhintSymNames = []string{
@@ -330,8 +332,8 @@ var (
"hintIdentifier",
"hintSingleAtIdentifier",
"']'",
- "hintPartition",
"'.'",
+ "hintPartition",
"'='",
"'('",
"$end",
@@ -359,6 +361,7 @@ var (
"TableOptimizerHintOpt",
"UnsupportedIndexLevelOptimizerHintName",
"UnsupportedTableLevelOptimizerHintName",
+ "ViewName",
"HintQueryType",
"HintStorageTypeAndTableList",
"HintTrueOrFalse",
@@ -371,6 +374,7 @@ var (
"SubqueryStrategiesOpt",
"UnitOfBytes",
"Value",
+ "ViewNameList",
"$default",
"error",
"hintInvalid",
@@ -378,11 +382,11 @@ var (
yyhintReductions = []struct{ xsym, components int }{
{0, 1},
- {113, 1},
- {111, 1},
- {111, 3},
- {111, 1},
- {111, 3},
+ {114, 1},
+ {112, 1},
+ {112, 3},
+ {112, 1},
+ {112, 3},
{103, 4},
{103, 4},
{103, 4},
@@ -397,12 +401,13 @@ var (
{103, 4},
{103, 6},
{103, 6},
+ {103, 6},
{103, 5},
{103, 4},
{103, 5},
{98, 5},
- {107, 1},
- {107, 3},
+ {108, 1},
+ {108, 3},
{93, 4},
{82, 0},
{82, 1},
@@ -410,30 +415,34 @@ var (
{86, 1},
{97, 0},
{97, 4},
- {112, 1},
- {112, 3},
+ {113, 1},
+ {113, 3},
{94, 1},
{94, 1},
{88, 2},
{88, 3},
{87, 3},
{87, 5},
+ {119, 3},
+ {119, 1},
+ {106, 2},
+ {106, 1},
{91, 4},
- {110, 0},
+ {111, 0},
+ {111, 1},
{110, 1},
- {109, 1},
- {109, 3},
- {115, 0},
+ {110, 3},
+ {116, 0},
+ {116, 1},
{115, 1},
- {114, 1},
- {114, 3},
- {117, 1},
+ {115, 3},
+ {118, 1},
+ {118, 1},
+ {118, 1},
{117, 1},
{117, 1},
- {116, 1},
- {116, 1},
- {108, 1},
- {108, 1},
+ {109, 1},
+ {109, 1},
{95, 1},
{95, 1},
{95, 1},
@@ -488,8 +497,8 @@ var (
{96, 1},
{96, 1},
{96, 1},
- {106, 1},
- {106, 1},
+ {107, 1},
+ {107, 1},
{92, 1},
{92, 1},
{83, 1},
@@ -569,35 +578,35 @@ var (
yyhintXErrors = map[yyhintXError]string{}
- yyhintParseTab = [271][]uint16{
+ yyhintParseTab = [280][]uint16{
// 0
- {1: 253, 221, 214, 216, 243, 249, 229, 230, 231, 241, 257, 233, 225, 223, 228, 193, 211, 212, 213, 232, 254, 200, 205, 224, 250, 251, 234, 215, 217, 260, 218, 236, 255, 219, 235, 237, 245, 239, 227, 201, 204, 209, 256, 210, 203, 244, 259, 202, 222, 238, 220, 258, 252, 226, 206, 247, 240, 242, 248, 246, 90: 207, 95: 194, 208, 98: 192, 199, 101: 198, 196, 191, 197, 195, 111: 190, 113: 189},
- {81: 188},
- {1: 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 356, 81: 187, 86: 456},
- {1: 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 81: 186},
- {1: 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 81: 184},
+ {1: 258, 226, 219, 221, 248, 254, 234, 235, 236, 246, 262, 238, 230, 228, 233, 198, 216, 217, 218, 237, 259, 205, 210, 229, 255, 256, 239, 220, 222, 265, 223, 241, 260, 224, 240, 242, 250, 244, 232, 206, 209, 214, 261, 215, 208, 249, 264, 207, 227, 243, 225, 263, 257, 231, 211, 252, 245, 247, 253, 251, 90: 212, 95: 199, 213, 98: 197, 204, 101: 203, 201, 196, 202, 200, 112: 195, 114: 194},
+ {81: 193},
+ {1: 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 361, 81: 192, 86: 470},
+ {1: 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 81: 191},
+ {1: 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 81: 189},
// 5
+ {80: 467},
+ {80: 464},
+ {80: 461},
+ {80: 456},
{80: 453},
- {80: 450},
- {80: 447},
- {80: 442},
- {80: 439},
// 10
- {80: 428},
- {80: 416},
- {80: 412},
- {80: 408},
- {80: 400},
+ {80: 442},
+ {80: 430},
+ {80: 426},
+ {80: 422},
+ {80: 414},
// 15
- {80: 397},
- {80: 394},
+ {80: 411},
+ {80: 399},
+ {80: 392},
{80: 387},
- {80: 382},
- {80: 376},
+ {80: 381},
// 20
- {80: 373},
- {80: 367},
- {80: 261},
+ {80: 378},
+ {80: 372},
+ {80: 266},
{80: 131},
{80: 130},
// 25
@@ -658,22 +667,22 @@ var (
{80: 80},
{80: 79},
{80: 78},
- {66: 161, 161, 75: 263, 82: 262},
- {66: 268, 267, 92: 266, 265, 107: 264},
+ {66: 165, 165, 75: 268, 82: 267},
+ {66: 273, 272, 92: 271, 270, 108: 269},
// 75
- {160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 76: 160, 160, 84: 160},
- {364, 61: 365},
- {164, 61: 164},
- {89: 269},
+ {164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 76: 164, 164, 164, 84: 164},
+ {369, 61: 370},
+ {168, 61: 168},
+ {89: 274},
{89: 75},
// 80
{89: 74},
- {1: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 271, 88: 270},
- {61: 362, 76: 361},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 273, 87: 272},
- {151, 61: 151, 76: 151},
+ {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 276, 88: 275},
+ {61: 367, 76: 366},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 278, 87: 277},
+ {155, 61: 155, 76: 155},
// 85
- {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 161, 161, 348, 82: 347},
+ {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 165, 353, 165, 82: 352},
{73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73},
{72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72},
{71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71},
@@ -761,141 +770,151 @@ var (
{3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
- {157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 76: 157, 351, 97: 360},
+ {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 76: 161, 78: 356, 97: 365},
// 160
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 349},
- {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 161, 161, 82: 350},
- {157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 76: 157, 351, 97: 352},
- {80: 353},
- {148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 76: 148},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 354},
+ {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 165, 78: 165, 82: 355},
+ {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 76: 161, 78: 356, 97: 357},
+ {80: 358},
+ {152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 76: 152},
// 165
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 355, 112: 354},
- {357, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 356, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 86: 358},
- {155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155},
- {158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 62: 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 85: 158},
- {156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 76: 156},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 360, 113: 359},
+ {362, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 361, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 86: 363},
+ {159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159},
+ {162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 62: 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 85: 162},
+ {160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 76: 160},
// 170
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 359},
- {154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154},
- {149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 76: 149},
- {162, 61: 162},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 273, 87: 363},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 364},
+ {158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158},
+ {153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 76: 153},
+ {166, 61: 166},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 278, 87: 368},
// 175
- {150, 61: 150, 76: 150},
- {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 81: 165},
- {66: 268, 267, 92: 266, 366},
- {163, 61: 163},
- {69: 161, 161, 75: 263, 82: 368},
+ {154, 61: 154, 76: 154},
+ {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 81: 169},
+ {66: 273, 272, 92: 271, 371},
+ {167, 61: 167},
+ {69: 165, 165, 75: 268, 82: 373},
// 180
- {69: 370, 371, 106: 369},
- {372},
+ {69: 375, 376, 107: 374},
+ {377},
{77},
{76},
- {1: 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 81: 166},
+ {1: 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 81: 170},
// 185
- {161, 75: 263, 82: 374},
- {375},
- {1: 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 81: 167},
- {68: 161, 71: 161, 75: 263, 82: 377},
- {68: 380, 71: 379, 108: 378},
+ {165, 75: 268, 82: 379},
+ {380},
+ {1: 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 81: 171},
+ {68: 165, 71: 165, 75: 268, 82: 382},
+ {68: 385, 71: 384, 109: 383},
// 190
- {381},
+ {386},
{133},
{132},
- {1: 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 81: 168},
- {85: 383},
+ {1: 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 81: 172},
+ {85: 388},
// 195
- {61: 356, 85: 159, 384},
- {85: 385},
- {386},
- {1: 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 81: 169},
- {75: 263, 82: 388, 84: 161},
+ {61: 361, 85: 163, 389},
+ {85: 390},
+ {391},
+ {1: 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 81: 173},
+ {75: 268, 82: 393, 84: 165},
// 200
- {84: 389},
- {72: 392, 391, 116: 390},
- {393},
+ {84: 394},
+ {72: 397, 396, 117: 395},
+ {398},
{135},
{134},
// 205
- {1: 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 81: 170},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 395},
- {396},
- {1: 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 81: 171},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 398},
+ {1: 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 81: 174},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 400},
+ {401, 61: 402},
+ {1: 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 81: 176},
+ {165, 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 268, 77: 165, 82: 406, 405, 106: 404, 119: 403},
// 210
- {399},
- {1: 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 81: 172},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 401},
- {79: 402},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 405, 406, 404, 117: 403},
+ {408, 77: 409},
+ {150, 77: 150},
+ {165, 75: 268, 77: 165, 82: 407},
+ {148, 77: 148},
+ {149, 77: 149},
// 215
- {407},
+ {1: 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 81: 175},
+ {165, 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 268, 77: 165, 82: 406, 405, 106: 410},
+ {151, 77: 151},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 412},
+ {413},
+ // 220
+ {1: 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 81: 177},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 415},
+ {79: 416},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 419, 420, 418, 118: 417},
+ {421},
+ // 225
{138},
{137},
{136},
- {1: 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 81: 173},
- // 220
- {75: 263, 82: 409, 84: 161},
- {84: 410},
- {411},
- {1: 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 81: 174},
- {75: 263, 82: 413, 84: 161},
- // 225
- {84: 414},
- {415},
- {1: 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 81: 175},
- {161, 62: 161, 161, 161, 161, 75: 263, 82: 417},
- {142, 62: 421, 422, 423, 424, 100: 420, 114: 419, 418},
+ {1: 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 81: 178},
+ {75: 268, 82: 423, 84: 165},
// 230
- {427},
- {141, 61: 425},
+ {84: 424},
+ {425},
+ {1: 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 81: 179},
+ {75: 268, 82: 427, 84: 165},
+ {84: 428},
+ // 235
+ {429},
+ {1: 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 81: 180},
+ {165, 62: 165, 165, 165, 165, 75: 268, 82: 431},
+ {142, 62: 435, 436, 437, 438, 100: 434, 115: 433, 432},
+ {441},
+ // 240
+ {141, 61: 439},
{140, 61: 140},
{96, 61: 96},
{95, 61: 95},
- // 235
{94, 61: 94},
+ // 245
{93, 61: 93},
- {62: 421, 422, 423, 424, 100: 426},
+ {62: 435, 436, 437, 438, 100: 440},
{139, 61: 139},
- {1: 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 81: 176},
- // 240
- {1: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 430, 91: 429},
- {438},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 273, 87: 431},
- {159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 356, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 86: 432},
- {146, 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 435, 109: 434, 433},
- // 245
+ {1: 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 81: 181},
+ {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 444, 91: 443},
+ // 250
+ {452},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 278, 87: 445},
+ {163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 361, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 86: 446},
+ {146, 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 449, 110: 448, 447},
{147},
- {145, 61: 436},
+ // 255
+ {145, 61: 450},
{144, 61: 144},
- {1: 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 437},
+ {1: 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 451},
{143, 61: 143},
- // 250
- {1: 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 81: 177},
- {1: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 430, 91: 440},
- {441},
- {1: 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 81: 178},
- {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 445, 88: 444, 94: 443},
- // 255
- {446},
- {153, 61: 362},
- {152, 303, 319, 279, 281, 330, 306, 283, 284, 285, 309, 305, 289, 310, 311, 312, 275, 276, 277, 278, 332, 304, 299, 313, 287, 307, 308, 291, 280, 282, 334, 286, 293, 290, 288, 292, 294, 298, 296, 314, 329, 302, 315, 316, 317, 301, 297, 333, 300, 320, 295, 318, 331, 321, 322, 327, 328, 324, 323, 325, 326, 62: 343, 344, 345, 346, 338, 337, 339, 335, 336, 340, 342, 341, 274, 83: 273, 87: 272},
- {1: 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 81: 179},
- {161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 445, 88: 444, 94: 448},
+ {1: 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 81: 182},
// 260
- {449},
- {1: 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 81: 180},
- {1: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 62: 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 263, 82: 271, 88: 451},
- {452, 61: 362},
- {1: 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 81: 181},
- // 265
- {161, 75: 263, 82: 454},
+ {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 444, 91: 454},
{455},
- {1: 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 81: 182},
- {1: 253, 221, 214, 216, 243, 249, 229, 230, 231, 241, 257, 233, 225, 223, 228, 193, 211, 212, 213, 232, 254, 200, 205, 224, 250, 251, 234, 215, 217, 260, 218, 236, 255, 219, 235, 237, 245, 239, 227, 201, 204, 209, 256, 210, 203, 244, 259, 202, 222, 238, 220, 258, 252, 226, 206, 247, 240, 242, 248, 246, 90: 207, 95: 194, 208, 98: 458, 199, 101: 198, 196, 457, 197, 195},
- {1: 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 81: 185},
- // 270
{1: 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 81: 183},
+ {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 459, 88: 458, 94: 457},
+ {460},
+ // 265
+ {157, 61: 367},
+ {156, 308, 324, 284, 286, 335, 311, 288, 289, 290, 314, 310, 294, 315, 316, 317, 280, 281, 282, 283, 337, 309, 304, 318, 292, 312, 313, 296, 285, 287, 339, 291, 298, 295, 293, 297, 299, 303, 301, 319, 334, 307, 320, 321, 322, 306, 302, 338, 305, 325, 300, 323, 336, 326, 327, 332, 333, 329, 328, 330, 331, 62: 348, 349, 350, 351, 343, 342, 344, 340, 341, 345, 347, 346, 279, 83: 278, 87: 277},
+ {1: 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 81: 184},
+ {165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 459, 88: 458, 94: 462},
+ {463},
+ // 270
+ {1: 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 81: 185},
+ {1: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 62: 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 268, 82: 276, 88: 465},
+ {466, 61: 367},
+ {1: 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 81: 186},
+ {165, 75: 268, 82: 468},
+ // 275
+ {469},
+ {1: 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 81: 187},
+ {1: 258, 226, 219, 221, 248, 254, 234, 235, 236, 246, 262, 238, 230, 228, 233, 198, 216, 217, 218, 237, 259, 205, 210, 229, 255, 256, 239, 220, 222, 265, 223, 241, 260, 224, 240, 242, 250, 244, 232, 206, 209, 214, 261, 215, 208, 249, 264, 207, 227, 243, 225, 263, 257, 231, 211, 252, 245, 247, 253, 251, 90: 212, 95: 199, 213, 98: 472, 204, 101: 203, 201, 471, 202, 200},
+ {1: 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 81: 190},
+ {1: 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 81: 188},
}
)
@@ -935,7 +954,7 @@ func yyhintlex1(yylex yyhintLexer, lval *yyhintSymType) (n int) {
}
func yyhintParse(yylex yyhintLexer, parser *hintParser) int {
- const yyError = 119
+ const yyError = 121
yyEx, _ := yylex.(yyhintLexerEx)
var yyn int
@@ -1212,6 +1231,14 @@ yynewstate:
}
}
case 18:
+ {
+ parser.yyVAL.hint = &ast.TableOptimizerHint{
+ HintName: model.NewCIStr(yyS[yypt-5].ident),
+ QBName: model.NewCIStr(yyS[yypt-3].ident),
+ Tables: yyS[yypt-1].hint.Tables,
+ }
+ }
+ case 19:
{
maxValue := uint64(math.MaxInt64) / yyS[yypt-1].number
if yyS[yypt-2].number <= maxValue {
@@ -1226,7 +1253,7 @@ yynewstate:
parser.yyVAL.hint = nil
}
}
- case 19:
+ case 20:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-5].ident),
@@ -1236,21 +1263,21 @@ yynewstate:
},
}
}
- case 20:
+ case 21:
{
h := yyS[yypt-1].hint
h.HintName = model.NewCIStr(yyS[yypt-4].ident)
h.QBName = model.NewCIStr(yyS[yypt-2].ident)
parser.yyVAL.hint = h
}
- case 21:
+ case 22:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-3].ident),
QBName: model.NewCIStr(yyS[yypt-1].ident),
}
}
- case 22:
+ case 23:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-4].ident),
@@ -1258,7 +1285,7 @@ yynewstate:
HintData: model.NewCIStr(yyS[yypt-1].ident),
}
}
- case 23:
+ case 24:
{
hs := yyS[yypt-1].hints
name := model.NewCIStr(yyS[yypt-4].ident)
@@ -1269,60 +1296,60 @@ yynewstate:
}
parser.yyVAL.hints = hs
}
- case 24:
+ case 25:
{
parser.yyVAL.hints = []*ast.TableOptimizerHint{yyS[yypt-0].hint}
}
- case 25:
+ case 26:
{
parser.yyVAL.hints = append(yyS[yypt-2].hints, yyS[yypt-0].hint)
}
- case 26:
+ case 27:
{
h := yyS[yypt-1].hint
h.HintData = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
- case 27:
+ case 28:
{
parser.yyVAL.ident = ""
}
- case 31:
+ case 32:
{
parser.yyVAL.modelIdents = nil
}
- case 32:
+ case 33:
{
parser.yyVAL.modelIdents = yyS[yypt-1].modelIdents
}
- case 33:
+ case 34:
{
parser.yyVAL.modelIdents = []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)}
}
- case 34:
+ case 35:
{
parser.yyVAL.modelIdents = append(yyS[yypt-2].modelIdents, model.NewCIStr(yyS[yypt-0].ident))
}
- case 36:
+ case 37:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
QBName: model.NewCIStr(yyS[yypt-0].ident),
}
}
- case 37:
+ case 38:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
Tables: []ast.HintTable{yyS[yypt-0].table},
QBName: model.NewCIStr(yyS[yypt-1].ident),
}
}
- case 38:
+ case 39:
{
h := yyS[yypt-2].hint
h.Tables = append(h.Tables, yyS[yypt-0].table)
parser.yyVAL.hint = h
}
- case 39:
+ case 40:
{
parser.yyVAL.table = ast.HintTable{
TableName: model.NewCIStr(yyS[yypt-2].ident),
@@ -1330,7 +1357,7 @@ yynewstate:
PartitionList: yyS[yypt-0].modelIdents,
}
}
- case 40:
+ case 41:
{
parser.yyVAL.table = ast.HintTable{
DBName: model.NewCIStr(yyS[yypt-4].ident),
@@ -1339,46 +1366,71 @@ yynewstate:
PartitionList: yyS[yypt-0].modelIdents,
}
}
- case 41:
+ case 42:
+ {
+ h := yyS[yypt-2].hint
+ h.Tables = append(h.Tables, yyS[yypt-0].table)
+ parser.yyVAL.hint = h
+ }
+ case 43:
+ {
+ parser.yyVAL.hint = &ast.TableOptimizerHint{
+ Tables: []ast.HintTable{yyS[yypt-0].table},
+ }
+ }
+ case 44:
+ {
+ parser.yyVAL.table = ast.HintTable{
+ TableName: model.NewCIStr(yyS[yypt-1].ident),
+ QBName: model.NewCIStr(yyS[yypt-0].ident),
+ }
+ }
+ case 45:
+ {
+ parser.yyVAL.table = ast.HintTable{
+ QBName: model.NewCIStr(yyS[yypt-0].ident),
+ }
+ }
+ case 46:
{
h := yyS[yypt-0].hint
h.Tables = []ast.HintTable{yyS[yypt-2].table}
h.QBName = model.NewCIStr(yyS[yypt-3].ident)
parser.yyVAL.hint = h
}
- case 42:
+ case 47:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{}
}
- case 44:
+ case 49:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
Indexes: []model.CIStr{model.NewCIStr(yyS[yypt-0].ident)},
}
}
- case 45:
+ case 50:
{
h := yyS[yypt-2].hint
h.Indexes = append(h.Indexes, model.NewCIStr(yyS[yypt-0].ident))
parser.yyVAL.hint = h
}
- case 52:
+ case 57:
{
parser.yyVAL.ident = strconv.FormatUint(yyS[yypt-0].number, 10)
}
- case 53:
+ case 58:
{
parser.yyVAL.number = 1024 * 1024
}
- case 54:
+ case 59:
{
parser.yyVAL.number = 1024 * 1024 * 1024
}
- case 55:
+ case 60:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{HintData: true}
}
- case 56:
+ case 61:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{HintData: false}
}
diff --git a/parser/hintparser.y b/parser/hintparser.y
index 25672393f13c3..a2ccd21d2d401 100644
--- a/parser/hintparser.y
+++ b/parser/hintparser.y
@@ -162,6 +162,7 @@ import (
HintIndexList "table name with index list in optimizer hint"
IndexNameList "index list in optimizer hint"
IndexNameListOpt "optional index list in optimizer hint"
+ ViewNameList "view name list in optimizer hint"
SubqueryStrategies "subquery strategies"
SubqueryStrategiesOpt "optional subquery strategies"
HintTrueOrFalse "true or false in optimizer hint"
@@ -169,6 +170,7 @@ import (
%type
HintTable "Table in optimizer hint"
+ ViewName "View name in optimizer hint"
%type
PartitionList "partition name list in optimizer hint"
@@ -285,6 +287,14 @@ TableOptimizerHintOpt:
QBName: model.NewCIStr($3),
}
}
+| "QB_NAME" '(' Identifier ',' ViewNameList ')'
+ {
+ $$ = &ast.TableOptimizerHint{
+ HintName: model.NewCIStr($1),
+ QBName: model.NewCIStr($3),
+ Tables: $5.Tables,
+ }
+ }
| "MEMORY_QUOTA" '(' QueryBlockOpt hintIntLit UnitOfBytes ')'
{
maxValue := uint64(math.MaxInt64) / $5
@@ -447,6 +457,35 @@ HintTable:
}
}
+ViewNameList:
+ ViewNameList '.' ViewName
+ {
+ h := $1
+ h.Tables = append(h.Tables, $3)
+ $$ = h
+ }
+| ViewName
+ {
+ $$ = &ast.TableOptimizerHint{
+ Tables: []ast.HintTable{$1},
+ }
+ }
+
+ViewName:
+ Identifier QueryBlockOpt
+ {
+ $$ = ast.HintTable{
+ TableName: model.NewCIStr($1),
+ QBName: model.NewCIStr($2),
+ }
+ }
+| QueryBlockOpt
+ {
+ $$ = ast.HintTable{
+ QBName: model.NewCIStr($1),
+ }
+ }
+
/**
* HintIndexList:
*
diff --git a/planner/core/integration_test.go b/planner/core/integration_test.go
index 9e414e943672a..2afc708834311 100644
--- a/planner/core/integration_test.go
+++ b/planner/core/integration_test.go
@@ -1324,6 +1324,75 @@ func TestReadFromStorageHint(t *testing.T) {
}
}
+func TestViewHint(t *testing.T) {
+ store := testkit.CreateMockStore(t)
+ tk := testkit.NewTestKit(t, store)
+
+ tk.MustExec("use test")
+ tk.MustExec("drop view if exists v, v1")
+ tk.MustExec("drop table if exists t, t1, t2")
+ tk.MustExec("create table t(a int, b int);")
+ tk.MustExec("create table t1(a int, b int);")
+ tk.MustExec("create table t2(a int, b int);")
+ tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join (select count(*) as a from t1 join t2 on t1.b=t2.b group by t2.a) tt on t.a = tt.a;")
+ tk.MustExec("create definer='root'@'localhost' view v1 as select t.a, t.b from t join (select count(*) as a from t1 join v on t1.b=v.b group by v.a) tt on t.a = tt.a;")
+ tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;")
+
+ var input []string
+ var output []struct {
+ SQL string
+ Plan []string
+ Warn []string
+ }
+ integrationSuiteData := core.GetIntegrationSuiteData()
+ integrationSuiteData.LoadTestCases(t, &input, &output)
+ for i, tt := range input {
+ testdata.OnRecord(func() {
+ output[i].SQL = tt
+ output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows())
+ output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())
+ })
+ res := tk.MustQuery(tt)
+ res.Check(testkit.Rows(output[i].Plan...))
+ require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()))
+ }
+}
+
+func TestViewHintScope(t *testing.T) {
+ store := testkit.CreateMockStore(t)
+ tk := testkit.NewTestKit(t, store)
+
+ tk.MustExec("use test")
+ tk.MustExec("drop view if exists v, v1")
+ tk.MustExec("drop table if exists t, t1, t2")
+ tk.MustExec("create table t(a int, b int);")
+ tk.MustExec("create table t1(a int, b int);")
+ tk.MustExec("create table t2(a int, b int);")
+ tk.MustExec("create table t3(a int, b int)")
+ tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join (select count(*) as a from t1 join t2 join t3 where t1.b=t2.b and t2.a = t3.a group by t2.a) tt on t.a = tt.a;")
+ tk.MustExec("create definer='root'@'localhost' view v1 as select t.a, t.b from t join (select count(*) as a from t1 join v on t1.b=v.b group by v.a) tt on t.a = tt.a;")
+ tk.MustExec("create definer='root'@'localhost' view v2 as select t.a, t.b from t join (select count(*) as a from t1 join v1 on t1.b=v1.b group by v1.a) tt on t.a = tt.a;")
+
+ var input []string
+ var output []struct {
+ SQL string
+ Plan []string
+ Warn []string
+ }
+ integrationSuiteData := core.GetIntegrationSuiteData()
+ integrationSuiteData.LoadTestCases(t, &input, &output)
+ for i, tt := range input {
+ testdata.OnRecord(func() {
+ output[i].SQL = tt
+ output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(tt).Rows())
+ output[i].Warn = testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings())
+ })
+ res := tk.MustQuery(tt)
+ res.Check(testkit.Rows(output[i].Plan...))
+ require.Equal(t, output[i].Warn, testdata.ConvertSQLWarnToStrings(tk.Session().GetSessionVars().StmtCtx.GetWarnings()))
+ }
+}
+
func TestReadFromStorageHintAndIsolationRead(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go
index 7e9d6c1a01cf8..18edbd52be994 100644
--- a/planner/core/logical_plan_builder.go
+++ b/planner/core/logical_plan_builder.go
@@ -59,6 +59,7 @@ import (
"github.com/pingcap/tidb/util/collate"
"github.com/pingcap/tidb/util/dbterror"
"github.com/pingcap/tidb/util/hack"
+ "github.com/pingcap/tidb/util/hint"
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/mathutil"
"github.com/pingcap/tidb/util/plancodec"
@@ -4411,7 +4412,36 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as
if tn.TableSample != nil {
return nil, expression.ErrInvalidTableSample.GenWithStackByArgs("Unsupported TABLESAMPLE in views")
}
- return b.BuildDataSourceFromView(ctx, dbName, tableInfo)
+
+ // Get the hints belong to the current view.
+ currentQBNameMap4View := make(map[string][]ast.HintTable)
+ currentViewHints := make(map[string][]*ast.TableOptimizerHint)
+ for qbName, viewQBNameHintTable := range b.hintProcessor.QbNameMap4View {
+ if len(viewQBNameHintTable) == 0 {
+ continue
+ }
+ viewSelectOffset := b.getSelectOffset()
+
+ var viewHintSelectOffset int
+ if viewQBNameHintTable[0].QBName.L == "" {
+ // If we do not explicit set the qbName, we will set the empty qb name to @sel_1.
+ viewHintSelectOffset = 1
+ } else {
+ viewHintSelectOffset = b.hintProcessor.GetHintOffset(viewQBNameHintTable[0].QBName, viewSelectOffset)
+ }
+
+ // Check whether the current view can match the view name in the hint.
+ if viewQBNameHintTable[0].TableName.L == tblName.L && viewHintSelectOffset == viewSelectOffset {
+ // If the view hint can match the current view, we pop the first view table in the query block hint's table list.
+ // It means the hint belong the current view, the first view name in hint is matched.
+ // Because of the nested views, so we should check the left table list in hint when build the data source from the view inside the current view.
+ currentQBNameMap4View[qbName] = viewQBNameHintTable[1:]
+ currentViewHints[qbName] = b.hintProcessor.QbHints4View[qbName]
+ delete(b.hintProcessor.QbNameMap4View, qbName)
+ delete(b.hintProcessor.QbHints4View, qbName)
+ }
+ }
+ return b.BuildDataSourceFromView(ctx, dbName, tableInfo, currentQBNameMap4View, currentViewHints)
}
if tableInfo.IsSequence() {
@@ -4941,7 +4971,10 @@ func (b *PlanBuilder) checkRecursiveView(dbName model.CIStr, tableName model.CIS
}
// BuildDataSourceFromView is used to build LogicalPlan from view
-func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.CIStr, tableInfo *model.TableInfo) (LogicalPlan, error) {
+// qbNameMap4View and viewHints are used for the view's hint.
+// qbNameMap4View maps the query block name to the view table lists.
+// viewHints group the view hints based on the view's query block name.
+func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.CIStr, tableInfo *model.TableInfo, qbNameMap4View map[string][]ast.HintTable, viewHints map[string][]*ast.TableOptimizerHint) (LogicalPlan, error) {
viewDepth := b.ctx.GetSessionVars().StmtCtx.ViewDepth
b.ctx.GetSessionVars().StmtCtx.ViewDepth++
deferFunc, err := b.checkRecursiveView(dbName, tableInfo.Name)
@@ -4976,6 +5009,50 @@ func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.
b.buildingCTE = o
}()
+ hintProcessor := &hint.BlockHintProcessor{Ctx: b.ctx}
+ selectNode.Accept(hintProcessor)
+ currentQbNameMap4View := make(map[string][]ast.HintTable)
+ currentQbHints4View := make(map[string][]*ast.TableOptimizerHint)
+ currentQbHints := make(map[int][]*ast.TableOptimizerHint)
+ currentQbNameMap := make(map[string]int)
+
+ for qbName, viewQbNameHint := range qbNameMap4View {
+ // Check whether the view hint belong the current view or its nested views.
+ selectOffset := -1
+ qbNameMap4View[qbName] = viewQbNameHint
+ if len(viewQbNameHint) == 0 {
+ selectOffset = 1
+ } else if len(viewQbNameHint) == 1 && viewQbNameHint[0].TableName.L == "" {
+ selectOffset = hintProcessor.GetHintOffset(viewQbNameHint[0].QBName, -1)
+ } else {
+ currentQbNameMap4View[qbName] = viewQbNameHint
+ currentQbHints4View[qbName] = viewHints[qbName]
+ }
+
+ if selectOffset != -1 {
+ // If the hint belongs to the current view and not belongs to it's nested views, we should convert the view hint to the normal hint.
+ // After we convert the view hint to the normal hint, it can be reused the origin hint's infrastructure.
+ currentQbHints[selectOffset] = viewHints[qbName]
+ currentQbNameMap[qbName] = selectOffset
+
+ delete(qbNameMap4View, qbName)
+ delete(viewHints, qbName)
+ }
+ }
+
+ hintProcessor.QbNameMap4View = qbNameMap4View
+ hintProcessor.QbHints4View = viewHints
+ hintProcessor.QbHints = currentQbHints
+ hintProcessor.QbNameMap = currentQbNameMap
+
+ originHintProcessor := b.hintProcessor
+ originPlannerSelectBlockAsName := b.ctx.GetSessionVars().PlannerSelectBlockAsName
+ b.hintProcessor = hintProcessor
+ b.ctx.GetSessionVars().PlannerSelectBlockAsName = make([]ast.HintTable, hintProcessor.MaxSelectStmtOffset()+1)
+ defer func() {
+ b.hintProcessor = originHintProcessor
+ b.ctx.GetSessionVars().PlannerSelectBlockAsName = originPlannerSelectBlockAsName
+ }()
selectLogicalPlan, err := b.Build(ctx, selectNode)
if err != nil {
if terror.ErrorNotEqual(err, ErrViewRecursive) &&
diff --git a/planner/core/testdata/integration_suite_in.json b/planner/core/testdata/integration_suite_in.json
index d820bdc629197..db677ac97d23c 100644
--- a/planner/core/testdata/integration_suite_in.json
+++ b/planner/core/testdata/integration_suite_in.json
@@ -653,6 +653,73 @@
"desc format = 'brief' select /*+ read_from_storage(tiflash[t, ttt], tikv[tt]) */ * from ttt"
]
},
+ {
+ "name": "TestViewHint",
+ "cases": [
+ // Hint for view v
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;",
+
+ // Hint for view v1
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v2;",
+
+ // Hint for view v2
+ "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2), stream_agg(@qb_v2_2), qb_name(qb_v2_1, v1@sel_1 .@sel_1), merge_join(t@qb_v2_1) */ * from v2;"
+ ]
+ },
+ {
+ "name": "TestViewHintScope",
+ "cases": [
+ // Same qb name in one query
+ "explain format = 'brief' select /*+ qb_name(qb_v, v@sel_1 .@sel_2), qb_name(qb_v, v@sel_1 .@sel_1), merge_join(t1@qb_v) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_2), qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_2), qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v2;",
+
+ // Set the unappeared view name
+ // TODO: add the warning for the unused the view hints
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
+
+ // Exist the view alias
+ "explain format = 'brief' select /*+ qb_name(qb_v2_2, vv@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
+ "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
+
+ // Tht view hint isn't set in the first query block.
+ "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v) t;",
+ "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v) t;",
+ "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1) t;",
+ "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1) t;",
+
+ // TODO: add the warning when the view hints don't set in the first query block
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v) t;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v) t;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v1) t;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v1) t;",
+
+ // Define more tables in one view hint
+ "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_1 .@sel_1), merge_join(t1@qb_v1_2, t@qb_v1_1) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t1@qb_v_2, t3@qb_v_2) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(@qb_v_2 t1, t3) */ * from v2;",
+
+ // Ignore the @sel_1 query block
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_1, v@sel_1), merge_join(t@qb_v_1) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_2, v1 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v_1, v1 .v@sel_2), merge_join(t@qb_v_1) */ * from v1;",
+
+ // Use the query block before define it
+ "explain format = 'brief' select /*+ merge_join(t1@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from v;",
+ "explain format = 'brief' select /*+ merge_join(t@qb_v_1), stream_agg(@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel1) */ * from v;"
+ ]
+ },
{
"name": "TestReadFromStorageHintAndIsolationRead",
"cases": [
diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json
index fa0eb12ccf0b5..c64c004266ffd 100644
--- a/planner/core/testdata/integration_suite_out.json
+++ b/planner/core/testdata/integration_suite_out.json
@@ -4355,6 +4355,1198 @@
}
]
},
+ {
+ "Name": "TestViewHint",
+ "Cases": [
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
+ "Plan": [
+ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#10)]",
+ "├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#10",
+ "│ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v;",
+ "Plan": [
+ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#10)]",
+ "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#10",
+ "│ └─Sort 12487.50 root test.t2.a",
+ "│ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#16)]",
+ "│ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16",
+ "│ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]",
+ "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#16",
+ "│ │ ├─Sort(Build) 7992.00 root Column#16",
+ "│ │ │ └─StreamAgg 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16",
+ "│ │ │ └─Sort 12487.50 root test.t2.a",
+ "│ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─Sort(Probe) 9980.01 root test.t.a",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]",
+ "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]",
+ "│ │ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#22",
+ "│ │ │ ├─Sort(Build) 7992.00 root Column#22",
+ "│ │ │ │ └─StreamAgg 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ │ └─Sort 12487.50 root test.t2.a",
+ "│ │ │ │ └─MergeJoin 12487.50 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ │ ├─Sort(Build) 9990.00 root test.t2.b",
+ "│ │ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9980.01 root test.t.a",
+ "│ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#17)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#17",
+ "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b",
+ "│ ├─Sort(Build) 9980.01 root test.t.b",
+ "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#16)]",
+ "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16",
+ "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v1;",
+ "Plan": [
+ "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#17",
+ "├─Sort(Build) 7984.01 root Column#17",
+ "│ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#17",
+ "│ └─Sort 12475.01 root test.t.a",
+ "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b",
+ "│ ├─Sort(Build) 9980.01 root test.t.b",
+ "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#16)]",
+ "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#16",
+ "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─Sort(Probe) 9990.00 root test.t.a",
+ " └─TableReader 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]",
+ "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), merge_join(t1@qb_v1_2), stream_agg(@qb_v1_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_1 .@sel_1), merge_join(t@qb_v1_1) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]",
+ "│ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b",
+ "│ ├─Sort(Build) 9980.01 root test.t.b",
+ "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]",
+ "│ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2), stream_agg(@qb_v2_2), qb_name(qb_v2_1, v1@sel_1 .@sel_1), merge_join(t@qb_v2_1) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#24)]",
+ "├─StreamAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#24",
+ "│ └─Sort 12475.01 root test.t.a",
+ "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b",
+ "│ ├─Sort(Build) 9980.01 root test.t.b",
+ "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#23)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#23",
+ "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#22)]",
+ "│ │ │ ├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#22",
+ "│ │ │ │ └─HashJoin 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]",
+ "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))",
+ "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ }
+ ]
+ },
+ {
+ "Name": "TestViewHintScope",
+ "Cases": [
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v@sel_1 .@sel_2), qb_name(qb_v, v@sel_1 .@sel_1), merge_join(t1@qb_v) */ * from v;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_2), qb_name(qb_v, v1@sel_1 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_2), qb_name(qb_v, v2@sel_1 .v1@sel_2 .v@sel_2 .@sel_1), merge_join(t1@qb_v) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Duplicate query block name qb_v for view's query block hint, only the first one is effective"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v@sel_1 .@sel_2), merge_join(t1@qb_v1_2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, vv@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t.b",
+ "│ ├─Sort(Build) 9980.01 root test.t.b",
+ "│ │ └─HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2_2, v2@sel_1 .@sel_2), merge_join(t1@qb_v2_2) */ * from v2 vv;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2) */ * from v) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v@sel_1 .@sel1), merge_join(t@qb_v_1) */ * from v) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint stream_agg(@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint merge_join(`t`@`qb_v_1`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select * from (select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), merge_join(t1@qb_v_2), stream_agg(@qb_v_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v1) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "The qb_name hint for view only supports to be defined in the first query block",
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint stream_agg(@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint merge_join(`t`@`qb_v_1`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint stream_agg(@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint merge_join(`t`@`qb_v_1`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2) */ * from (select /*+ merge_join(t1@qb_v_2) */ * from v1) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1@sel_1 . v@sel_2 .@sel_2), qb_name(qb_v_1, v1@sel_1 . v@sel_2 .@sel_1) */ * from (select /*+ merge_join(t1@qb_v_2), stream_agg(@qb_v_2), merge_join(t@qb_v_1) */ * from v1) t;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Hint merge_join(`t1`@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint stream_agg(@`qb_v_2`) is ignored due to unknown query block name",
+ "Hint merge_join(`t`@`qb_v_1`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1_2, v2@sel_1 . v1@sel_1 .@sel_2), qb_name(qb_v1_1, v2@sel_1 . v1@sel_1 .@sel_1), merge_join(t1@qb_v1_2, t@qb_v1_1) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": [
+ "Hint merge_join(`t1`@`qb_v1_2`, `t`@`qb_v1_1`) is ignored due to unknown query block name"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(t1@qb_v_2, t3@qb_v_2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─MergeJoin 15593.77 root inner join, left key:test.t2.a, right key:test.t3.a",
+ "│ │ │ ├─Sort(Build) 9990.00 root test.t3.a",
+ "│ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 12475.01 root test.t2.a",
+ "│ │ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_2), qb_name(qb_v_1, v2@sel_1 . v1@sel_2 . v@sel_2 .@sel_1), merge_join(@qb_v_2 t1, t3) */ * from v2;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#27)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#26)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#26",
+ "│ │ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#25)]",
+ "│ │ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#25",
+ "│ │ │ └─MergeJoin 15593.77 root inner join, left key:test.t2.a, right key:test.t3.a",
+ "│ │ │ ├─Sort(Build) 9990.00 root test.t3.a",
+ "│ │ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 12475.01 root test.t2.a",
+ "│ │ │ └─MergeJoin 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ │ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v .@sel_2), merge_join(t1@qb_v_2) */ * from v;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v@sel_1), merge_join(t@qb_v_1) */ * from v;",
+ "Plan": [
+ "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#13",
+ "├─Sort(Build) 7984.01 root Column#13",
+ "│ └─HashAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─Sort(Probe) 9990.00 root test.t.a",
+ " └─TableReader 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_2, v1 .v@sel_2 .@sel_2), merge_join(t1@qb_v_2) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "│ ├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ │ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ │ └─TableReader 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v_1, v1 .v@sel_2), merge_join(t@qb_v_1) */ * from v1;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#20)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t.a, funcs:count(1)->Column#20",
+ "│ └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b, test.t.b)]",
+ "│ ├─MergeJoin(Build) 9980.01 root inner join, left key:test.t.a, right key:Column#19",
+ "│ │ ├─Sort(Build) 7984.01 root Column#19",
+ "│ │ │ └─HashAgg 7984.01 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ │ │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ │ │ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ │ │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ │ │ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ │ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ │ │ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "│ │ └─Sort(Probe) 9980.01 root test.t.a",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t.a)), not(isnull(test.t.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ merge_join(t1@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2) */ * from v;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─HashAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t2.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─MergeJoin(Probe) 12475.01 root inner join, left key:test.t1.b, right key:test.t2.b",
+ "│ ├─Sort(Build) 9980.01 root test.t2.b",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 9990.00 root test.t1.b",
+ "│ └─TableReader 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ merge_join(t@qb_v_1), stream_agg(@qb_v_2), qb_name(qb_v_2, v@sel_1 .@sel_2), qb_name(qb_v_1, v@sel_1 .@sel1) */ * from v;",
+ "Plan": [
+ "HashJoin 9980.01 root inner join, equal:[eq(test.t.a, Column#13)]",
+ "├─StreamAgg(Build) 7984.01 root group by:test.t2.a, funcs:count(1)->Column#13",
+ "│ └─Sort 15593.77 root test.t2.a",
+ "│ └─HashJoin 15593.77 root inner join, equal:[eq(test.t2.a, test.t3.a)]",
+ "│ ├─TableReader(Build) 9990.00 root data:Selection",
+ "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 9990.00 root data:Selection",
+ "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))",
+ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 9990.00 root data:Selection",
+ " └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))",
+ " └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ }
+ ]
+ },
{
"Name": "TestReadFromStorageHintAndIsolationRead",
"Cases": [
diff --git a/util/hint/hint_processor.go b/util/hint/hint_processor.go
index ce61936aa1cf7..47613a429d99a 100644
--- a/util/hint/hint_processor.go
+++ b/util/hint/hint_processor.go
@@ -314,8 +314,13 @@ func extractHintWarns(warns []error) []error {
// BlockHintProcessor processes hints at different level of sql statement.
type BlockHintProcessor struct {
- QbNameMap map[string]int // Map from query block name to select stmt offset.
- QbHints map[int][]*ast.TableOptimizerHint // Group all hints at same query block.
+ QbNameMap map[string]int // Map from query block name to select stmt offset.
+ QbHints map[int][]*ast.TableOptimizerHint // Group all hints at same query block.
+
+ // Used for the view's hint
+ QbNameMap4View map[string][]ast.HintTable // Map from view's query block name to view's table list.
+ QbHints4View map[string][]*ast.TableOptimizerHint // Group all hints at same query block for view hints.
+
Ctx sessionctx.Context
selectStmtOffset int
}
@@ -334,8 +339,15 @@ func (p *BlockHintProcessor) Enter(in ast.Node) (ast.Node, bool) {
p.checkQueryBlockHints(node.TableHints, 0)
case *ast.SelectStmt:
p.selectStmtOffset++
+ // Only support view hints which appear in the outer select part
+ if p.selectStmtOffset == 1 {
+ // Handle the view hints and update the left hint.
+ node.TableHints = p.handleViewHints(node.TableHints)
+ }
node.QueryBlockOffset = p.selectStmtOffset
p.checkQueryBlockHints(node.TableHints, node.QueryBlockOffset)
+ case *ast.ExplainStmt:
+ return in, true
}
return in, false
}
@@ -354,9 +366,15 @@ func (p *BlockHintProcessor) checkQueryBlockHints(hints []*ast.TableOptimizerHin
if hint.HintName.L != hintQBName {
continue
}
+ if offset > 1 && len(hint.Tables) > 0 {
+ if p.Ctx != nil {
+ p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("The qb_name hint for view only supports to be defined in the first query block"))
+ }
+ continue
+ }
if qbName != "" {
if p.Ctx != nil {
- p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("There are more than two query names in same query block,, using the first one %s", qbName))
+ p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("There are more than two query names in same query block, using the first one %s", qbName))
}
} else {
qbName = hint.QBName.L
@@ -377,6 +395,75 @@ func (p *BlockHintProcessor) checkQueryBlockHints(hints []*ast.TableOptimizerHin
}
}
+func (p *BlockHintProcessor) handleViewHints(hints []*ast.TableOptimizerHint) (leftHints []*ast.TableOptimizerHint) {
+ if len(hints) == 0 {
+ return
+ }
+
+ usedHints := make([]bool, len(hints))
+ // handle the query block name hints for view
+ for i, hint := range hints {
+ if hint.HintName.L != hintQBName || len(hint.Tables) == 0 {
+ continue
+ }
+ usedHints[i] = true
+ if p.QbNameMap4View == nil {
+ p.QbNameMap4View = make(map[string][]ast.HintTable)
+ }
+ qbName := hint.QBName.L
+ if qbName == "" {
+ continue
+ }
+ if _, ok := p.QbNameMap4View[qbName]; ok {
+ if p.Ctx != nil {
+ p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Duplicate query block name %s for view's query block hint, only the first one is effective", qbName))
+ }
+ } else {
+ p.QbNameMap4View[qbName] = hint.Tables
+ }
+ }
+
+ // handle the view hints
+ for i, hint := range hints {
+ if usedHints[i] || hint.HintName.L == hintQBName {
+ continue
+ }
+
+ ok := false
+ qbName := hint.QBName.L
+ if qbName != "" {
+ _, ok = p.QbNameMap4View[qbName]
+ } else if len(hint.Tables) > 0 {
+ // Only support to define the tables belong to the same query block in one view hint
+ qbName = hint.Tables[0].QBName.L
+ _, ok = p.QbNameMap4View[qbName]
+ if ok {
+ for _, table := range hint.Tables {
+ if table.QBName.L != qbName {
+ ok = false
+ break
+ }
+ }
+ }
+ }
+
+ if ok {
+ if p.QbHints4View == nil {
+ p.QbHints4View = make(map[string][]*ast.TableOptimizerHint)
+ }
+ usedHints[i] = true
+ p.QbHints4View[qbName] = append(p.QbHints4View[qbName], hint)
+ }
+ }
+
+ for i, hint := range hints {
+ if !usedHints[i] {
+ leftHints = append(leftHints, hint)
+ }
+ }
+ return
+}
+
const (
defaultUpdateBlockName = "upd_1"
defaultDeleteBlockName = "del_1"