diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go
index ebc13d6f6f245..18b78ae404c72 100644
--- a/executor/infoschema_reader.go
+++ b/executor/infoschema_reader.go
@@ -688,7 +688,7 @@ func (e *hugeMemTableRetriever) dataForColumnsInTable(ctx context.Context, sctx
if err := runWithSystemSession(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 8ee1ba9b84607..0a26b94783672 100644
--- a/executor/show.go
+++ b/executor/show.go
@@ -1904,7 +1904,7 @@ func tryFillViewColumnType(ctx context.Context, sctx sessionctx.Context, is info
return runWithSystemSession(sctx, func(s sessionctx.Context) error {
// Retrieve view columns info.
planBuilder, _ := plannercore.NewPlanBuilder().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/ast/misc.go b/parser/ast/misc.go
index 5fc1feb396b1a..b4a348cd804c6 100644
--- a/parser/ast/misc.go
+++ b/parser/ast/misc.go
@@ -1808,9 +1808,10 @@ type StatisticsSpec struct {
// CreateStatisticsStmt is a statement to create extended statistics.
// Examples:
-// CREATE STATISTICS stats1 (cardinality) ON t(a, b, c);
-// CREATE STATISTICS stats2 (dependency) ON t(a, b);
-// CREATE STATISTICS stats3 (correlation) ON t(a, b);
+//
+// CREATE STATISTICS stats1 (cardinality) ON t(a, b, c);
+// CREATE STATISTICS stats2 (dependency) ON t(a, b);
+// CREATE STATISTICS stats3 (correlation) ON t(a, b);
type CreateStatisticsStmt struct {
stmtNode
@@ -1878,7 +1879,8 @@ func (n *CreateStatisticsStmt) Accept(v Visitor) (Node, bool) {
// DropStatisticsStmt is a statement to drop extended statistics.
// Examples:
-// DROP STATISTICS stats1;
+//
+// DROP STATISTICS stats1;
type DropStatisticsStmt struct {
stmtNode
@@ -2009,6 +2011,7 @@ const (
)
// ShowSlow is used for the following command:
+//
// admin show slow top [ internal | all] N
// admin show slow recent N
type ShowSlow struct {
@@ -3464,9 +3467,13 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
}
ctx.WriteName(n.QBName.String())
}
+ if n.HintName.L == "qb_name" && len(n.Tables) == 0 {
+ ctx.WritePlain(")")
+ return nil
+ }
// Hints without args except query block.
switch n.HintName.L {
- case "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "qb_name", "ignore_plan_cache", "limit_to_cop", "straight_join":
+ case "hash_agg", "stream_agg", "agg_to_cop", "read_consistent_replica", "no_index_merge", "ignore_plan_cache", "limit_to_cop", "straight_join":
ctx.WritePlain(")")
return nil
}
@@ -3495,6 +3502,16 @@ func (n *TableOptimizerHint) Restore(ctx *format.RestoreCtx) error {
}
ctx.WriteName(index.String())
}
+ case "qb_name":
+ if len(n.Tables) > 0 {
+ ctx.WritePlain(", ")
+ for i, table := range n.Tables {
+ if i != 0 {
+ ctx.WritePlain(". ")
+ }
+ table.Restore(ctx)
+ }
+ }
case "use_toja", "use_cascades":
if n.HintData.(bool) {
ctx.WritePlain("TRUE")
diff --git a/parser/hintparser.go b/parser/hintparser.go
index b86638e44b682..f8e8cb46713c3 100644
--- a/parser/hintparser.go
+++ b/parser/hintparser.go
@@ -117,88 +117,88 @@ const (
hintUseToja = 57396
yyhintMaxDepth = 200
- yyhintTabOfs = -174
+ yyhintTabOfs = -179
)
var (
yyhintXLAT = map[int]int{
- 41: 0, // ')' (131x)
- 57377: 1, // hintAggToCop (123x)
- 57390: 2, // hintBCJoin (123x)
- 57355: 3, // hintBKA (123x)
- 57357: 4, // hintBNL (123x)
- 57401: 5, // hintForceIndex (123x)
- 57379: 6, // hintHashAgg (123x)
- 57359: 7, // hintHashJoin (123x)
- 57380: 8, // hintIgnoreIndex (123x)
- 57378: 9, // hintIgnorePlanCache (123x)
- 57363: 10, // hintIndexMerge (123x)
- 57381: 11, // hintInlHashJoin (123x)
- 57382: 12, // hintInlJoin (123x)
- 57383: 13, // hintInlMergeJoin (123x)
- 57351: 14, // hintJoinFixedOrder (123x)
- 57352: 15, // hintJoinOrder (123x)
- 57353: 16, // hintJoinPrefix (123x)
- 57354: 17, // hintJoinSuffix (123x)
- 57403: 18, // hintLeading (123x)
- 57400: 19, // hintLimitToCop (123x)
- 57373: 20, // hintMaxExecutionTime (123x)
- 57384: 21, // hintMemoryQuota (123x)
- 57361: 22, // hintMerge (123x)
- 57365: 23, // hintMRR (123x)
- 57356: 24, // hintNoBKA (123x)
- 57358: 25, // hintNoBNL (123x)
- 57360: 26, // hintNoHashJoin (123x)
- 57367: 27, // hintNoICP (123x)
- 57364: 28, // hintNoIndexMerge (123x)
- 57362: 29, // hintNoMerge (123x)
- 57366: 30, // hintNoMRR (123x)
- 57368: 31, // hintNoRangeOptimization (123x)
- 57372: 32, // hintNoSemijoin (123x)
- 57370: 33, // hintNoSkipScan (123x)
- 57385: 34, // hintNoSwapJoinInputs (123x)
- 57399: 35, // hintNthPlan (123x)
- 57376: 36, // hintQBName (123x)
- 57386: 37, // hintQueryType (123x)
- 57387: 38, // hintReadConsistentReplica (123x)
- 57388: 39, // hintReadFromStorage (123x)
- 57375: 40, // hintResourceGroup (123x)
- 57371: 41, // hintSemijoin (123x)
- 57374: 42, // hintSetVar (123x)
- 57369: 43, // hintSkipScan (123x)
- 57389: 44, // hintSMJoin (123x)
- 57402: 45, // hintStraightJoin (123x)
- 57391: 46, // hintStreamAgg (123x)
- 57392: 47, // hintSwapJoinInputs (123x)
- 57397: 48, // hintTimeRange (123x)
- 57398: 49, // hintUseCascades (123x)
- 57394: 50, // hintUseIndex (123x)
- 57393: 51, // hintUseIndexMerge (123x)
- 57395: 52, // hintUsePlanCache (123x)
- 57396: 53, // hintUseToja (123x)
- 44: 54, // ',' (121x)
- 57413: 55, // hintDupsWeedOut (101x)
- 57414: 56, // hintFirstMatch (101x)
- 57415: 57, // hintLooseScan (101x)
- 57416: 58, // hintMaterialization (101x)
- 57408: 59, // hintTiFlash (101x)
- 57407: 60, // hintTiKV (101x)
- 57409: 61, // hintFalse (100x)
- 57404: 62, // hintOLAP (100x)
- 57405: 63, // hintOLTP (100x)
- 57410: 64, // hintTrue (100x)
- 57412: 65, // hintGB (99x)
- 57411: 66, // hintMB (99x)
- 57347: 67, // hintIdentifier (98x)
- 57349: 68, // hintSingleAtIdentifier (83x)
+ 41: 0, // ')' (139x)
+ 57377: 1, // hintAggToCop (126x)
+ 57390: 2, // hintBCJoin (126x)
+ 57355: 3, // hintBKA (126x)
+ 57357: 4, // hintBNL (126x)
+ 57401: 5, // hintForceIndex (126x)
+ 57379: 6, // hintHashAgg (126x)
+ 57359: 7, // hintHashJoin (126x)
+ 57380: 8, // hintIgnoreIndex (126x)
+ 57378: 9, // hintIgnorePlanCache (126x)
+ 57363: 10, // hintIndexMerge (126x)
+ 57381: 11, // hintInlHashJoin (126x)
+ 57382: 12, // hintInlJoin (126x)
+ 57383: 13, // hintInlMergeJoin (126x)
+ 57351: 14, // hintJoinFixedOrder (126x)
+ 57352: 15, // hintJoinOrder (126x)
+ 57353: 16, // hintJoinPrefix (126x)
+ 57354: 17, // hintJoinSuffix (126x)
+ 57403: 18, // hintLeading (126x)
+ 57400: 19, // hintLimitToCop (126x)
+ 57373: 20, // hintMaxExecutionTime (126x)
+ 57384: 21, // hintMemoryQuota (126x)
+ 57361: 22, // hintMerge (126x)
+ 57365: 23, // hintMRR (126x)
+ 57356: 24, // hintNoBKA (126x)
+ 57358: 25, // hintNoBNL (126x)
+ 57360: 26, // hintNoHashJoin (126x)
+ 57367: 27, // hintNoICP (126x)
+ 57364: 28, // hintNoIndexMerge (126x)
+ 57362: 29, // hintNoMerge (126x)
+ 57366: 30, // hintNoMRR (126x)
+ 57368: 31, // hintNoRangeOptimization (126x)
+ 57372: 32, // hintNoSemijoin (126x)
+ 57370: 33, // hintNoSkipScan (126x)
+ 57385: 34, // hintNoSwapJoinInputs (126x)
+ 57399: 35, // hintNthPlan (126x)
+ 57376: 36, // hintQBName (126x)
+ 57386: 37, // hintQueryType (126x)
+ 57387: 38, // hintReadConsistentReplica (126x)
+ 57388: 39, // hintReadFromStorage (126x)
+ 57375: 40, // hintResourceGroup (126x)
+ 57371: 41, // hintSemijoin (126x)
+ 57374: 42, // hintSetVar (126x)
+ 57369: 43, // hintSkipScan (126x)
+ 57389: 44, // hintSMJoin (126x)
+ 57402: 45, // hintStraightJoin (126x)
+ 57391: 46, // hintStreamAgg (126x)
+ 57392: 47, // hintSwapJoinInputs (126x)
+ 57397: 48, // hintTimeRange (126x)
+ 57398: 49, // hintUseCascades (126x)
+ 57394: 50, // hintUseIndex (126x)
+ 57393: 51, // hintUseIndexMerge (126x)
+ 57395: 52, // hintUsePlanCache (126x)
+ 57396: 53, // hintUseToja (126x)
+ 44: 54, // ',' (123x)
+ 57413: 55, // hintDupsWeedOut (103x)
+ 57414: 56, // hintFirstMatch (103x)
+ 57415: 57, // hintLooseScan (103x)
+ 57416: 58, // hintMaterialization (103x)
+ 57408: 59, // hintTiFlash (103x)
+ 57407: 60, // hintTiKV (103x)
+ 57409: 61, // hintFalse (102x)
+ 57404: 62, // hintOLAP (102x)
+ 57405: 63, // hintOLTP (102x)
+ 57410: 64, // hintTrue (102x)
+ 57412: 65, // hintGB (101x)
+ 57411: 66, // hintMB (101x)
+ 57347: 67, // hintIdentifier (100x)
+ 57349: 68, // hintSingleAtIdentifier (86x)
93: 69, // ']' (77x)
- 57406: 70, // hintPartition (71x)
- 46: 71, // '.' (67x)
+ 46: 70, // '.' (76x)
+ 57406: 71, // hintPartition (71x)
61: 72, // '=' (67x)
40: 73, // '(' (62x)
- 57344: 74, // $end (24x)
- 57437: 75, // QueryBlockOpt (17x)
- 57429: 76, // Identifier (13x)
+ 57344: 74, // $end (25x)
+ 57437: 75, // QueryBlockOpt (20x)
+ 57429: 76, // Identifier (15x)
57346: 77, // hintIntLit (8x)
57350: 78, // hintStringLit (5x)
57419: 79, // CommaOpt (4x)
@@ -221,21 +221,23 @@ var (
57446: 96, // TableOptimizerHintOpt (2x)
57448: 97, // UnsupportedIndexLevelOptimizerHintName (2x)
57449: 98, // UnsupportedTableLevelOptimizerHintName (2x)
- 57421: 99, // HintQueryType (1x)
- 57424: 100, // HintStorageTypeAndTableList (1x)
- 57428: 101, // HintTrueOrFalse (1x)
- 57430: 102, // IndexNameList (1x)
- 57431: 103, // IndexNameListOpt (1x)
- 57434: 104, // OptimizerHintList (1x)
- 57435: 105, // PartitionList (1x)
- 57438: 106, // Start (1x)
- 57441: 107, // SubqueryStrategies (1x)
- 57442: 108, // SubqueryStrategiesOpt (1x)
- 57447: 109, // UnitOfBytes (1x)
- 57450: 110, // Value (1x)
- 57417: 111, // $default (0x)
- 57345: 112, // error (0x)
- 57348: 113, // hintInvalid (0x)
+ 57451: 99, // ViewName (2x)
+ 57421: 100, // HintQueryType (1x)
+ 57424: 101, // HintStorageTypeAndTableList (1x)
+ 57428: 102, // HintTrueOrFalse (1x)
+ 57430: 103, // IndexNameList (1x)
+ 57431: 104, // IndexNameListOpt (1x)
+ 57434: 105, // OptimizerHintList (1x)
+ 57435: 106, // PartitionList (1x)
+ 57438: 107, // Start (1x)
+ 57441: 108, // SubqueryStrategies (1x)
+ 57442: 109, // SubqueryStrategiesOpt (1x)
+ 57447: 110, // UnitOfBytes (1x)
+ 57450: 111, // Value (1x)
+ 57452: 112, // ViewNameList (1x)
+ 57417: 113, // $default (0x)
+ 57345: 114, // error (0x)
+ 57348: 115, // hintInvalid (0x)
}
yyhintSymNames = []string{
@@ -309,8 +311,8 @@ var (
"hintIdentifier",
"hintSingleAtIdentifier",
"']'",
- "hintPartition",
"'.'",
+ "hintPartition",
"'='",
"'('",
"$end",
@@ -338,6 +340,7 @@ var (
"TableOptimizerHintOpt",
"UnsupportedIndexLevelOptimizerHintName",
"UnsupportedTableLevelOptimizerHintName",
+ "ViewName",
"HintQueryType",
"HintStorageTypeAndTableList",
"HintTrueOrFalse",
@@ -350,6 +353,7 @@ var (
"SubqueryStrategiesOpt",
"UnitOfBytes",
"Value",
+ "ViewNameList",
"$default",
"error",
"hintInvalid",
@@ -357,11 +361,11 @@ var (
yyhintReductions = []struct{ xsym, components int }{
{0, 1},
- {106, 1},
- {104, 1},
- {104, 3},
- {104, 1},
- {104, 3},
+ {107, 1},
+ {105, 1},
+ {105, 3},
+ {105, 1},
+ {105, 3},
{96, 4},
{96, 4},
{96, 4},
@@ -376,12 +380,13 @@ var (
{96, 4},
{96, 6},
{96, 6},
+ {96, 6},
{96, 5},
{96, 4},
{96, 5},
{91, 5},
- {100, 1},
- {100, 3},
+ {101, 1},
+ {101, 3},
{86, 4},
{75, 0},
{75, 1},
@@ -389,30 +394,34 @@ var (
{79, 1},
{90, 0},
{90, 4},
- {105, 1},
- {105, 3},
+ {106, 1},
+ {106, 3},
{87, 1},
{87, 1},
{81, 2},
{81, 3},
{80, 3},
{80, 5},
+ {112, 3},
+ {112, 1},
+ {99, 2},
+ {99, 1},
{84, 4},
- {103, 0},
+ {104, 0},
+ {104, 1},
{103, 1},
- {102, 1},
- {102, 3},
- {108, 0},
+ {103, 3},
+ {109, 0},
+ {109, 1},
{108, 1},
- {107, 1},
- {107, 3},
- {110, 1},
+ {108, 3},
+ {111, 1},
+ {111, 1},
+ {111, 1},
{110, 1},
{110, 1},
- {109, 1},
- {109, 1},
- {101, 1},
- {101, 1},
+ {102, 1},
+ {102, 1},
{88, 1},
{88, 1},
{88, 1},
@@ -460,8 +469,8 @@ var (
{89, 1},
{89, 1},
{89, 1},
- {99, 1},
- {99, 1},
+ {100, 1},
+ {100, 1},
{85, 1},
{85, 1},
{76, 1},
@@ -534,35 +543,35 @@ var (
yyhintXErrors = map[yyhintXError]string{}
- yyhintParseTab = [257][]uint16{
+ yyhintParseTab = [266][]uint16{
// 0
- {1: 234, 208, 200, 202, 226, 232, 214, 224, 238, 216, 210, 209, 213, 179, 197, 198, 199, 215, 235, 186, 191, 205, 217, 201, 203, 204, 219, 236, 206, 218, 220, 228, 222, 212, 187, 190, 195, 237, 196, 189, 227, 188, 221, 207, 239, 233, 211, 192, 230, 223, 225, 231, 229, 83: 193, 88: 180, 194, 91: 178, 185, 94: 184, 182, 177, 183, 181, 104: 176, 106: 175},
- {74: 174},
- {1: 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 328, 74: 173, 79: 428},
- {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, 74: 172},
- {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, 74: 170},
+ {1: 239, 213, 205, 207, 231, 237, 219, 229, 243, 221, 215, 214, 218, 184, 202, 203, 204, 220, 240, 191, 196, 210, 222, 206, 208, 209, 224, 241, 211, 223, 225, 233, 227, 217, 192, 195, 200, 242, 201, 194, 232, 193, 226, 212, 244, 238, 216, 197, 235, 228, 230, 236, 234, 83: 198, 88: 185, 199, 91: 183, 190, 94: 189, 187, 182, 188, 186, 105: 181, 107: 180},
+ {74: 179},
+ {1: 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, 333, 74: 178, 79: 442},
+ {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, 74: 177},
+ {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, 74: 175},
// 5
+ {73: 439},
+ {73: 436},
+ {73: 433},
+ {73: 428},
{73: 425},
- {73: 422},
- {73: 419},
- {73: 414},
- {73: 411},
// 10
- {73: 400},
- {73: 388},
- {73: 384},
- {73: 380},
- {73: 372},
+ {73: 414},
+ {73: 402},
+ {73: 398},
+ {73: 394},
+ {73: 386},
// 15
- {73: 369},
- {73: 366},
+ {73: 383},
+ {73: 371},
+ {73: 364},
{73: 359},
- {73: 354},
- {73: 348},
+ {73: 353},
// 20
- {73: 345},
- {73: 339},
- {73: 240},
+ {73: 350},
+ {73: 344},
+ {73: 245},
{73: 117},
{73: 116},
// 25
@@ -615,21 +624,21 @@ var (
{73: 72},
// 65
{73: 71},
- {59: 147, 147, 68: 242, 75: 241},
- {59: 247, 246, 85: 245, 244, 100: 243},
- {146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 69: 146, 146, 77: 146},
- {336, 54: 337},
+ {59: 151, 151, 68: 247, 75: 246},
+ {59: 252, 251, 85: 250, 249, 101: 248},
+ {150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 69: 150, 150, 150, 77: 150},
+ {341, 54: 342},
// 70
- {150, 54: 150},
- {82: 248},
+ {154, 54: 154},
+ {82: 253},
{82: 68},
{82: 67},
- {1: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 250, 81: 249},
+ {1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 255, 81: 254},
// 75
- {54: 334, 69: 333},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 252, 80: 251},
- {137, 54: 137, 69: 137},
- {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 147, 147, 320, 75: 319},
+ {54: 339, 69: 338},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 257, 80: 256},
+ {141, 54: 141, 69: 141},
+ {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 151, 325, 151, 75: 324},
{66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66},
// 80
{65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65},
@@ -710,140 +719,151 @@ var (
{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},
// 145
- {143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 69: 143, 323, 90: 332},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 321},
- {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 147, 147, 75: 322},
- {143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 69: 143, 323, 90: 324},
- {73: 325},
+ {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 69: 147, 71: 328, 90: 337},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 326},
+ {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 151, 71: 151, 75: 327},
+ {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 69: 147, 71: 328, 90: 329},
+ {73: 330},
// 150
- {134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 69: 134},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 327, 105: 326},
- {329, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 328, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 79: 330},
- {141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141},
- {144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 55: 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 78: 144},
+ {138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 69: 138},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 332, 106: 331},
+ {334, 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, 333, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 79: 335},
+ {145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145},
+ {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, 55: 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 78: 148},
// 155
- {142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 69: 142},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 331},
- {140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140},
- {135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 69: 135},
- {148, 54: 148},
+ {146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 69: 146},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 336},
+ {144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144},
+ {139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 69: 139},
+ {152, 54: 152},
// 160
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 252, 80: 335},
- {136, 54: 136, 69: 136},
- {1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 74: 151},
- {59: 247, 246, 85: 245, 338},
- {149, 54: 149},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 257, 80: 340},
+ {140, 54: 140, 69: 140},
+ {1: 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, 74: 155},
+ {59: 252, 251, 85: 250, 343},
+ {153, 54: 153},
// 165
- {62: 147, 147, 68: 242, 75: 340},
- {62: 342, 343, 99: 341},
- {344},
+ {62: 151, 151, 68: 247, 75: 345},
+ {62: 347, 348, 100: 346},
+ {349},
{70},
{69},
// 170
- {1: 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, 74: 152},
- {147, 68: 242, 75: 346},
- {347},
- {1: 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, 74: 153},
- {61: 147, 64: 147, 68: 242, 75: 349},
+ {1: 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, 74: 156},
+ {151, 68: 247, 75: 351},
+ {352},
+ {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, 74: 157},
+ {61: 151, 64: 151, 68: 247, 75: 354},
// 175
- {61: 352, 64: 351, 101: 350},
- {353},
+ {61: 357, 64: 356, 102: 355},
+ {358},
{119},
{118},
- {1: 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, 74: 154},
+ {1: 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, 74: 158},
// 180
- {78: 355},
- {54: 328, 78: 145, 356},
- {78: 357},
- {358},
- {1: 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, 74: 155},
+ {78: 360},
+ {54: 333, 78: 149, 361},
+ {78: 362},
+ {363},
+ {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, 74: 159},
// 185
- {68: 242, 75: 360, 77: 147},
- {77: 361},
- {65: 364, 363, 109: 362},
- {365},
+ {68: 247, 75: 365, 77: 151},
+ {77: 366},
+ {65: 369, 368, 110: 367},
+ {370},
{121},
// 190
{120},
- {1: 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, 74: 156},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 367},
- {368},
- {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, 74: 157},
+ {1: 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, 74: 160},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 372},
+ {373, 54: 374},
+ {1: 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, 74: 162},
// 195
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 370},
- {371},
- {1: 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, 74: 158},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 373},
- {72: 374},
+ {151, 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 247, 70: 151, 75: 378, 377, 99: 376, 112: 375},
+ {380, 70: 381},
+ {136, 70: 136},
+ {151, 68: 247, 70: 151, 75: 379},
+ {134, 70: 134},
// 200
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 377, 378, 376, 110: 375},
- {379},
+ {135, 70: 135},
+ {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, 74: 161},
+ {151, 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 247, 70: 151, 75: 378, 377, 99: 382},
+ {137, 70: 137},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 384},
+ // 205
+ {385},
+ {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, 74: 163},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 387},
+ {72: 388},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 391, 392, 390, 111: 389},
+ // 210
+ {393},
{124},
{123},
{122},
- // 205
- {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, 74: 159},
- {68: 242, 75: 381, 77: 147},
- {77: 382},
- {383},
- {1: 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, 74: 160},
- // 210
- {68: 242, 75: 385, 77: 147},
- {77: 386},
- {387},
- {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, 74: 161},
- {147, 55: 147, 147, 147, 147, 68: 242, 75: 389},
+ {1: 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, 74: 164},
// 215
- {128, 55: 393, 394, 395, 396, 93: 392, 107: 391, 390},
- {399},
- {127, 54: 397},
+ {68: 247, 75: 395, 77: 151},
+ {77: 396},
+ {397},
+ {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, 74: 165},
+ {68: 247, 75: 399, 77: 151},
+ // 220
+ {77: 400},
+ {401},
+ {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, 74: 166},
+ {151, 55: 151, 151, 151, 151, 68: 247, 75: 403},
+ {128, 55: 407, 408, 409, 410, 93: 406, 108: 405, 404},
+ // 225
+ {413},
+ {127, 54: 411},
{126, 54: 126},
{85, 54: 85},
- // 220
{84, 54: 84},
+ // 230
{83, 54: 83},
{82, 54: 82},
- {55: 393, 394, 395, 396, 93: 398},
+ {55: 407, 408, 409, 410, 93: 412},
{125, 54: 125},
- // 225
- {1: 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, 74: 162},
- {1: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 402, 84: 401},
- {410},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 252, 80: 403},
- {145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 328, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 79: 404},
- // 230
- {132, 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 407, 102: 406, 405},
+ {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, 74: 167},
+ // 235
+ {1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 416, 84: 415},
+ {424},
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 257, 80: 417},
+ {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, 333, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 79: 418},
+ {132, 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 421, 103: 420, 419},
+ // 240
{133},
- {131, 54: 408},
+ {131, 54: 422},
{130, 54: 130},
- {1: 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 409},
- // 235
+ {1: 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 423},
{129, 54: 129},
- {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, 74: 163},
- {1: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 402, 84: 412},
- {413},
- {1: 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, 74: 164},
- // 240
- {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 417, 81: 416, 87: 415},
- {418},
- {139, 54: 334},
- {138, 280, 294, 258, 260, 304, 283, 262, 284, 282, 266, 285, 286, 287, 254, 255, 256, 257, 306, 281, 276, 288, 264, 268, 259, 261, 263, 270, 267, 265, 269, 271, 275, 273, 289, 303, 279, 290, 291, 292, 278, 274, 277, 272, 293, 305, 295, 296, 301, 302, 298, 297, 299, 300, 55: 315, 316, 317, 318, 310, 309, 311, 307, 308, 312, 314, 313, 253, 76: 252, 80: 251},
- {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, 74: 165},
// 245
- {147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 417, 81: 416, 87: 420},
- {421},
- {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, 74: 166},
- {1: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 55: 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 242, 75: 250, 81: 423},
- {424, 54: 334},
- // 250
- {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, 74: 167},
- {147, 68: 242, 75: 426},
- {427},
{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, 74: 168},
- {1: 234, 208, 200, 202, 226, 232, 214, 224, 238, 216, 210, 209, 213, 179, 197, 198, 199, 215, 235, 186, 191, 205, 217, 201, 203, 204, 219, 236, 206, 218, 220, 228, 222, 212, 187, 190, 195, 237, 196, 189, 227, 188, 221, 207, 239, 233, 211, 192, 230, 223, 225, 231, 229, 83: 193, 88: 180, 194, 91: 430, 185, 94: 184, 182, 429, 183, 181},
+ {1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 416, 84: 426},
+ {427},
+ {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, 74: 169},
+ {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 431, 81: 430, 87: 429},
+ // 250
+ {432},
+ {143, 54: 339},
+ {142, 285, 299, 263, 265, 309, 288, 267, 289, 287, 271, 290, 291, 292, 259, 260, 261, 262, 311, 286, 281, 293, 269, 273, 264, 266, 268, 275, 272, 270, 274, 276, 280, 278, 294, 308, 284, 295, 296, 297, 283, 279, 282, 277, 298, 310, 300, 301, 306, 307, 303, 302, 304, 305, 55: 320, 321, 322, 323, 315, 314, 316, 312, 313, 317, 319, 318, 258, 76: 257, 80: 256},
+ {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, 74: 170},
+ {151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 431, 81: 430, 87: 434},
// 255
+ {435},
{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, 74: 171},
- {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, 74: 169},
+ {1: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 55: 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 247, 75: 255, 81: 437},
+ {438, 54: 339},
+ {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, 74: 172},
+ // 260
+ {151, 68: 247, 75: 440},
+ {441},
+ {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, 74: 173},
+ {1: 239, 213, 205, 207, 231, 237, 219, 229, 243, 221, 215, 214, 218, 184, 202, 203, 204, 220, 240, 191, 196, 210, 222, 206, 208, 209, 224, 241, 211, 223, 225, 233, 227, 217, 192, 195, 200, 242, 201, 194, 232, 193, 226, 212, 244, 238, 216, 197, 235, 228, 230, 236, 234, 83: 198, 88: 185, 199, 91: 444, 190, 94: 189, 187, 443, 188, 186},
+ {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, 74: 176},
+ // 265
+ {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, 74: 174},
}
)
@@ -883,7 +903,7 @@ func yyhintlex1(yylex yyhintLexer, lval *yyhintSymType) (n int) {
}
func yyhintParse(yylex yyhintLexer, parser *hintParser) int {
- const yyError = 112
+ const yyError = 114
yyEx, _ := yylex.(yyhintLexerEx)
var yyn int
@@ -1160,6 +1180,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 {
@@ -1174,7 +1202,7 @@ yynewstate:
parser.yyVAL.hint = nil
}
}
- case 19:
+ case 20:
{
parser.yyVAL.hint = &ast.TableOptimizerHint{
HintName: model.NewCIStr(yyS[yypt-5].ident),
@@ -1184,21 +1212,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),
@@ -1206,7 +1234,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)
@@ -1217,60 +1245,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),
@@ -1278,7 +1306,7 @@ yynewstate:
PartitionList: yyS[yypt-0].modelIdents,
}
}
- case 40:
+ case 41:
{
parser.yyVAL.table = ast.HintTable{
DBName: model.NewCIStr(yyS[yypt-4].ident),
@@ -1287,46 +1315,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 e3c3dacf4faff..d714be674a766 100644
--- a/parser/hintparser.y
+++ b/parser/hintparser.y
@@ -155,6 +155,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"
@@ -162,6 +163,7 @@ import (
%type
HintTable "Table in optimizer hint"
+ ViewName "View name in optimizer hint"
%type
PartitionList "partition name list in optimizer hint"
@@ -278,6 +280,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
@@ -440,6 +450,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 7d66336c947c2..b11bf88f3e117 100644
--- a/planner/core/integration_test.go
+++ b/planner/core/integration_test.go
@@ -1268,6 +1268,173 @@ func TestReadFromStorageHint(t *testing.T) {
}
}
+func TestViewHint(t *testing.T) {
+ store, clean := testkit.CreateMockStore(t)
+ defer clean()
+ tk := testkit.NewTestKit(t, store)
+
+ tk.MustExec("use test")
+ tk.MustExec("drop view if exists v, v1, v2")
+ 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.GetTestCases(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, clean := testkit.CreateMockStore(t)
+ defer clean()
+ tk := testkit.NewTestKit(t, store)
+
+ tk.MustExec("use test")
+ tk.MustExec("drop view if exists v, v1, v2, v3")
+ 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;")
+ tk.MustExec("create definer='root'@'localhost' view v3 as select /*+ merge_join(t) */ t.a, t.b from t join (select /*+ stream_agg() */ 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.GetTestCases(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 TestViewHintWithBinding(t *testing.T) {
+ store, clean := testkit.CreateMockStore(t)
+ defer clean()
+ 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;")
+
+ tk.MustExec("select * from v2")
+ tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
+ tk.MustExec("create global binding for select * from v2 using select /*+ qb_name(qb_v_2, v2.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. v1@sel_2 .v@sel_2 .@sel_1), merge_join(t@qb_v_1) */ * from v2;")
+ tk.MustExec("select * from v2")
+ tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1"))
+ res := tk.MustQuery("show global bindings").Rows()
+ require.Equal(t, res[0][0], "select * from `test` . `v2`")
+ require.Equal(t, res[0][1], "SELECT /*+ qb_name(`qb_v_2` , `v2`. `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`. `v1`@`sel_2`. `v`@`sel_2`. ``@`sel_1`) merge_join(`t`@`qb_v_1`)*/ * FROM `test`.`v2`")
+
+ tk.MustExec("drop global binding for select * from v2")
+ tk.MustExec("select * from v2")
+ tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
+ res = tk.MustQuery("show global bindings").Rows()
+ require.Equal(t, len(res), 0)
+}
+
+func TestAllViewHintType(t *testing.T) {
+ store, clean := testkit.CreateMockStore(t)
+ defer clean()
+ tk := testkit.NewTestKit(t, store)
+
+ tk.MustExec("use test")
+ tk.MustExec("set @@session.tidb_allow_mpp=ON")
+ tk.MustExec("set @@session.tidb_isolation_read_engines='tiflash, tikv'")
+ tk.MustExec("drop view if exists v, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12")
+ tk.MustExec("drop table if exists t, t1, t2, t4, t3, t5")
+ tk.MustExec("create table t(a int not null, b int, index idx_a(a));")
+ tk.MustExec("create table t1(a int not null, b int, index idx_a(a));")
+ tk.MustExec("create table t2(a int, b int, index idx_a(a));")
+ tk.MustExec("create table t3(a int, b int, index idx_a(a));")
+ tk.MustExec("create table t4(a int, b int, index idx_a(a));")
+ tk.MustExec("create table t5(a int, b int, index idx_a(a), index idx_b(b));")
+
+ // Create virtual tiflash replica info.
+ dom := domain.GetDomain(tk.Session())
+ is := dom.InfoSchema()
+ db, exists := is.SchemaByName(model.NewCIStr("test"))
+ require.True(t, exists)
+ for _, tblInfo := range db.Tables {
+ if tblInfo.Name.L == "t" {
+ tblInfo.TiFlashReplica = &model.TiFlashReplicaInfo{
+ Count: 1,
+ Available: true,
+ }
+ }
+ }
+
+ tk.MustExec("create definer='root'@'localhost' view v as select t.a, t.b from t join t1 on t.a = t1.a;")
+ tk.MustExec("create definer='root'@'localhost' view v1 as select t2.a, t2.b from t2 join t3 join v where t2.b = t3.b and t3.a = v.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;")
+ tk.MustExec("create definer='root'@'localhost' view v3 as select * from t5 where a > 1 and b < 2;")
+ tk.MustExec("create definer='root'@'localhost' view v4 as select * from t5 where a > 1 or b < 2;")
+ tk.MustExec("create definer='root'@'localhost' view v5 as SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t1 WHERE t1.b = t.b);")
+ tk.MustExec("create definer='root'@'localhost' view v6 as select * from t1 where t1.a < (select sum(t2.a) from t2 where t2.b = t1.b);")
+ tk.MustExec("create definer='root'@'localhost' view v9 as select sum(a) from t;")
+ tk.MustExec("create definer='root'@'localhost' view v10 as SELECT * FROM t WHERE a > 10 ORDER BY b LIMIT 1;")
+ tk.MustExec("create definer='root'@'localhost' view v11 as select a, sum(b) from t group by a")
+ tk.MustExec("create definer='root'@'localhost' view v12 as select t.a, t.b from t join t t1 on t.a = t1.a;")
+
+ var input []string
+ var output []struct {
+ SQL string
+ Plan []string
+ Warn []string
+ }
+ integrationSuiteData := core.GetIntegrationSuiteData()
+ integrationSuiteData.GetTestCases(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, clean := testkit.CreateMockStore(t)
defer clean()
diff --git a/planner/core/logical_plan_builder.go b/planner/core/logical_plan_builder.go
index b905f973d39fe..b309ff559cfe8 100644
--- a/planner/core/logical_plan_builder.go
+++ b/planner/core/logical_plan_builder.go
@@ -57,6 +57,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"
@@ -823,10 +824,10 @@ func (b *PlanBuilder) buildJoin(ctx context.Context, joinNode *ast.Join) (Logica
// on the "USING" clause.
//
// According to the standard SQL, columns are ordered in the following way:
-// 1. coalesced common columns of "leftPlan" and "rightPlan", in the order they
-// appears in "leftPlan".
-// 2. the rest columns in "leftPlan", in the order they appears in "leftPlan".
-// 3. the rest columns in "rightPlan", in the order they appears in "rightPlan".
+// 1. coalesced common columns of "leftPlan" and "rightPlan", in the order they
+// appears in "leftPlan".
+// 2. the rest columns in "leftPlan", in the order they appears in "leftPlan".
+// 3. the rest columns in "rightPlan", in the order they appears in "rightPlan".
func (b *PlanBuilder) buildUsingClause(p *LogicalJoin, leftPlan, rightPlan LogicalPlan, join *ast.Join) error {
filter := make(map[string]bool, len(join.Using))
for _, col := range join.Using {
@@ -847,9 +848,10 @@ func (b *PlanBuilder) buildUsingClause(p *LogicalJoin, leftPlan, rightPlan Logic
// buildNaturalJoin builds natural join output schema. It finds out all the common columns
// then using the same mechanism as buildUsingClause to eliminate redundant columns and build join conditions.
// According to standard SQL, producing this display order:
-// All the common columns
-// Every column in the first (left) table that is not a common column
-// Every column in the second (right) table that is not a common column
+//
+// All the common columns
+// Every column in the first (left) table that is not a common column
+// Every column in the second (right) table that is not a common column
func (b *PlanBuilder) buildNaturalJoin(p *LogicalJoin, leftPlan, rightPlan LogicalPlan, join *ast.Join) error {
err := b.coalesceCommonColumns(p, leftPlan, rightPlan, join.Tp, nil)
if err != nil {
@@ -1788,7 +1790,9 @@ func (b *PlanBuilder) buildUnion(ctx context.Context, selects []LogicalPlan, aft
// divideUnionSelectPlans resolves union's select stmts to logical plans.
// and divide result plans into "union-distinct" and "union-all" parts.
// divide rule ref:
-// https://dev.mysql.com/doc/refman/5.7/en/union.html
+//
+// https://dev.mysql.com/doc/refman/5.7/en/union.html
+//
// "Mixed UNION types are treated such that a DISTINCT union overrides any ALL union to its left."
func (b *PlanBuilder) divideUnionSelectPlans(ctx context.Context, selects []LogicalPlan, setOprTypes []*ast.SetOprType) (distinctSelects []LogicalPlan, allSelects []LogicalPlan, err error) {
firstUnionAllIdx := 0
@@ -4233,7 +4237,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() {
@@ -4743,8 +4776,11 @@ func (b *PlanBuilder) checkRecursiveView(dbName model.CIStr, tableName model.CIS
return func() { delete(b.buildingViewStack, viewFullName) }, nil
}
-// BuildDataSourceFromView is used to build LogicalPlan from view
-func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.CIStr, tableInfo *model.TableInfo) (LogicalPlan, error) {
+// BuildDataSourceFromView is used to build LogicalPlan from view.
+// 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) {
deferFunc, err := b.checkRecursiveView(dbName, tableInfo.Name)
if err != nil {
return nil, err
@@ -4760,6 +4796,51 @@ func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName model.
}
originalVisitInfo := b.visitInfo
b.visitInfo = make([]visitInfo, 0)
+
+ 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
+ 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 a2a6c7e655efc..d755966372f46 100644
--- a/planner/core/testdata/integration_suite_in.json
+++ b/planner/core/testdata/integration_suite_in.json
@@ -627,6 +627,124 @@
"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 .@sel_1), 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, v2), 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 .@sel_1) */ * from v;",
+
+ // The view contains the hint when creation
+ "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2), hash_agg(@qb_v3_2), qb_name(qb_v3_1, v3@sel_1 .@sel_1), hash_join(t@qb_v3_1) */ * from v3;"
+ ]
+ },
+ {
+ "name": "TestAllViewHintType",
+ "cases": [
+ // leading hint
+ // join nodes in the same view
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 v, t2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(v@qb_v1, t2@qb_v1) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 t3, t2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(t3@qb_v1, t2@qb_v1) */ * from v1;",
+
+ // join node across view
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), qb_name(qb_v, v1.v), leading(t2@qb_v1, t@qb_v) */ * from v1;",
+
+ // hash_join hint
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(@qb_v1 v, t2) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(t2@qb_v1, t3@qb_v1) */ * from v1;",
+
+ // merge join hint
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(@qb_v1 v) */ * from v1;",
+ "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(t2@qb_v1) */ * from v1;",
+
+ // index join hint
+ "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(@qb_v t) */ * from v;",
+ "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(t@qb_v) */ * from v;",
+
+ // agg hint
+ "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), hash_agg(@qb_v2) */ * from v2;",
+ "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), stream_agg(@qb_v2) */ * from v2;",
+
+ // index hint
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(t5@qb_v3, idx_a) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(t5@qb_v3, idx_a) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(t5@qb_v3, idx_a) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(t5@qb_v4, idx_a, idx_b) */ * from v4;",
+ "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(@qb_v4 t5, idx_b, idx_a) */ * from v4;",
+
+ // read from storage
+ "explain format = 'brief' select /*+ qb_name(qb_v, v), READ_FROM_STORAGE(TIFLASH[t@qb_v], TIKV[t1@qb_v]) */ * from v;",
+
+ // agg to cop hint
+ "explain format = 'brief' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
+ "explain format = 'brief' select /*+ qb_name(qb_v10, v10), LIMIT_TO_COP(@qb_v10) */ * from v10;"
+ ]
+ },
{
"name": "TestReadFromStorageHintAndIsolationRead",
"cases": [
diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json
index f3f200872b93e..f68588176c2e4 100644
--- a/planner/core/testdata/integration_suite_out.json
+++ b/planner/core/testdata/integration_suite_out.json
@@ -4121,6 +4121,1672 @@
}
]
},
+ {
+ "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 .@sel_1), merge_join(t@qb_v_1) */ * from v;",
+ "Plan": [
+ "MergeJoin 9990.00 root inner join, left key:test.t.a, right key:Column#10",
+ "├─Sort(Build) 7992.00 root Column#10",
+ "│ └─StreamAgg 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",
+ "└─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@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, v2), merge_join(t@qb_v2_1) */ * from v2;",
+ "Plan": [
+ "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#24",
+ "├─Sort(Build) 7984.01 root Column#24",
+ "│ └─StreamAgg 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",
+ "└─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
+ }
+ ]
+ },
+ {
+ "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": [
+ "Only one query block name is allowed in a view hint, otherwise the hint will be invalid"
+ ]
+ },
+ {
+ "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 .@sel_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",
+ "│ └─StreamAgg 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",
+ "└─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_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2) */ * from v3;",
+ "Plan": [
+ "MergeJoin 9980.01 root inner join, left key:test.t.a, right key:Column#27",
+ "├─Sort(Build) 7984.01 root Column#27",
+ "│ └─StreamAgg 7984.01 root group by:test.t.a, funcs:count(1)->Column#27",
+ "│ └─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#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",
+ "└─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_v3_2, v3@sel_1 .@sel_2), merge_join(t1@qb_v3_2), hash_agg(@qb_v3_2), qb_name(qb_v3_1, v3@sel_1 .@sel_1), hash_join(t@qb_v3_1) */ * from v3;",
+ "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": [
+ "[planner:1815]Join hints are conflict, you can only specify one type of join",
+ "[planner:1815]Optimizer aggregation hints are conflicted"
+ ]
+ }
+ ]
+ },
+ {
+ "Name": "TestAllViewHintType",
+ "Cases": [
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 v, t2) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ " ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": [
+ "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(v@qb_v1, t2@qb_v1) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ " ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": [
+ "[planner:1815]We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(@qb_v1 t3, t2) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ " ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), leading(t3@qb_v1, t2@qb_v1) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ " ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), qb_name(qb_v, v1.v), leading(t2@qb_v1, t@qb_v) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ " ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ " │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": [
+ "Only one query block name is allowed in a view hint, otherwise the hint will be invalid"
+ ]
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(@qb_v1 v, t2) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ "├─HashJoin(Build) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 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",
+ "└─HashJoin(Probe) 12500.00 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ " ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ " │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), hash_join(t2@qb_v1, t3@qb_v1) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]",
+ "├─HashJoin(Build) 12475.01 root inner join, equal:[eq(test.t2.b, test.t3.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 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",
+ "└─HashJoin(Probe) 12500.00 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ " ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ " │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(@qb_v1 v) */ * from v1;",
+ "Plan": [
+ "MergeJoin 19492.21 root inner join, left key:test.t3.a, right key:test.t.a",
+ "├─MergeJoin(Build) 12500.00 root inner join, left key:test.t.a, right key:test.t1.a",
+ "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:true, stats:pseudo",
+ "│ └─IndexReader(Probe) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t, index:idx_a(a) keep order:true, stats:pseudo",
+ "└─Sort(Probe) 12475.01 root test.t3.a",
+ " └─Projection 12475.01 root test.t2.a, test.t2.b, test.t3.a",
+ " └─HashJoin 12475.01 root inner join, equal:[eq(test.t3.b, test.t2.b)]",
+ " ├─TableReader(Build) 9980.01 root data:Selection",
+ " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 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"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v1, v1), merge_join(t2@qb_v1) */ * from v1;",
+ "Plan": [
+ "HashJoin 19492.21 root inner join, equal:[eq(test.t.a, test.t3.a)]",
+ "├─MergeJoin(Build) 12475.01 root inner join, left key:test.t2.b, right key:test.t3.b",
+ "│ ├─Sort(Build) 9980.01 root test.t3.b",
+ "│ │ └─TableReader 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─Sort(Probe) 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",
+ "└─HashJoin(Probe) 12500.00 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ " ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ " │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ " └─TableReader(Probe) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(@qb_v t) */ * from v;",
+ "Plan": [
+ "IndexJoin 12500.00 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─IndexLookUp(Probe) 1.25 root ",
+ " ├─IndexRangeScan(Build) 1.25 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo",
+ " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), INL_JOIN(t@qb_v) */ * from v;",
+ "Plan": [
+ "IndexJoin 12500.00 root inner join, inner:IndexLookUp, outer key:test.t1.a, inner key:test.t.a, equal cond:eq(test.t1.a, test.t.a)",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─IndexLookUp(Probe) 1.25 root ",
+ " ├─IndexRangeScan(Build) 1.25 cop[tikv] table:t, index:idx_a(a) range: decided by [eq(test.t.a, test.t1.a)], keep order:false, stats:pseudo",
+ " └─TableRowIDScan(Probe) 1.25 cop[tikv] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), hash_agg(@qb_v2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "├─HashAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ └─HashJoin 24365.26 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ "│ ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 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.t3.b, test.t2.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 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) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v2, v2.@sel_2), stream_agg(@qb_v2) */ * from v2;",
+ "Plan": [
+ "HashJoin 9990.00 root inner join, equal:[eq(test.t.a, Column#19)]",
+ "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:count(1)->Column#19",
+ "│ └─Sort 24365.26 root test.t2.a",
+ "│ └─HashJoin 24365.26 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "│ ├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ │ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 19492.21 root inner join, equal:[eq(test.t3.a, test.t.a)]",
+ "│ ├─TableReader(Build) 10000.00 root data:TableFullScan",
+ "│ │ └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo",
+ "│ └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t2.b, test.t1.b)]",
+ "│ ├─TableReader(Build) 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.t3.b, test.t2.b)]",
+ "│ ├─TableReader(Build) 9980.01 root data:Selection",
+ "│ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))",
+ "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo",
+ "│ └─TableReader(Probe) 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) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(t5@qb_v3, idx_a) */ * from v3;",
+ "Plan": [
+ "IndexLookUp 1107.78 root ",
+ "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
+ "└─Selection(Probe) 1107.78 cop[tikv] lt(test.t5.b, 2)",
+ " └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), use_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "Plan": [
+ "IndexLookUp 1107.78 root ",
+ "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
+ "└─Selection(Probe) 1107.78 cop[tikv] gt(test.t5.a, 1)",
+ " └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(t5@qb_v3, idx_a) */ * from v3;",
+ "Plan": [
+ "IndexLookUp 1107.78 root ",
+ "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
+ "└─Selection(Probe) 1107.78 cop[tikv] lt(test.t5.b, 2)",
+ " └─TableRowIDScan 3333.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), force_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "Plan": [
+ "IndexLookUp 1107.78 root ",
+ "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
+ "└─Selection(Probe) 1107.78 cop[tikv] gt(test.t5.a, 1)",
+ " └─TableRowIDScan 3323.33 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(t5@qb_v3, idx_a) */ * from v3;",
+ "Plan": [
+ "TableReader 1107.78 root data:Selection",
+ "└─Selection 1107.78 cop[tikv] gt(test.t5.a, 1), lt(test.t5.b, 2)",
+ " └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v3, v3), ignore_index(@qb_v3 t5, idx_b) */ * from v3;",
+ "Plan": [
+ "TableReader 1107.78 root data:Selection",
+ "└─Selection 1107.78 cop[tikv] gt(test.t5.a, 1), lt(test.t5.b, 2)",
+ " └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(t5@qb_v4, idx_a, idx_b) */ * from v4;",
+ "Plan": [
+ "IndexMerge 5548.89 root ",
+ "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
+ "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
+ "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v4, v4), use_index_merge(@qb_v4 t5, idx_b, idx_a) */ * from v4;",
+ "Plan": [
+ "IndexMerge 5548.89 root ",
+ "├─IndexRangeScan(Build) 3333.33 cop[tikv] table:t5, index:idx_a(a) range:(1,+inf], keep order:false, stats:pseudo",
+ "├─IndexRangeScan(Build) 3323.33 cop[tikv] table:t5, index:idx_b(b) range:[-inf,2), keep order:false, stats:pseudo",
+ "└─TableRowIDScan(Probe) 5548.89 cop[tikv] table:t5 keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v, v), READ_FROM_STORAGE(TIFLASH[t@qb_v], TIKV[t1@qb_v]) */ * from v;",
+ "Plan": [
+ "HashJoin 12500.00 root inner join, equal:[eq(test.t.a, test.t1.a)]",
+ "├─IndexReader(Build) 10000.00 root index:IndexFullScan",
+ "│ └─IndexFullScan 10000.00 cop[tikv] table:t1, index:idx_a(a) keep order:false, stats:pseudo",
+ "└─TableReader(Probe) 10000.00 root data:TableFullScan",
+ " └─TableFullScan 10000.00 cop[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v9, v9), AGG_TO_COP(@qb_v9) */ * from v9;",
+ "Plan": [
+ "HashAgg 1.00 root funcs:sum(Column#6)->Column#4",
+ "└─TableReader 1.00 root data:ExchangeSender",
+ " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough",
+ " └─HashAgg 1.00 mpp[tiflash] funcs:sum(Column#8)->Column#6",
+ " └─Projection 10000.00 mpp[tiflash] cast(test.t.a, decimal(10,0) BINARY)->Column#8",
+ " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo"
+ ],
+ "Warn": null
+ },
+ {
+ "SQL": "explain format = 'brief' select /*+ qb_name(qb_v10, v10), LIMIT_TO_COP(@qb_v10) */ * from v10;",
+ "Plan": [
+ "TopN 1.00 root test.t.b, offset:0, count:1",
+ "└─TableReader 1.00 root data:ExchangeSender",
+ " └─ExchangeSender 1.00 mpp[tiflash] ExchangeType: PassThrough",
+ " └─TopN 1.00 mpp[tiflash] test.t.b, offset:0, count:1",
+ " └─Selection 3333.33 mpp[tiflash] gt(test.t.a, 10)",
+ " └─TableFullScan 10000.00 mpp[tiflash] 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 1bc49d92da301..5bd383773eab2 100644
--- a/util/hint/hint_processor.go
+++ b/util/hint/hint_processor.go
@@ -274,6 +274,13 @@ func ParseHintsSet(p *parser.Parser, sql, charset, collation, db string) (*Hints
}
for _, tblHint := range tblHints {
if tblHint.HintName.L == hintQBName {
+ if len(tblHint.Tables) > 0 {
+ newHints = append(newHints, tblHint)
+ }
+ continue
+ }
+ if processor.isHint4View(tblHint) {
+ newHints = append(newHints, tblHint)
continue
}
offset := processor.GetHintOffset(tblHint.QBName, curOffset)
@@ -315,8 +322,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
}
@@ -335,8 +347,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
}
@@ -355,9 +374,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(errors.New(fmt.Sprintf("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
@@ -378,6 +403,79 @@ 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 {
+ p.Ctx.GetSessionVars().StmtCtx.AppendWarning(fmt.Errorf("Only one query block name is allowed in a view hint, otherwise the hint will be invalid"))
+ usedHints[i] = true
+ }
+ }
+ }
+
+ 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"
@@ -453,6 +551,25 @@ func (p *BlockHintProcessor) checkTableQBName(tables []ast.HintTable) bool {
return true
}
+func (p *BlockHintProcessor) isHint4View(hint *ast.TableOptimizerHint) bool {
+ if hint.QBName.L != "" {
+ if p.QbNameMap4View != nil {
+ _, ok := p.QbNameMap4View[hint.QBName.L]
+ return ok
+ }
+ return false
+ }
+ allViewHints := true
+ for _, table := range hint.Tables {
+ qbName := table.QBName.L
+ if _, ok := p.QbNameMap4View[qbName]; !ok {
+ allViewHints = false
+ break
+ }
+ }
+ return allViewHints
+}
+
// GetCurrentStmtHints extracts all hints that take effects at current stmt.
func (p *BlockHintProcessor) GetCurrentStmtHints(hints []*ast.TableOptimizerHint, currentOffset int) []*ast.TableOptimizerHint {
if p.QbHints == nil {