diff --git a/pkg/sql/distsql_physical_planner.go b/pkg/sql/distsql_physical_planner.go index 2f9960b75fdd..b89ca52758ac 100644 --- a/pkg/sql/distsql_physical_planner.go +++ b/pkg/sql/distsql_physical_planner.go @@ -364,8 +364,8 @@ func (dsp *DistSQLPlanner) checkSupportForNode(node planNode) (distRecommendatio return dsp.checkSupportForNode(n.plan) case *unionNode: - // Only UNION and UNION ALL are supported so far. - if n.unionType == tree.UnionOp { + // EXCEPT and INTERSECT are currently not supported. + if n.all || n.unionType == tree.UnionOp { recLeft, err := dsp.checkSupportForNode(n.left) if err != nil { return 0, err @@ -1589,23 +1589,7 @@ func (dsp *DistSQLPlanner) createPlanForJoin( // Set up the output columns. if numEq := len(n.pred.leftEqualityIndices); numEq != 0 { - // TODO(radu): for now we run a join processor on every node that produces - // data for either source. In the future we should be smarter here. - seen := make(map[roachpb.NodeID]struct{}) - for _, pIdx := range leftRouters { - n := p.Processors[pIdx].Node - if _, ok := seen[n]; !ok { - seen[n] = struct{}{} - nodes = append(nodes, n) - } - } - for _, pIdx := range rightRouters { - n := p.Processors[pIdx].Node - if _, ok := seen[n]; !ok { - seen[n] = struct{}{} - nodes = append(nodes, n) - } - } + nodes = findJoinProcessorNodes(leftRouters, rightRouters, p.Processors) // Set up the equality columns. leftEqCols = eqCols(n.pred.leftEqualityIndices, leftPlan.planToStreamColMap) @@ -1659,61 +1643,10 @@ func (dsp *DistSQLPlanner) createPlanForJoin( } } - pIdxStart := distsqlplan.ProcessorIdx(len(p.Processors)) - stageID := p.NewStageID() - - // Each node has a join processor. - for _, n := range nodes { - proc := distsqlplan.Processor{ - Node: n, - Spec: distsqlrun.ProcessorSpec{ - Input: []distsqlrun.InputSyncSpec{ - {ColumnTypes: leftTypes}, - {ColumnTypes: rightTypes}, - }, - Core: core, - Post: post, - Output: []distsqlrun.OutputRouterSpec{{Type: distsqlrun.OutputRouterSpec_PASS_THROUGH}}, - StageID: stageID, - }, - } - p.Processors = append(p.Processors, proc) - } - - if len(nodes) > 1 { - // Parallel hash or merge join: we distribute rows (by hash of - // equality columns) to len(nodes) join processors. - - // Set up the left routers. - for _, resultProc := range leftRouters { - p.Processors[resultProc].Spec.Output[0] = distsqlrun.OutputRouterSpec{ - Type: distsqlrun.OutputRouterSpec_BY_HASH, - HashColumns: leftEqCols, - } - } - // Set up the right routers. - for _, resultProc := range rightRouters { - p.Processors[resultProc].Spec.Output[0] = distsqlrun.OutputRouterSpec{ - Type: distsqlrun.OutputRouterSpec_BY_HASH, - HashColumns: rightEqCols, - } - } - } - p.ResultRouters = p.ResultRouters[:0] - - // Connect the left and right routers to the output joiners. Each joiner - // corresponds to a hash bucket. - for bucket := 0; bucket < len(nodes); bucket++ { - pIdx := pIdxStart + distsqlplan.ProcessorIdx(bucket) - - // Connect left routers to the processor's first input. Currently the join - // node doesn't care about the orderings of the left and right results. - p.MergeResultStreams(leftRouters, bucket, leftMergeOrd, pIdx, 0) - // Connect right routers to the processor's second input. - p.MergeResultStreams(rightRouters, bucket, rightMergeOrd, pIdx, 1) - - p.ResultRouters = append(p.ResultRouters, pIdx) - } + p.AddJoinStage( + nodes, core, post, leftTypes, rightTypes, leftEqCols, rightEqCols, + leftMergeOrd, rightMergeOrd, leftRouters, rightRouters, + ) p.planToStreamColMap = joinToStreamColMap p.ResultTypes = getTypesForPlanResult(n, joinToStreamColMap) @@ -1795,7 +1728,7 @@ func (dsp *DistSQLPlanner) createPlanForNode( return dsp.createPlanForDistinct(planCtx, n) case *unionNode: - return dsp.createPlanForUnion(planCtx, n) + return dsp.createPlanForSetOp(planCtx, n) case *valuesNode: return dsp.createPlanForValues(planCtx, n) @@ -1943,7 +1876,7 @@ func (dsp *DistSQLPlanner) isOnlyOnGateway(plan *physicalPlan) bool { return false } -func (dsp *DistSQLPlanner) createPlanForUnion( +func (dsp *DistSQLPlanner) createPlanForSetOp( planCtx *planningCtx, n *unionNode, ) (physicalPlan, error) { leftPlan, err := dsp.createPlanForNode(planCtx, n.left) @@ -1954,6 +1887,9 @@ func (dsp *DistSQLPlanner) createPlanForUnion( if err != nil { return physicalPlan{}, err } + if n.inverted { + leftPlan, rightPlan = rightPlan, leftPlan + } childPlans := []*physicalPlan{&leftPlan, &rightPlan} var distinctSpec distsqlrun.ProcessorCoreUnion @@ -1967,7 +1903,7 @@ func (dsp *DistSQLPlanner) createPlanForUnion( // group stage. In the worst case (total duplication), this causes double // the amount of data to be streamed as necessary. var distinctColumns []uint32 - for planCol := range planColumns(n.left) { + for planCol := range planColumns(n) { if streamCol := leftPlan.planToStreamColMap[planCol]; streamCol != -1 { distinctColumns = append(distinctColumns, uint32(streamCol)) } @@ -1991,8 +1927,8 @@ func (dsp *DistSQLPlanner) createPlanForUnion( var p physicalPlan // Merge the plans' planToStreamColMap, which should be equivalent. - // TODO(solon): Are there any valid UNION ALL cases where these differ? If - // we encounter any, we could handle them similarly to the differing + // TODO(solon): Are there any valid UNION/INTERSECT/EXCEPT cases where these + // differ? If we encounter any, we could handle them similarly to the differing // ResultTypes case below. if !reflect.DeepEqual(leftPlan.planToStreamColMap, rightPlan.planToStreamColMap) { return physicalPlan{}, errors.Errorf( @@ -2001,22 +1937,50 @@ func (dsp *DistSQLPlanner) createPlanForUnion( } p.planToStreamColMap = leftPlan.planToStreamColMap + columns := make([]uint32, 0, len(p.planToStreamColMap)) + for _, col := range p.planToStreamColMap { + if col < 0 { + continue + } + columns = append(columns, uint32(col)) + } + // Merge the plans' result types and merge ordering. resultTypes, err := distsqlplan.MergeResultTypes(leftPlan.ResultTypes, rightPlan.ResultTypes) mergeOrdering := leftPlan.MergeOrdering - if err != nil || !mergeOrdering.Equal(rightPlan.MergeOrdering) { + if n.unionType != tree.UnionOp { + // In INTERSECT and EXCEPT cases where the merge ordering contains columns + // that don't appear in the output (e.g. SELECT k FROM kv ORDER BY v), we + // cannot keep the ordering, since some ORDER BY columns are not also + // equality columns. As a result, update the ordering to remove these + // columns, and add a projection on the left and right sides to strip out + // these (now unused) columns. + var newMergeOrdering distsqlrun.Ordering + newMergeOrdering.Columns = make([]distsqlrun.Ordering_Column, 0, len(mergeOrdering.Columns)) + for _, ord := range mergeOrdering.Columns { + if ord.ColIdx < uint32(len(columns)) { + newMergeOrdering.Columns = append(newMergeOrdering.Columns, ord) + } + } + for _, plan := range childPlans { + plan.MergeOrdering = newMergeOrdering + projCols := make([]uint32, len(columns)) + copy(projCols, columns) + plan.AddProjection(projCols) + } + + // Re-merge the result types now that the child plans have been updated. + resultTypes, err = distsqlplan.MergeResultTypes(leftPlan.ResultTypes, rightPlan.ResultTypes) + if err != nil { + return physicalPlan{}, err + } + + mergeOrdering = newMergeOrdering + } else if err != nil || !mergeOrdering.Equal(rightPlan.MergeOrdering) { // The result types or merge ordering can differ between the two sides in // pathological cases, like if they have incompatible ORDER BY clauses. // Resolve this by collecting results on a single node and adding a // projection to the results that will be unioned. - columns := make([]uint32, 0, len(p.planToStreamColMap)) - for _, col := range p.planToStreamColMap { - if col < 0 { - continue - } - columns = append(columns, uint32(col)) - } - for _, plan := range childPlans { plan.AddSingleGroupStage( dsp.nodeDesc.NodeID, @@ -2038,7 +2002,70 @@ func (dsp *DistSQLPlanner) createPlanForUnion( var leftRouters, rightRouters []distsqlplan.ProcessorIdx p.PhysicalPlan, leftRouters, rightRouters = distsqlplan.MergePlans( &leftPlan.PhysicalPlan, &rightPlan.PhysicalPlan) - p.ResultRouters = append(leftRouters, rightRouters...) + + if n.unionType == tree.UnionOp { + // We just need to append the left and right streams together, so append + // the left and right output routers. + p.ResultRouters = append(leftRouters, rightRouters...) + } else { + // We plan INTERSECT ALL and EXCEPT ALL queries with joiners. Get the + // appropriate join type. + joinType := distsqlSetOpJoinType(n.unionType) + + // Nodes where we will run the join processors. + nodes := findJoinProcessorNodes(leftRouters, rightRouters, p.Processors) + + // Set up the equality columns. + eqCols := make([]uint32, len(columns)) + copy(eqCols, columns) + + canUseMergeJoinForSetOp := func(mergeOrdering distsqlrun.Ordering, columns []uint32) bool { + if len(mergeOrdering.Columns) != len(columns) { + return false + } + for i := range columns { + if columns[i] != mergeOrdering.Columns[i].ColIdx { + return false + } + } + return true + } + // TODO(radu): we currently only use merge joins when we have an ordering on + // all equality columns. We should relax this by either: + // - implementing a hybrid hash/merge processor which implements merge + // logic on the columns we have an ordering on, and within each merge + // group uses a hashmap on the remaining columns + // - or: adding a sort processor to complete the order + if !planMergeJoins.Get(&dsp.st.SV) || !canUseMergeJoinForSetOp(mergeOrdering, columns) { + // We must do a hash join, so there's no guaranteed output ordering. + mergeOrdering = distsqlrun.Ordering{} + } + + // Project the left-side columns only. + post := distsqlrun.PostProcessSpec{Projection: true} + post.OutputColumns = make([]uint32, len(columns)) + copy(post.OutputColumns, columns) + + // Create the Core spec. + var core distsqlrun.ProcessorCoreUnion + if mergeOrdering.Columns == nil { + core.HashJoiner = &distsqlrun.HashJoinerSpec{ + LeftEqColumns: eqCols, + RightEqColumns: eqCols, + Type: joinType, + } + } else { + core.MergeJoiner = &distsqlrun.MergeJoinerSpec{ + LeftOrdering: mergeOrdering, + RightOrdering: mergeOrdering, + Type: joinType, + } + } + + p.AddSetOpStage( + nodes, core, post, resultTypes, eqCols, mergeOrdering, leftRouters, rightRouters, + ) + } p.ResultTypes = resultTypes p.MergeOrdering = mergeOrdering diff --git a/pkg/sql/distsql_plan_join.go b/pkg/sql/distsql_plan_join.go index b0c796be38dc..1b5f5cbb4b81 100644 --- a/pkg/sql/distsql_plan_join.go +++ b/pkg/sql/distsql_plan_join.go @@ -787,3 +787,37 @@ func distsqlJoinType(joinType joinType) distsqlrun.JoinType { panic(fmt.Sprintf("invalid join type %d", joinType)) } + +func distsqlSetOpJoinType(setOpType tree.UnionType) distsqlrun.JoinType { + switch setOpType { + case tree.ExceptOp: + return distsqlrun.JoinType_EXCEPT_ALL + case tree.IntersectOp: + return distsqlrun.JoinType_INTERSECT_ALL + default: + panic(fmt.Sprintf("set op type %v unsupported by joins", setOpType)) + } +} + +func findJoinProcessorNodes( + leftRouters, rightRouters []distsqlplan.ProcessorIdx, processors []distsqlplan.Processor, +) (nodes []roachpb.NodeID) { + // TODO(radu): for now we run a join processor on every node that produces + // data for either source. In the future we should be smarter here. + seen := make(map[roachpb.NodeID]struct{}) + for _, pIdx := range leftRouters { + n := processors[pIdx].Node + if _, ok := seen[n]; !ok { + seen[n] = struct{}{} + nodes = append(nodes, n) + } + } + for _, pIdx := range rightRouters { + n := processors[pIdx].Node + if _, ok := seen[n]; !ok { + seen[n] = struct{}{} + nodes = append(nodes, n) + } + } + return nodes +} diff --git a/pkg/sql/distsqlplan/physical_plan.go b/pkg/sql/distsqlplan/physical_plan.go index a294d0609ae0..2b4f05249098 100644 --- a/pkg/sql/distsqlplan/physical_plan.go +++ b/pkg/sql/distsqlplan/physical_plan.go @@ -770,3 +770,88 @@ func MergeResultTypes(left, right []sqlbase.ColumnType) ([]sqlbase.ColumnType, e } return merged, nil } + +// AddJoinStage adds join processors at each of the specified nodes, and wires +// the left and right-side outputs to these processors. +func (p *PhysicalPlan) AddJoinStage( + nodes []roachpb.NodeID, + core distsqlrun.ProcessorCoreUnion, + post distsqlrun.PostProcessSpec, + leftTypes, rightTypes []sqlbase.ColumnType, + leftEqCols, rightEqCols []uint32, + leftMergeOrd, rightMergeOrd distsqlrun.Ordering, + leftRouters, rightRouters []ProcessorIdx, +) { + pIdxStart := ProcessorIdx(len(p.Processors)) + stageID := p.NewStageID() + + // Each node has a join processor. + for _, n := range nodes { + proc := Processor{ + Node: n, + Spec: distsqlrun.ProcessorSpec{ + Input: []distsqlrun.InputSyncSpec{ + {ColumnTypes: leftTypes}, + {ColumnTypes: rightTypes}, + }, + Core: core, + Post: post, + Output: []distsqlrun.OutputRouterSpec{{Type: distsqlrun.OutputRouterSpec_PASS_THROUGH}}, + StageID: stageID, + }, + } + p.Processors = append(p.Processors, proc) + } + + if len(nodes) > 1 { + // Parallel hash or merge join: we distribute rows (by hash of + // equality columns) to len(nodes) join processors. + + // Set up the left routers. + for _, resultProc := range leftRouters { + p.Processors[resultProc].Spec.Output[0] = distsqlrun.OutputRouterSpec{ + Type: distsqlrun.OutputRouterSpec_BY_HASH, + HashColumns: leftEqCols, + } + } + // Set up the right routers. + for _, resultProc := range rightRouters { + p.Processors[resultProc].Spec.Output[0] = distsqlrun.OutputRouterSpec{ + Type: distsqlrun.OutputRouterSpec_BY_HASH, + HashColumns: rightEqCols, + } + } + } + p.ResultRouters = p.ResultRouters[:0] + + // Connect the left and right routers to the output joiners. Each joiner + // corresponds to a hash bucket. + for bucket := 0; bucket < len(nodes); bucket++ { + pIdx := pIdxStart + ProcessorIdx(bucket) + + // Connect left routers to the processor's first input. Currently the join + // node doesn't care about the orderings of the left and right results. + p.MergeResultStreams(leftRouters, bucket, leftMergeOrd, pIdx, 0) + // Connect right routers to the processor's second input. + p.MergeResultStreams(rightRouters, bucket, rightMergeOrd, pIdx, 1) + + p.ResultRouters = append(p.ResultRouters, pIdx) + } +} + +// AddSetOpStage creates a join stage to implement INTERSECT ALL and EXCEPT ALL +// plans. +func (p *PhysicalPlan) AddSetOpStage( + nodes []roachpb.NodeID, + core distsqlrun.ProcessorCoreUnion, + post distsqlrun.PostProcessSpec, + resultTypes []sqlbase.ColumnType, + eqCols []uint32, + mergeOrdering distsqlrun.Ordering, + leftRouters, rightRouters []ProcessorIdx, +) { + p.AddJoinStage( + nodes, core, post, resultTypes, resultTypes, eqCols, eqCols, + mergeOrdering, mergeOrdering, leftRouters, rightRouters, + ) +} diff --git a/pkg/sql/distsqlrun/joinerbase.go b/pkg/sql/distsqlrun/joinerbase.go index b52b6285f532..6d77f919e15b 100644 --- a/pkg/sql/distsqlrun/joinerbase.go +++ b/pkg/sql/distsqlrun/joinerbase.go @@ -157,11 +157,11 @@ func isSetOpJoin(joinType joinType) bool { func isValidSetOpJoin(onExpr Expression, numLeftCols int, numRightCols int, numEqCols int) error { if onExpr.Expr != "" { - return errors.Errorf("Expected empty onExpr, got %v", onExpr.Expr) + return errors.Errorf("expected empty onExpr, got %v", onExpr.Expr) } if numLeftCols != numEqCols || numRightCols != numEqCols { return errors.Errorf( - "Expected %v left and right columns, got %v left and %v right columns", + "expected %v left and right columns, got %v left and %v right columns", numEqCols, numLeftCols, numRightCols) } return nil diff --git a/pkg/sql/logictest/testdata/logic_test/distsql_union b/pkg/sql/logictest/testdata/logic_test/distsql_union index 6855271b2476..b727058c9ebe 100644 --- a/pkg/sql/logictest/testdata/logic_test/distsql_union +++ b/pkg/sql/logictest/testdata/logic_test/distsql_union @@ -74,7 +74,7 @@ SELECT x FROM xyz UNION SELECT x FROM xyz ORDER BY x query T SELECT "URL" FROM [EXPLAIN (DISTSQL) SELECT x FROM xyz WHERE x < 3 UNION SELECT x FROM xyz WHERE x >= 3 ORDER BY x] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFr3DAQhe_9Fctcq8OO7E0aQWEPpbCXpKS5tT641hAMG2uRZEga_N-L7UPqJTuKLRt8tLRv3rx930GvUBlNt_kTOVC_AEGABAEJCEhBwA4yASdrCnLO2PYnveCgn0FtBZTVqfbtcSagMJZAvYIv_ZFAwUP-50j3lGuyIECTz8tjZ3Ky5VNuX_bPL39BwPfy6MmqzR43v-vtNqGvm0Qpdbh9AAF3tW9vIGsEmNq_mTmfPxIobMTHF_pWOl9WhR9uw0yXY6ZPjFuMSJssmja9OP1taF0Zq8mSHkzNmjn8d2PS_TTWn__Re_x8cfjVYDiujdzAQpHkLhN3Orlzpx2SK9dWbmChyHKXiTu93LnTDstN1lZuYKHIcpeJO73cudMOy03XVm5gochyl4k7vdy5015-ULwz_Z7cyVSOzh4W70_etg8O0o_Uv06cqW1BP6wpOpv-867TdQeanO9vsf84VP1Vu-D_YmTF6UCM52LJihPeOYlxTlnxjnfesWIpefUVq77mxdcxob-w4hve-SbGGQOMhSCLogx5zDDAGUaBhjxpGEANedZC5jxrGIANo2hDHjcM8IZRwEkeOBkATo4DLms-_QsAAP__cnI-Vw== +https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFr3DAQhe_9Fctcq8OO7E0aQWEPpbCXpKS5tT641hAMjmUkGZIG__di-5B6yY7qygYfLe2bN2_fd9Ar1EbTbf5EDtQPQBAgQUACAlIQcIBMQGNNQc4Z2_9kFJz0M6i9gLJuWt8fZwIKYwnUK_jSVwQKHvJfFd1TrsmCAE0-L6vBpLHlU25fjs8vv0HA17LyZNXuiLuf7X6fFLtEKXW6fQABd63vLyDrBJjWv3k5nz8SKOzEv-_zpXS-rAs_XYaZLudM_8-09HlG3GTVuOnF6W9D29pYTZb0ZGrWLeF_mJPuu7H-_J8-4seLw68mw3Fj5Ab2iSR3nbQR5C4dd0qu3Fi5gX0iy10nbUS5S8edlptsrNzAPpHlrpM2otyl407LTTdWbmCfyHLXSRtR7tJxLz8o3pl-T64xtaOzh8X7k_f9g4P0I42vE2daW9A3a4rBZvy8G3TDgSbnx1scP071eNUv-LcYWXE6EeO5WLLihHdOYpxTVnzgnQ-sWEpefcWqr3nxdUzoT6z4hne-iXHGAGMhyKIoQx4zDHCGUaAhTxoGUEOetZA5zxoGYMMo2pDHDQO8YRRwkgdOBoCT84DLug9_AgAA___KeT5X query I SELECT x FROM xyz WHERE x < 3 UNION SELECT x FROM xyz WHERE x >= 3 ORDER BY x @@ -89,7 +89,7 @@ SELECT x FROM xyz WHERE x < 3 UNION SELECT x FROM xyz WHERE x >= 3 ORDER BY x query T SELECT "URL" FROM [EXPLAIN (DISTSQL) SELECT x FROM xyz WHERE x <= 4 UNION SELECT x FROM xyz WHERE x > 1 ORDER BY x] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFr3DAQhe_9Fctcq8OO7E0aQWEPpbCXpKS5tT641hAMjmUkGZIG__di-5B6yY52Ixt8tLRv3rx930GvUBtNt_kTOVC_AEGABAEJCEhBwA4yAY01BTlnbP-TUXDQz6C2Asq6aX1_nAkojCVQr-BLXxEoeMj_VHRPuSYLAjT5vKwGk8aWT7l92T-__AUB38vKk1WbPW5-t9ttQhtUSh1uH0DAXev7C8g6Aab1b17O548ECjtx_j7fSufLuvDTZZjp8pLpH0xbfN2kZ8dNFo2bnpz-NrStjdVkSU-mZt0c_rtL0v001h__03v8fHL41WQ4rozcwD6R5C6TNoLcueNOyZUrKzewT2S5y6SNKHfuuNNyk5WVG9gnstxl0kaUO3fcabnpysoN7BNZ7jJpI8qdO-7pB8U70-_JNaZ2dPSweH_ytn9wkH6k8XXiTGsL-mFNMdiMn3eDbjjQ5Px4i-PHoR6v-gX_FyMrTidiPBZLVpzwzkmMc8qKd7zzjhVLyauvWPU1L76OCf2FFd_wzjcxzhhgLARZFGXIY4YBzjAKNORJwwBqyLMWMudZwwBsGEUb8rhhgDeMAk7ywMkAcPIy4LLu078AAAD__5emPlI= +https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFr3DAQhe_9Fctcq8OO7E0aQWEPpbCXpKS5tT641hAMG8tIMiQN_u_F9iH1kh1lLRt8tLRv3rx930GvUBlNt_kTOVC_AEGABAEJCEhBwA4yAbU1BTlnbPeTQXDQz6C2Asqqbnx3nAkojCVQr-BLfyRQ8JD_OdI95ZosCNDk8_LYm9S2fMrty_755S8I-F4ePVm12ePmd7PdJsXXTaqUOtw-gIC7xnc3kLUCTOPfzJzPHwkUtuLjC30rnS-rwo-3YabLS6ZPjEsb_HDaZNG06dnpb0ObylhNlvRoatbO4b-7JN1PY_3pH73Hz2eHX42G49rIDSwUSe4ycaeTO3faMblybeUGFoosd5m408udO-243GRt5QYWiix3mbjTy5077bjcdG3lBhaKLHeZuNPLnTvt-QfFO9PvydWmcnTysHh_8rZ7cJB-pOF14kxjC_phTdHbDJ93va4_0OT8cIvDx6EarroF_xcjK05HYjwVS1ac8M5JjHPKine8844VS8mrr1j1NS--jgn9hRXf8M43Mc4YYCwEWRRlyGOGAc4wCjTkScMAasizFjLnWcMAbBhFG_K4YYA3jAJO8sDJAHDyMuCy9tO_AAAA__86-T5S query I SELECT x FROM xyz WHERE x <= 4 UNION SELECT x FROM xyz WHERE x > 1 ORDER BY x @@ -104,7 +104,7 @@ SELECT x FROM xyz WHERE x <= 4 UNION SELECT x FROM xyz WHERE x > 1 ORDER BY x query T SELECT "URL" FROM [EXPLAIN (DISTSQL) SELECT x, y FROM xyz UNION ALL SELECT y, x from xyz] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzElL1qwzAUhfc-RTnzLURy0h9PXrMkJXQrHlTrEgyJZSQZkga_e4k8pAlJqSsXj_r5_PlcxDmgMpoXassO6TsECBKEBIQpCDPkhNqagp0z9nilA-Z6h3RCKKu68cftnFAYy0gP8KXfMFK8qY8Nr1hptiBo9qrcBElty62y-2y3_wRh2fj0PpOUCeQtwTT-9Enn1ZqRipb-SSsokze18qb2ZGsqYzVb1meuvL3yYwvzYOqLa9fFyZlYjDPmIbU9xizHSTuktkfaZJy0Q2p7pJ2Ok3ZI7R8L44p2xa42leNfNcLkWCis19y1jzONLfjVmiJouuUycGFDs_PdqewW8yochbl8h0UMLH-EhTijJ5d0EqOexsCzGPgxBn6KgZ9j4JeoV9LvjeXt3VcAAAD__41Qv_4= +https://cockroachdb.github.io/distsqlplan/decode.html?eJzElL1qwzAUhfc-RTnzLURy0h9PXrMkJXQrHlTrEgyJZSQZkga_e4k8pAlJqSsXj_r5_PlcxDmgMpoXassO6TsECBKEBIQpCDPkhNqagp0z9nilA-Z6h3RCKKu68cftnFAYy0gP8KXfMFK8qY8Nr1hptiBo9qrcBElty62y-2y3_wRh2fj0PhOUSeQtwTT-9Enn1ZqRipb-SSspEze18qb2ZGsqYzVb1meuvL3yYwvzYOqLa9fFyZlYjDPmIbU9xizHSTuktkfaZJy0Q2p7pJ2Ok3ZI7R8L44p2xa42leNfNcLkWCis19y1jzONLfjVmiJouuUycGFDs_PdqewW8yochbl8h0UMLH-EhTijJ5d0EqOexsCzGPgxBn6KgZ9j4JeoV9LvjeXt3VcAAAD__41Qv_4= query II rowsort SELECT x, y FROM xyz UNION ALL SELECT y, x from xyz @@ -124,7 +124,7 @@ SELECT x, y FROM xyz UNION ALL SELECT y, x from xyz query T SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) UNION ALL (SELECT x FROM xyz ORDER BY z) ORDER BY x] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFvm0AQhe_9FdVcs5U8C9guJ19zSaq0t4oD9Y4iS44X7S5S0oj_XgGVEtIwg-Wl5Gjg8c3b99j1M5ysoZvygTzkPwFBgQYFCShIQUEGhYLK2T15b137SC-4No-QrxQcTlUd2suFgr11BPkzhEM4EuTwo_x1pDsqDTlQYCiUh2MHqdzhoXRPu8en36Dgtg755x2qXQJFo8DW4eWVPpT3BDk2ajr2u3XhLXGnr16T9ChJj5JeANYZcmT-JRTNO-Pc2C-2Gj77d47RIZJz7J67yuPe0_-2ytlHWOX1xXbxavTlm2VeLi0fTl6-MfZ2wMZldgABG3EHiGxw6sc3p8Hhx6eXSVDARkwwssGpCc5pcJhgskyCAjZigpENTk1wToPDBNNlEhSwEROMbHBqgnMaHP8L8w7pjnxlT54mnbCr9oAmc0_9ge5t7fb0zdl9h-l_3na67oIhH_q72P-4PvW32gFfi5EV64EY34o1K17z5IQVp7w4ZcUZP3bGijc8ec2Ktzx5c4l4y0eV8XN_5VuyEmrCl0zoCfItQy3A-Z4JaSNfNBSahnzVJOd811D4RpBvm-ScrxtuBbhQOAHOF04LhdN84QTnWtjWhMJpvnDSrsgXTguF0-ftbUXz6U8AAAD__7-ewX0= +https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFvm0AQhe_9FdVcs5U8C9guJ19zSaq0t4oD9Y4iS44X7a6lpBH_vQIqpaRhZq0spUcDj2_evseun-FkDd3UD-Sh_A4ICjQoyEBBDgoKqBQ0zu7Je-u6RwbBtXmEcqXgcGrOobtcKdhbR1A-QziEI0EJ3-ofR7qj2pADBYZCfTj2kMYdHmr3tHt8-gkKbs-h_LhDtdNQtQrsOby80of6nqDEVsVjv1oXXhN3-iqOpCdJLwDrDDkyfxOq9o1xbuwn24yf_T3H5BDZJXYvXeVsEpv_s1Uu_odVXr_bLl5NvnyzzMul5cPo5Ztib0dsXGYHELAJd4DEBmM_vjkNjj8-vUyCAjZhgokNxiY4p8FxgtkyCQrYhAkmNhib4JwGxwnmyyQoYBMmmNhgbIJzGpz-C_MG6Y58Y0-eok7YVXdAk7mn4UD39uz29MXZfY8Zft72uv6CIR-Guzj8uD4Nt7oB_xQjK9YjMb4Wa1a85skZK855cc6KC37sghVvePKaFW958uY94i0fVcHP_ZlvyUqoCV8yoSfItwy1AOd7JqSNfNFQaBryVZOc811D4RtBvm2Sc75uuBXgQuEEOF84LRRO84UTnGthWxMKp_nCSbsiXzgtFE5ftrdV7YdfAQAA__-6tMF9 query I (SELECT x FROM xyz ORDER BY y) UNION ALL (SELECT x FROM xyz ORDER BY z) ORDER BY x @@ -143,7 +143,7 @@ query I query T SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) UNION (SELECT x FROM xyz ORDER BY z) ORDER BY x] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFvm0AQhe_9FdVcs5W8sxjbnHzoJZekSnurOFAYRUgOi5ZFShr5v1c2lRIozGABdY4G3rzZt9-O9xUKm9Fd8kQVRD9BgwIEBQYUBKBgDbGC0tmUqsq60yeN4DZ7hmilIC_K2p8exwpS6wiiV_C5PxBE8CP5daAHSjJyoCAjn-SHs0np8qfEveyfX36DgvvaR5_3Wu0NxEcFtvZvJSufPBJE-qjG2363zncd93jz3gkHnfASp6955fMi9R0vPVjdDFZ_K2pdRo6yf_uPjz0t3Nkvtmx_-3eVg00Elyzx0j0cTnb93_YwXHQPNx9hD7cjmqiLvjZ6O7g4hN3kzdQ3w6d91aqurzNlBNsZp4zgNHHKzBzf2AO-ZHzhovG1Dzhehz7Bdkb6BKeJ9M0c31j6lowvXDS-Nn3mOvQJtjPSJzhNpG_m-MbSt2R84aLxtekLrkOfYDsjfYLTRPpmjm8sfUvGFy4a3_DVuqf6A1WlLSrq3G77K69Ot17KHqm5Ile2dil9czY92zQ_78-684OMKt-81c2P26J5dWrwvVizYuTFyIpNS6y7YsOKt7w4YMVrvu01Kw55cciKN3zbmylr3rLiHd_2jt-qQKBEYEyCjKdMC5jpSZxpHjQtLZ1HTQusaR42gRfN06Y3gjnPm94Kcp44KXceOVwJs4VHDgXkkEdOyB154tAI5jxyKCCHPHJC7sgTh8J8Qx45FJBDHjkpd544FIYcClNOQM7wyEn_ZzxxRhhyRhhyAnKGR66be3z89CcAAP__hliVOw== +https://cockroachdb.github.io/distsqlplan/decode.html?eJzMlkFvm0AQhe_9FdVcs5W8sxjbnHzoJZekSnurOFAYRUgOi5ZFShr5v1c2lVwozGABdY8G3rzZt9-O9x0Km9FD8kIVRN9BgwIEBQYUBKBgDbGC0tmUqsq60yeN4D57hWilIC_K2p8exwpS6wiid_C5PxBE8C35caAnSjJyoCAjn-SHs0np8pfEve1f336CgsfaRx_3Wu0R4qMCW_tLyconzwSRPqrxtl-t813HPd6Nc8JrnD7nlc-L1He89GB1M1j9UtS6jBxlf_cfH3taeLCfbNn-9vcqB5sIrlnitXtoBm3X_2wPw0X3cPM_7OF2RBN10ddGbwdXh7CbvJn6bvi0r1rV9W2mjGA745QRnCZOmZnjG3vAl4wvXDS-9gHH29An2M5In-A0kb6Z4xtL35LxhYvG16bP3IY-wXZG-gSnifTNHN9Y-paML1w0vjZ9wW3oE2xnpE9wmkjfzPGNpW_J-MJF4xu-WvdUf6KqtEVFndttf-XV6dZL2TM1V-TK1i6lL86mZ5vm5-NZd36QUeWbt7r5cV80r04N_inWrBh5MbJi0xLrrtiw4i0vDljxmm97zYpDXhyy4g3f9mbKmreseMe3veO3KhAoERiTIOMp0wJmehJnmgdNS0vnUdMCa5qHTeBF87TpjWDO86a3gpwnTsqdRw5XwmzhkUMBOeSRE3JHnjg0gjmPHArIIY-ckDvyxKEw35BHDgXkkEdOyp0nDoUhh8KUE5AzPHLS_xlPnBGGnBGGnICc4ZHr5h4fP_wKAAD__3-YlTs= query I (SELECT x FROM xyz ORDER BY y) UNION (SELECT x FROM xyz ORDER BY z) ORDER BY x @@ -158,7 +158,7 @@ query I query T SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) UNION ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x] ---- -https://cockroachdb.github.io/distsqlplan/decode.html?eJzEljFv2zAQhff-iuJWs4CPkmxXk9YsSZF2KzSo5iEw4JgCSQNJA__3wlKBxIF1R0sENFrS08d374n0GxysofvmmTyUvwFBgQYFGSjIQUEBtYLW2S15b935kV5wZ16gXCrYHdpjOF-uFWytIyjfIOzCnqCEX82fPT1SY8iBAkOh2e07SOt2z417rV5e_4KCh2Mov1aoKq2qDOqTAnsM72_1oXkiKPGk4sk_rQufoZVeqCpbRAP1IPCdY50hR-Y6qD5dWdm9_Wbby-f_L2dwIdktzm-e-SA2TzDwOFIxYdLJpryabBcXgy9fz_NyaXwYPb4h9uaCjbPtBwI5_X6Q2mrkZzjO55jPUM-WpUBOn2Vqq5FZjvM5JststiwFcvosU1uNzHKczzFZ5rNlKZDTZ5naamSW43xO_atzhfRIvrUHT1En8fJ8kJN5ov7g9_botvTD2W2H6X8-dLrugiEf-rvY_7g79LfOC_woRlasL8T4WaxZ8YonZ6w458U5Ky74ZReseM2TV6x4w5PXU8QbPqqCX_d3viVLoSZ8yYSeIN8y1AKc75mQNvJFQ6FpyFdNcs53DYVvBPm2Sc75uuFGgAuFE-B84bRQOM0XTnCuhW1NKJzmCyftinzhtFA4fdveVp--_AsAAP__ZcDMag== +https://cockroachdb.github.io/distsqlplan/decode.html?eJzElkGPmzAQhe_9FdVc40oZA0nKietedqttbxUHGo9WkbIxsh1pt6v89ypQaZttmHHAEscAj89v3sPOGxysofvmmTyUPwFBgQYFGSjIQUEBtYLW2S15b935kV5wZ16gXCrYHdpjOF-uFWytIyjfIOzCnqCEH82vPT1SY8iBAkOh2e07SOt2z417rV5ef4OCh2MoP1eoKg31SYE9hvdX-tA8EZR4UvHY79aFj8RKL-JIepD0DrDOkCPzP6E-XVnOvf1i28tn_65jcBHZLXZvnrKqskFynmDQqsoW0cBiwrw7UKqZryY7x8Xgy9fzvFwaIUaPb4i9uWDjPPuBgE24H6Q2GP8pjvM44VPU82QpYBNmmdpgfJbjPE7IMpsnSwGbMMvUBuOzHOdxQpb5PFkK2IRZpjYYn-U4j4n-7lwBPpJv7cFT1Em8PB_kZJ6oP_i9PbotfXN222H6nw-drrtgyIf-LvY_7g79rfMC_xUjK9YXYvwo1qx4xZMzVpzz4pwVF_yyC1a85skrVrzhyesp4g0fVcGv-yvfkqVQE75kQk-QbxlqAc73TEgb-aKh0DTkqyY557uGwjeCfNsk53zdcCPAhcIJcL5wWiic5gsnONfCtiYUTvOFk3ZFvnBaKJy-bW-rT5_-BAAA___KYcxq query I (SELECT x FROM xyz ORDER BY y) UNION ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x @@ -186,3 +186,209 @@ VALUES (1), (2) UNION VALUES (2), (3) 1 2 3 + +# Basic INTERSECT ALL case -- should return every row. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz) INTERSECT ALL (SELECT y FROM xyz) ORDER BY y] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlkFv2jAUx-_7FNU7bZonYQNtiTSJ47pDO3W7TTmkxININEaOkcoqvvsEqcYSJ--P5R3CrZT87Ofn3-OfVypNru-zZ11R8pMkCVIkaEyCJiRoSqmgjTULXVXGHh6pgbv8hZKRoKLcbN3h36mghbGakldyhVtrSuhH9rTWjzrLtSVBuXZZsT5usrHFc2Z385fdbxL0sHXJ1VxRuhdktu5tvdMyT7urVVatmkvMJaX7VFDlsqWmRO7FIOtSvXWd1tmWxuba6ryxUnog0SMdh_uSVauvpijbZ1vrX-79XH74bIvl6vjX3yPK1hFP5Y9D2vrdWNfedS4_9i4-OaM3Xcd-W7SjgnvzyWzaXezce9rYWw7GFznQulRvXRfoMWhrnMdqMHcmB1qX6q3rAl0CbY1zaTyYO5MDrUv11nWBLoG2xrk0GcydyYHWpXrrukCXQFv_37tax-KPutqYstJnvYmNDo3R-VLXja7M1i70N2sWx23qjw9H7hjcua5c_a2qP9yV9VeHAs-Hb2JgKaPoaRQ942kZ0DMVBt_EwK2ehdLTKHrG06pNj_6lxw141IbHLDzhb2vCwkryW09j5oOHwXzwMJoPQIP5ADSYj-uY-eBhMB88jOYD0GA-AA3m44a19JaX9DZmPmYxhvMwMJyHkeGABoYDGiVASGz6v6QhuRlKwxAISs5gHGguvRRpqCoVL7rkYwSYLr0cCVEd0MB1QCPZEQ5sRzjS3cvQIN15GunO01B3gCPdAY5094K0qfs10N3LlCDdvUwJ0p2nke48DXUHONId4Eh3L0-DdOdppDtPQ90BjnQHONLdS9Xmu_aI11152cLqnu7f_QkAAP__jUMURA== + +query I +(SELECT y FROM xyz) INTERSECT ALL (SELECT y FROM xyz) ORDER BY y +---- +1 +1 +1 +2 +2 + +# INTERSECT ALL with MergeJoiner. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz ORDER BY y) INTERSECT ALL (SELECT y FROM xyz ORDER BY y)] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUl0Fv2k4Qxe__TxHN6V9lK7FrQxpLlbimUpMq7a3ywcFTsERYtF6k0IjvXoGlEkw8D2srY24B--c3M563L7zSwuZ8nz1zSclP0qTIkKKIFMWkaEipoqWzEy5L67a3VMBd_kLJQFGxWK789utU0cQ6puSVfOHnTAn9yJ7m_MhZzo4U5eyzYr4TWbriOXPr8cv6Nyl6WPnkamwo3SiyK79_XumzKVOiN-p0ze_W-brcWF__ldE1mT35tL6aZeWsjlK62Zdi2pTyj9qP-tN-3FjK_jnW5ew4Py4h3cIn3PVOV1_ZTfmLLRb11ub8y_8_1tcfPrtiOqv-bOx138cwrI93Kry3H-3y4N4m7dGBtj6Dg4Bmlw7qpv2oP-3HjaVcsoPMGbYYaHa5xd20H_Wn_bixlEve4ugMWww0u9zibtqP-tN-3FjKJW9xfIYtBppdbnE37Uf9aT9uLOWStxj8zHnkcmkXJZ_0H_dgWz7nU66GUtqVm_A3Zyc7merjw47bfZFz6auruvpwt6gubQt8C-s6rN_C8QGs28F6EEQPQ2gTpG2AthEnHskTj1pM3LSDaxNvSw9DaBOkbYB2LE4cvK6hCJuR_L5GIn0jwzch9pJhZC9Ag5nJNLIXoIH2J3Hit_LEb0PsJcPIXoAGKy7TyF6ABtpazhB0FB-dpocJZEAEHR2nrTJIpmEIARy1LuMwhgCO1I8O1cPBx2DwR6dqG68AGpkF4WhjZRzZBeFIXY4U9NrkSNEgU3RQqAAa-iUsVgAO_RIWLFpOFg2iRQdlC6ChX8LSBeDQL2H5YoLyxcj5YkC-mKB8ATTyC8JR62H5gnCkLueLAfligvIF0MgvCEcbG5YvCEfq7fIl3fz3JwAA___YeTHS + +query I rowsort +(SELECT y FROM xyz ORDER BY y) INTERSECT ALL (SELECT y FROM xyz ORDER BY y) +---- +1 +1 +1 +2 +2 + +# INTERSECT ALL with no overlap. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz WHERE x < 2) INTERSECT ALL (SELECT x FROM xyz WHERE x >= 2) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlk1vm0AQhu_9FdacWnUrsYDzgRTJp6rpIanS3FoOxGxtJIe1FpDiRv7vFRDJBex5vdpw4BYCz84weSYvr5TrVN0lz6qg6BdJEuSToIAEhSRoTrGgrdFLVRTa1I-0wG36QpEnKMu3VVn_Oha01EZR9EplVm4URfSYPG3Ug0pSZUhQqsok2zRFtiZ7Tsxu8bL7S4K-ZptSmWi2kLPflecFy5kfRdHt3SMJuq_K-gbFe0G6Kt9qHUo87WbrpFh3j2-ejwUVZbJSFMm9GL1ndfPOTfsnmz6cU-XapMqotHNSXJPokSNv_i0p1t91lvdffKP-lB8X8tONyVbr5qeTr3hoP7CZ-U9tyn7Vhfx88vDwjNkce-23Q490cKe_6G1_ikdrzzu15QQXYJyeR14AOe0FADN3WwB_ghKO0_PIEvrTlhDM3E3CYIISjtPzyBIG05YQzNxNwnCCEo7T88gShtOWEMz8_b5Hjxz-oIqtzgt11temVw9GpSvVDrrQlVmqH0YvmzLt5X3DNd8YqSrK9q7fXtzm7a26wfPhSxdYSid67kRf87S0mJlvB1-6wL2Z2dJzJ_qap_0-7f1PBx3Y68MBC4f8XytkYV_ypecu-8HDYD94GO0HoMF-ABrsx4XLfvAw2A8eRvsBaLAfgAb7cclaesVLeuWyH9cuhvMwMJyHkeGABoYDGiWATWwO_5Pa5KYtDUPAKjmtcaC5HKRIR1Xp86JLPkaA6XKQIzaqAxq4DmgkO8KB7QhHug8y1Ep3nka68zTUHeBId4Aj3QdB2tX9Aug-yBQr3QeZYqU7TyPdeRrqDnCkO8CR7oM8tdKdp5HuPA11BzjSHeBI90Gqdr-1PV53f5AtrO7x_sO_AAAA__8v81_z + +query I +(SELECT x FROM xyz WHERE x < 2) INTERSECT ALL (SELECT x FROM xyz WHERE x >= 2) ORDER BY x +---- + + +# INTERSECT ALL with some overlap. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz WHERE x < 3) INTERSECT ALL (SELECT y FROM xyz WHERE x >= 1) ORDER BY y] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlk9vm0wQxu_vp0BzeqtuJRZw_iBF4lQ1PThVmlvLgZitjeSw1gJS3MjfvbKJ6gLOPF5tOHCLY347s5Pf5OGFSp2refakKop_kCRBAQkKSVBEgmaUCtoYvVBVpc3-kRa4zZ8p9gUV5aap979OBS20URS_UF3Ua0UxPWSPa3WvslwZEpSrOivWhyIbUzxlZps8b3-ToM_FulYm9hLp_Wx8P1x4YRzHt_MHEnTX1LGXBJTuBOmmfq11LPG49VZZteoen0hKd6mgqs6WimK5E6P3rG48-a5NB282fTynKbXJlVF556R0T6JHTtz8S1atvuqi7F98rX7V_yfyw40plqvDT3-vKHtXPLYf2sz8uzZ1v2oiP755eHTGbE5d-_XQEx3M9Se96U_xZO1Zp7ac4AKM0_PICyCnvQBg5m4LEExQwnF6HlnCYNoSgpm7SRhOUMJxeh5ZwnDaEoKZu0kYTVDCcXoeWcJo2hKCmb_f--iJw-9VtdFlpc562_T3g1H5UrWDrnRjFuqb0YtDmfbj3YE7vGPkqqrbb4P2w23ZfrVv8Hz40gWW0omeOdHXPC0tZhbYwZcucG9mtvTMib7m6aBP-__SYQf2-3DIwhH_14pYOJB86ZnLfvAw2A8eRvsBaLAfgAb7ceGyHzwM9oOH0X4AGuwHoMF-XLKWXvGSXrnsx7WL4TwMDOdhZDiggeGARglgE5vD_6Q2uWlLwxCwSk5rHGguBynSUVUGvOiSjxFguhzkiI3qgAauAxrJjnBgO8KR7oMMtdKdp5HuPA11BzjSHeBI90GQdnW_ALoPMsVK90GmWOnO00h3noa6AxzpDnCk-yBPrXTnaaQ7T0PdAY50BzjSfZCq3Xdtn9c9GGQLq3u6--9PAAAA__8P8l_9 + +query I +(SELECT y FROM xyz WHERE x < 3) INTERSECT ALL (SELECT y FROM xyz WHERE x >= 1) ORDER BY y +---- +1 +1 + +# INTERSECT ALL with swapped column orders. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) SELECT x, y FROM xyz INTERSECT ALL SELECT y, x from xyz] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzclkFr20AQhe_9FWFOLWzBK8luLSj42PSQlNBb0UGxtrbA0YpdCeIG__ciqcG17M6zGAWMj2vp232z-sDvhQqbmbv0yXiKf5ImRQEpCklRRIqmlCgqnV0a761rXumA2-yZ4omivCjrqvk5UbS0zlD8QlVebQzF9CN93JgHk2bGkaLMVGm-aQ8pXf6Uuu3iefubFN3XVXyz0GoRULJTZOvq75b7nR63N-vUrw93eUUSRb5KV4ZivVNvlC5QCy1NF_w33X6rurAuM85kB5slDYleOTHi19Svv9m86E-4Mb-q923AD19cvlq_LriPsZ8jFMxxIuSd_WjL_rgnD44ODtYXLd-Y6caXT1-JfMFFOzBmuvEdCK7EgfCiHRgz3fgOhFfiQHTRDoyZbnwHoitxANS9B-NLW3hzVtOYNEOYbGW6S_G2dkvz3dlle0y3vG-59r80M77qngbd4rboHjUBz4dnEngugbUot57ytB5wZcEweCaB5xJYi3L3ruyIDvr05F865O87ZGF9eGeTPh1JBOdhIDgPA8F5GAkOaCD4VCI4DwPBeRgIzsNIcEADwWcSwT9JFOVhoCgPA0V5GCkKaKDoZ4miPAwU5WGgKA8jRQENFJ1LFNWingBoICmggaWARpoiHHUFWVmQtQVZXRD2BVlh0KLGoI8qwyBbeRrZytPIVp6GtgIc2TqkLB1_syFtaSiNbB3UlwbjyNaj8sDamuze_QkAAP__OIEoJA== + +query II rowsort +SELECT x, y FROM xyz INTERSECT ALL SELECT y, x from xyz +---- +1 1 + +# INTERSECT ALL with different ORDER BY types. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) INTERSECT ALL (SELECT x FROM xyz ORDER BY z) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUmEFv2kAQhe_9FdGcWmUrZdcGEqRKHJsekirtreLg4G1AIl60NlLSiP9eGVdysPE8D0a43Ar486wf_d4ueaPExfYuerYpjX-RJkWGFAWkKCRFA5oqWnk3s2nqfH5JAdzGLzS-UrRIVussf3uqaOa8pfEbZYtsaWlMP6PHpX2wUWw9KYptFi2W2yErv3iO_Ovk5fUPKbpfZ-OLiVYTQ9ONIrfOylumWfRkaaw3qv3YH85n1YkTc1lOqowpycfXi3mUzitofn25FCNZijSBoDGB4P9JIGxcSnmfdeJ8bL2Nd-40zUl0yZ7n-Rql829ukVSfaWl_Zx8n-tMXv3iab__V-Ijl8gedk9SXjTcftshm32P_u-meFdy5z25VTXHv7NHObN2Pm2DsKd08cgJt3ew1gbBxKWfo5iFJtnbT9OMHGHtKP46cQFs_ek0gbFzKGfpxSJKt_Qj68QOMPaUfR06grR-9JhA2LuUM_TgkydZ-hP34Acae0o8jJ9DWj14TCBuXcoZ-HJLkQb999tz8waYrl6S21S-bqzwYGz_ZIujUrf3Mfvduth1TvLzfcts3Yptmxae6eHGbFB_lC3wP6yqs38PhDqxlsNad6FEX2gSd6BueNmziAZ94IEjcyOBK4lJ61IWuJC6lb3g6ZBMf8IkPWHjIf9dD_rsGeo1Y-pqHr7u4ycPITUADN3kauQlo4OYN34ZXoA5rZSqxE9BIT4QDPwGOBEU4MFTXKnU3eAOC5zsVSKpr7bI7PATDa_Ui2gV5Gm6DAEf7II_DjRDgwDbNd6seguBr7SrSjaehbgBHuvE41A3gSDd-Z9Fga9G1khXpxpesASVrJCVbP3yJSlaMA90AjnRDODp48iVrQMmaWslKdAM00g3hQDeAI90QDnQz_AZjwAZj-PMr0M3wJWtAyRpJydaHi0pWjCPdRCUrxpFufMkaULJGcoCv_5cTneDFONJNdIYX40g3foMJwAYT8H8Sqeo23Xz4GwAA___8RzSn + +query I +(SELECT x FROM xyz ORDER BY y) INTERSECT ALL (SELECT x FROM xyz ORDER BY z) ORDER BY x +---- +1 +2 +3 +4 +5 + +# INTERSECT ALL with different numbers of ORDER BY columns. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) INTERSECT ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUmMFu2kwUhff_U0R39VeZSpmxgQSpkpdNF0mVdlexcPA0IBEGjY2UNMq7V8aVHGy4x9c2IHYF_PmOD_3ODHmjpUvsXfxsUxr_Ik2KDCkKSFFIigY0UbTybmrT1Pn8kgK4TV5ofKVovlyts_ztiaKp85bGb5TNs4WlMf2MHxf2wcaJ9aQosVk8X2yGrPz8Ofav0cvrH1J0v87GF5FWkaHJuyK3zspbpln8ZGms31XzsT-cz6oTI3NZTqqMKcnH14tZnM4qaH59uRQjWYo4ARUFe0MIeghBRUFfQYR7l1PeZ710PrHeJlt3muQkumTHM32N09k3N19Wn2thf2f_R_rTFz9_mm3-tfcRy-UPOqepL_fefNggm12P_e-mO1Zw5z67VTXFnbNHW7P1aRQFY4-paN8JNFe0XQgHU1Sft6Jt0mysqDmNJmDsMTXpO4HmmrQL4WCamPPWpE2ajTUJTqMJGHtMTfpOoLkm7UI4mCbBeWvSJs3GmoSn0QSMPaYmfSfQXJN2IRxMk_C8NWmTZqvfRTtu_mDTlVumttGvnqs8GJs82SLo1K391H73broZU7y833CbNxKbZsWnunhxuyw-yhf4EdZVWH-Ewy1Yy2CtO9GjLrQJOtE3PG3YxAM-8UCQuJHBlcSl9KgLXUlcSt_wdMgmPuATH7DwkP-uh_x3DfQasfQ1D193cZOHkZuABm7yNHIT0MDNG74Nr0Ad1spUYiegkZ4IB34CHAmKcGCorlXqdvAGBM93KpBU19ple3gIhtfqRbQL8jTcBgGO9kEehxshwIFtmu9WPQTB19pVpBtPQ90AjnTjcagbwJFu_M6iwdaiayUr0o0vWQNK1khKtn74EpWsGAe6ARzphnB08ORL1oCSNbWSlegGaKQbwoFuAEe6IRzoZvgNxoANxvDnV6Cb4UvWgJI1kpKtDxeVrBhHuolKVowj3fiSNaBkjeQAX_8vJzrBi3Gkm-gML8aRbvwGE4ANJuD_JFLVbfL-398AAAD__zCzO68= + +query I +(SELECT x FROM xyz ORDER BY y) INTERSECT ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x +---- +1 +2 +3 +4 +5 + +# INTERSECT ALL with compatible ORDER BY columns that are not in the final result. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz ORDER BY z) INTERSECT ALL (SELECT y FROM xyz ORDER BY z)] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUl0Fv2kAUhO_9FdE7tepWYtcLaSxV4tj0kFRpbxUHB2_BEvGi3UUKjfjvlbFUgsFvYm1l4FbAn-ft-I2neaHS5uYuezKe0l8kSZAiQQkJ0iRoSBNBS2enxnvrqktq4DZ_pnQgqCiXq1B9PRE0tc5Q-kKhCAtDKf3MHhfmwWS5cSQoNyErFluRpSueMrceP6__kKD7VUivxkqME5psBNlV2N3Sh2xmKJUb8XbZH9aFpuJYffynJBsyO_JxfTXP_LyBVtfvRlFdRvl_DiTn44BuHWV3n1VpXW6cyffuNKlIdMmR83zN_PybLcrmmRbmd3g_lh--uGI23_6r9Yi78YcR4x-Z7c5-ssvmKY8Kj_aE5WmyA2T7zE5vDiTn44BuHeUCs6NOs8JAts8V7s2B5Hwc0K2jXOAKJ6dZYSDb5wr35kByPg7o1lEucIX1aVYYyPa5wr05kJyPA7p1lAtcYfDnzIPxS1t686b_ZQ-q2U0-M7UX3q7c1Hx3drqVqT_eb7ntF7nxof5V1h9uy_qnasDXsGzC8jWs92DZDZaDKHoYQ6sobQW0Fet4wjuedHBcdYMbjnelhzG0itJWQFuzjoPHNWRhNeKf14ilr3n4OiZePIziBWjgGU-jeAEaaH9mHb_hHb-JiRcPo3gBGqw4T6N4ARpoS75D0Kv44G2630AKVNDB67RTB_E0LCGAo6PzOKwhgCP1g5fqvvEaGH_wVu2SFUCjsCAcbSyPo7ggHKnzlYIeG18pEnSKjCoVQMO8xNUKwGFe4opF8s0iQbXIqG4BNMxLXLsAHOYlrl9UVL8ovl8U6BcV1S-ARnlBODp6XL8gHKnz_aJAv6iofgE0ygvC0cbG9QvCkXq3fpls3v0NAAD__7kXNGk= + +query I rowsort +(SELECT y FROM xyz ORDER BY z) INTERSECT ALL (SELECT y FROM xyz ORDER BY z) +---- +1 +1 +1 +2 +2 + +# Basic EXCEPT ALL case. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz) EXCEPT ALL (SELECT x AS y FROM xyz) ORDER BY y] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlkFv2kwQhu_fr4jm9FXdSuzahGCpEsemh6RKe6t8cPAWLBEvWhspNOK_V-BI1F4zL6t1JbiF4Gd2dvJMXr9RaXL9kL3oipKfJEmQIkERCYpJ0JhSQWtr5rqqjN0_0gD3-SslI0FFud7U-1-ngubGakreqC7qlaaEfmTPK_2ks1xbEpTrOitWh0PWtnjJ7Hb2uv1Ngh43dXIzU5TuBJlN_V7vWOZ5e7PMqmW7xExSuksFVXW20JTInfhHfcmgvtTJvo51NqWxubY6b1VK9yR6pOdyX7Jq-dUUZfduK_2r_n8mP3y2xWJ5-OnkFY_tRz5j_W5s3T11Jj-eLB6fMZu-a78X7engwXwy6-4Ue88et86WF-rxkH0N6bG8bo_BWMM8Vhfq0pB9DemSum6XwFjDXIou1KUh-xrSpei6XQJjDXMpvlCXhuxrSJfi63YJjHW4d7We4k-6Wpuy0me9iY32g9H5QjeDrszGzvU3a-aHY5qPjwfuENy5rurmW9V8uC-br_YNng9PQmApg-hxED3laekxM-UHT0Lgzsx86XEQPeVp1aVHf9NRCx514YiFY_6vFbOwkvzR45D94GGwHzyM9gPQYD8ADfbjNmQ_eBjsBw-j_QA02A9Ag_2YsJbe8ZLehezHNMRwHgaG8zAyHNDAcECjBPCJTfc_qU9u-tIwBLyS0xsHmksnRVqqSsWLLvkYAaZLJ0d8VAc0cB3QSHaEA9sRjnR3MtRLd55GuvM01B3gSHeAI92dIG3rfgt0dzLFS3cnU7x052mkO09D3QGOdAc40t3JUy_deRrpztNQd4Aj3QGOdHdStf2uPeJ1V062sLqnu__-BAAA__8jDhQ_ + +query I +(SELECT y FROM xyz) EXCEPT ALL (SELECT x AS y FROM xyz) ORDER BY y +---- +1 +1 +2 + +# EXCEPT ALL with MergeJoiner. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz ORDER BY y) EXCEPT ALL (SELECT y FROM xyz ORDER BY y)] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUl0Fv2k4Qxe__TxHN6V9lK7FrQxpLlbimUpMq7a3ywcFTsERYtF6k0IjvXoGlEkw8D2srY24B--c3M563L7zSwuZ8nz1zSclP0qTIkKKIFMWkaEipoqWzEy5L67a3VMBd_kLJQFGxWK789utU0cQ6puSVfOHnTAn9yJ7m_MhZzo4U5eyzYr4TWbriOXPr8cv6Nyl6WPnkamwo3SiyK79_XumzKVOiN-p0ze_W-brcWF__ldE1mT35tL6aZeWsjlK62Zdi2pTyj9qP-tN-3FjK_jnW5ew4Py4h3cIn3PVOV1_ZTfmLLRb11ub8y_8_1tcfPrtiOqv-bOx138cwrI93Kry3H-3y4N4m7dGBtj6Dg4Bmlw7qpv2oP-3HjaVcsoPMGbYYaHa5xd20H_Wn_bixlEve4ugMWww0u9zibtqP-tN-3FjKJW9xfIYtBppdbnE37Uf9aT9uLOWStxj8zHnkcmkXJZ_0H_dgWz7nU66GUtqVm_A3Zyc7merjw47bfZFz6auruvpwt6gubQt8C-s6rN_C8QGs28F6EEQPQ2gTpG2AthEnHskTj1pM3LSDaxNvSw9DaBOkbYB2LE4cvK6hCJuR_L5GIn0jwzch9pJhZC9Ag5nJNLIXoIH2J3Hit_LEb0PsJcPIXoAGKy7TyF6ABtpazhB0FB-dpocJZEAEHR2nrTJIpmEIARy1LuMwhgCO1I8O1cPBx2DwR6dqG68AGpkF4WhjZRzZBeFIXY4U9NrkSNEgU3RQqAAa-iUsVgAO_RIWLFpOFg2iRQdlC6ChX8LSBeDQL2H5YoLyxcj5YkC-mKB8ATTyC8JR62H5gnCkLueLAfligvIF0MgvCEcbG5YvCEfq7fIl3fz3JwAA___YeTHS + +query I rowsort +(SELECT y FROM xyz ORDER BY y) EXCEPT ALL (SELECT y FROM xyz ORDER BY y) +---- + + +# EXCEPT ALL with no overlap. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz WHERE x < 2) EXCEPT ALL (SELECT x FROM xyz WHERE x >= 2) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlk1vm0AQhu_9FdacWnUrsYDzgRTJp6rpIanS3FoOxGxtJIe1FpDiRv7vFRDJBex5vdpw4BYCz84weSYvr5TrVN0lz6qg6BdJEuSToIAEhSRoTrGgrdFLVRTa1I-0wG36QpEnKMu3VVn_Oha01EZR9EplVm4URfSYPG3Ug0pSZUhQqsok2zRFtiZ7Tsxu8bL7S4K-ZptSmWi2kLPflecFy5kfRdHt3SMJuq_K-gbFe0G6Kt9qHUo87WbrpFh3j2-ejwUVZbJSFMm9GL1ndfPOTfsnmz6cU-XapMqotHNSXJPokSNv_i0p1t91lvdffKP-lB8X8tONyVbr5qeTr3hoP7CZ-U9tyn7Vhfx88vDwjNkce-23Q490cKe_6G1_ikdrzzu15QQXYJyeR14AOe0FADN3WwB_ghKO0_PIEvrTlhDM3E3CYIISjtPzyBIG05YQzNxNwnCCEo7T88gShtOWEMz8_b5Hjxz-oIqtzgt11temVw9GpSvVDrrQlVmqH0YvmzLt5X3DNd8YqSrK9q7fXtzm7a26wfPhSxdYSid67kRf87S0mJlvB1-6wL2Z2dJzJ_qap_0-7f1PBx3Y68MBC4f8XytkYV_ypecu-8HDYD94GO0HoMF-ABrsx4XLfvAw2A8eRvsBaLAfgAb7cclaesVLeuWyH9cuhvMwMJyHkeGABoYDGiWATWwO_5Pa5KYtDUPAKjmtcaC5HKRIR1Xp86JLPkaA6XKQIzaqAxq4DmgkO8KB7QhHug8y1Ep3nka68zTUHeBId4Aj3QdB2tX9Aug-yBQr3QeZYqU7TyPdeRrqDnCkO8CR7oM8tdKdp5HuPA11BzjSHeBI90Gqdr-1PV53f5AtrO7x_sO_AAAA__8v81_z + +query I +(SELECT x FROM xyz WHERE x < 2) EXCEPT ALL (SELECT x FROM xyz WHERE x >= 2) ORDER BY x +---- +1 + +# EXCEPT ALL with some overlap. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz WHERE x >= 1) EXCEPT ALL (SELECT y FROM xyz WHERE x < 3) ORDER BY y] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUlk9vm0wQxu_vp0BzeqtuJRZw_iBF4lQ1PThVmlvLgZitjeSw1gJS3MjfvbKJ6gLOPF5tOHCLY347s5Pf5OGFSp2refakKop_kCRBAQkKSVBEgmaUCtoYvVBVpc3-kRa4zZ8p9gUV5aap979OBS20URS_UF3Ua0UxPWSPa3WvslwZEpSrOivWhyIbUzxlZps8b3-ToM_FulYm9hLp_Wx8P1Q3nozj-Hb-QILumjr2koDSnSDd1K_FjjUet94qq1bd8xNJ6S4VVNXZUlEsd2L0phde-K49B2_2fDynKbXJlVF556R0T6JHTlz8S1atvuqi7N97rX7V_yfyw40plqvDT3-vKHtXPLYf2oz8uzZ1v2oiP755eHTGbE5d-_XQEx3M9Se96U_xZO1Zp7ac4gKM0_S4CyCnvQBg5G4LEExRwnGaHlfCYNoSgpG7SRhOUcJxmh5XwnDaEoKRu0kYTVHCcZoeV8Jo2hKCkb_f--iJw-9VtdFlpc562_T3g1H5UrWDrnRjFuqb0YtDmfbj3YE7vGPkqqrbb4P2w23ZfrVv8Hz40gWW0omeOdHXPC0tZhbYwZcucG9mtvTMib7m6aBP-__SYQf2-3DIwhH_14pYOJB86ZnLfvAw2A8eRvsBaLAfgAb7ceGyHzwM9oOH0X4AGuwHoMF-XLKWXvGSXrnsx7WL4TwMDOdhZDiggeGARglgE5vD_6Q2uWlLwxCwSk5rHGguBynSUVUGvOiSjxFguhzkiI3qgAauAxrJjnBgO8KR7oMMtdKdp5HuPA11BzjSHeBI90GQdnW_ALoPMsVK90GmWOnO00h3noa6AxzpDnCk-yBPrXTnaaQ7T0PdAY50BzjSfZCq3Xdtn9c9GGQLq3u6--9PAAAA___IwV_9 + +query I +(SELECT y FROM xyz WHERE x >= 1) EXCEPT ALL (SELECT y FROM xyz WHERE x < 3) ORDER BY y +---- +1 +2 +2 + +# EXCEPT ALL with swapped column orders. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) SELECT x, y FROM xyz EXCEPT ALL SELECT y, x from xyz] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzclkFr20AQhe_9FWFOLWzBK8luLSj42PSQlNBb0UGxtrbA0YpdCeIG__ciqcG17M6zGAWMj2vp232z-sDvhQqbmbv0yXiKf5ImRQEpCklRRIqmlCgqnV0a761rXumA2-yZ4omivCjrqvk5UbS0zlD8QlVebQzF9CN93JgHk2bGkaLMVGm-aQ8pXf6Uuu3iefubFN3XVXyz0GoRULJTZOvq75b7nR63N-vUrw93eUUSRb5KV4ZivVNvlC5QCy1NF_w33X6rurAuM85kB5slDYleOTHi19Svv9m86E-4Mb-q923AD19cvlq_LriPsZ8jFMxxIuSd_WjL_rgnD44ODtYXLd-Y6caXT1-JfMFFOzBmuvEdCK7EgfCiHRgz3fgOhFfiQHTRDoyZbnwHoitxANS9B-NLW3hzVtOYNEOYbGW6S_G2dkvz3dlle0y3vG-59r80M77qngbd4rboHjUBz4dnEngugbUot57ytB5wZcEweCaB5xJYi3L3ruyIDvr05F865O87ZGF9eGeTPh1JBOdhIDgPA8F5GAkOaCD4VCI4DwPBeRgIzsNIcEADwWcSwT9JFOVhoCgPA0V5GCkKaKDoZ4miPAwU5WGgKA8jRQENFJ1LFNWingBoICmggaWARpoiHHUFWVmQtQVZXRD2BVlh0KLGoI8qwyBbeRrZytPIVp6GtgIc2TqkLB1_syFtaSiNbB3UlwbjyNaj8sDamuze_QkAAP__OIEoJA== + +query II rowsort +SELECT x, y FROM xyz EXCEPT ALL SELECT y, x from xyz +---- +2 1 +3 1 +4 2 +5 2 + +# EXCEPT ALL with different ORDER BY types. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) EXCEPT ALL (SELECT y AS x FROM xyz ORDER BY z) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUmEFv2kAQhe_9FdGcWmUrZdcGEqRKHJsekirtreLg4G1AIl60NlLSiP9eGVdysPE8D0a43Ar486wf_d4ueaPExfYuerYpjX-RJkWGFAWkKCRFA5oqWnk3s2nqfH5JAdzGLzS-UrRIVussf3uqaOa8pfEbZYtsaWlMP6PHpX2wUWw9KYptFi2W2yErv3iO_Ovk5fUPKbpfZ-OLiVYTQ9ONIrfOylumWfRkaaw3qv3YH85n1YkTc1lOqowpycfXi3mUzitofn25FCNZiigBoyZBYwLB_5NA2LiU8j7rxPnYehvv3Gmak-iSPc_zNUrn39wiqT7T0v7OPk70py9-8TTf_qvxEcvlDzonqS8bbz5skc2-x_530z0ruHOf3aqa4t7Zo53Zuh83wdhTunnMBARu9ppA2LiUM3TzkCRbu2n68QOMPaUfx0xA4EevCYSNSzlDPw5JsrUfQT9-gLGn9OOYCQj86DWBsHEpZ-jHIUm29iPsxw8w9pR-HDMBgR-9JhA2LuUM_TgkyYN---y5-YNNVy5JbatfNld5MDZ-skXQqVv7mf3u3Ww7pnh5v-W2b8Q2zYpPdfHiNik-yhf4HtZVWL-Hwx1Yy2CtO9GjLrQJOtE3PG3YxAM-8UCQuJHBlcSl9KgLXUlcSt_wdMgmPuATH7DwkP-uh_x3DfQasfQ1D193cZOHkZuABm7yNHIT0MDNG74Nr0Ad1spUYiegkZ4IB34CHAmKcGCorlXqbvAGBM93KpBU19pld3gIhtfqRbQL8jTcBgGO9kEehxshwIFtmu9WPQTB19pVpBtPQ90AjnTjcagbwJFu_M6iwdaiayUr0o0vWQNK1khKtn74EpWsGAe6ARzphnB08ORL1oCSNbWSlegGaKQbwoFuAEe6IRzoZvgNxoANxvDnV6Cb4UvWgJI1kpKtDxeVrBhHuolKVowj3fiSNaBkjeQAX_8vJzrBi3Gkm-gML8aRbvwGE4ANJuD_JFLVbbr58DcAAP__fYM0rA== + +query I +(SELECT x FROM xyz ORDER BY y) EXCEPT ALL (SELECT y AS x FROM xyz ORDER BY z) ORDER BY x +---- +3 +4 +5 + +# EXCEPT ALL with different numbers of ORDER BY columns. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT x FROM xyz ORDER BY y) EXCEPT ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUmMFu2kwUhff_U0R39VeZSpmxgQSpkpdNF0mVdlexcPA0IBEGjY2UNMq7V8aVHGy4x9c2IHYF_PmOD_3ODHmjpUvsXfxsUxr_Ik2KDCkKSFFIigY0UbTybmrT1Pn8kgK4TV5ofKVovlyts_ztiaKp85bGb5TNs4WlMf2MHxf2wcaJ9aQosVk8X2yGrPz8Ofav0cvrH1J0v87GF5FWkaHJuyK3zspbpln8ZGms31XzsT-cz6oTI3NZTqqMKcnH14tZnM4qaH59uRQjWYo4ARUFe0MIeghBRUFfQYR7l1PeZ710PrHeJlt3muQkumTHM32N09k3N19Wn2thf2f_R_rTFz9_mm3-tfcRy-UPOqepL_fefNggm12P_e-mO1Zw5z67VTXFnbNHW7P1aRQFY4-paN8JNFe0XQgHU1Sft6Jt0mysqDmNJmDsMTXpO4HmmrQL4WCamPPWpE2ajTUJTqMJGHtMTfpOoLkm7UI4mCbBeWvSJs3GmoSn0QSMPaYmfSfQXJN2IRxMk_C8NWmTZqvfRTtu_mDTlVumttGvnqs8GJs82SLo1K391H73broZU7y833CbNxKbZsWnunhxuyw-yhf4EdZVWH-Ewy1Yy2CtO9GjLrQJOtE3PG3YxAM-8UCQuJHBlcSl9KgLXUlcSt_wdMgmPuATH7DwkP-uh_x3DfQasfQ1D193cZOHkZuABm7yNHIT0MDNG74Nr0Ad1spUYiegkZ4IB34CHAmKcGCorlXqdvAGBM93KpBU19ple3gIhtfqRbQL8jTcBgGO9kEehxshwIFtmu9WPQTB19pVpBtPQ90AjnTjcagbwJFu_M6iwdaiayUr0o0vWQNK1khKtn74EpWsGAe6ARzphnB08ORL1oCSNbWSlegGaKQbwoFuAEe6IRzoZvgNxoANxvDnV6Cb4UvWgJI1kpKtDxeVrBhHuolKVowj3fiSNaBkjeQAX_8vJzrBi3Gkm-gML8aRbvwGE4ANJuD_JFLVbfL-398AAAD__zCzO68= + +query I +(SELECT x FROM xyz ORDER BY y) EXCEPT ALL (SELECT x FROM xyz ORDER BY y, z) ORDER BY x +---- + + +# EXCEPT ALL with compatible ORDER BY columns that are not in the final result. +query T +SELECT "URL" FROM [EXPLAIN (DISTSQL) (SELECT y FROM xyz ORDER BY z) EXCEPT ALL (SELECT y FROM xyz ORDER BY z)] +---- +https://cockroachdb.github.io/distsqlplan/decode.html?eJzUl0Fv2kAUhO_9FdE7tepWYtcLaSxV4tj0kFRpbxUHB2_BEvGi3UUKjfjvlbFUgsFvYm1l4FbAn-ft-I2neaHS5uYuezKe0l8kSZAiQQkJ0iRoSBNBS2enxnvrqktq4DZ_pnQgqCiXq1B9PRE0tc5Q-kKhCAtDKf3MHhfmwWS5cSQoNyErFluRpSueMrceP6__kKD7VUivxkqME5psBNlV2N3Sh2xmKJUb8XbZH9aFpuJYffynJBsyO_JxfTXP_LyBVtfvRlFdRvl_DiTn44BuHWV3n1VpXW6cyffuNKlIdMmR83zN_PybLcrmmRbmd3g_lh--uGI23_6r9Yi78YcR4x-Z7c5-ssvmKY8Kj_aE5WmyA2T7zE5vDiTn44BuHeUCs6NOs8JAts8V7s2B5Hwc0K2jXOAKJ6dZYSDb5wr35kByPg7o1lEucIX1aVYYyPa5wr05kJyPA7p1lAtcYfDnzIPxS1t686b_ZQ-q2U0-M7UX3q7c1Hx3drqVqT_eb7ntF7nxof5V1h9uy_qnasDXsGzC8jWs92DZDZaDKHoYQ6sobQW0Fet4wjuedHBcdYMbjnelhzG0itJWQFuzjoPHNWRhNeKf14ilr3n4OiZePIziBWjgGU-jeAEaaH9mHb_hHb-JiRcPo3gBGqw4T6N4ARpoS75D0Kv44G2630AKVNDB67RTB_E0LCGAo6PzOKwhgCP1g5fqvvEaGH_wVu2SFUCjsCAcbSyPo7ggHKnzlYIeG18pEnSKjCoVQMO8xNUKwGFe4opF8s0iQbXIqG4BNMxLXLsAHOYlrl9UVL8ovl8U6BcV1S-ARnlBODp6XL8gHKnz_aJAv6iofgE0ygvC0cbG9QvCkXq3fpls3v0NAAD__7kXNGk= + +query I rowsort +(SELECT y FROM xyz ORDER BY z) EXCEPT ALL (SELECT y FROM xyz ORDER BY z) +---- +