diff --git a/build/builder/mkrelease.sh b/build/builder/mkrelease.sh index 8ad60b07cec2..e2ccc0bfffd8 100755 --- a/build/builder/mkrelease.sh +++ b/build/builder/mkrelease.sh @@ -39,7 +39,9 @@ case "${1-}" in XGOARCH=amd64 XCMAKE_SYSTEM_NAME=Linux TARGET_TRIPLE=x86_64-unknown-linux-gnu - LDFLAGS="-static-libgcc -static-libstdc++" +# -lrt is needed as clock_gettime isn't part of glibc prior to 2.17 +# once we update - the -lrt can be removed + LDFLAGS="-static-libgcc -static-libstdc++ -lrt" SUFFIX=-linux-2.6.32-gnu-amd64 ) ;; diff --git a/pkg/base/config.go b/pkg/base/config.go index 1cd126cfda44..efb31708f656 100644 --- a/pkg/base/config.go +++ b/pkg/base/config.go @@ -213,6 +213,10 @@ type Config struct { // connections to determine connection health and update the local view // of remote clocks. RPCHeartbeatInterval time.Duration + + // Enables the use of an PTP hardware clock user space API for HLC current time. + // This contains the path to the device to be used (i.e. /dev/ptp0) + ClockDevicePath string } func wrapError(err error) error { @@ -243,6 +247,7 @@ func (cfg *Config) InitDefaults() { cfg.RPCHeartbeatInterval = defaultRPCHeartbeatInterval cfg.ClusterName = "" cfg.DisableClusterNameVerification = false + cfg.ClockDevicePath = "" } // HTTPRequestScheme returns "http" or "https" based on the value of diff --git a/pkg/cli/cliflags/flags.go b/pkg/cli/cliflags/flags.go index 955ed0deaa26..82a14db6a3af 100644 --- a/pkg/cli/cliflags/flags.go +++ b/pkg/cli/cliflags/flags.go @@ -673,6 +673,20 @@ fields. Description: `Path to the CA key.`, } + ClockDevice = FlagInfo{ + Name: "clock-device", + Description: ` +Override HLC to use PTP hardware clock user space API when querying for current time. +The value corresponds to the clock device to be used. This is currently only tested +and supported on Linux. +
+
+  --clock-device=/dev/ptp0
+
+
+`, + } + MaxOffset = FlagInfo{ Name: "max-offset", Description: ` diff --git a/pkg/cli/flags.go b/pkg/cli/flags.go index ed286dbf7dbe..10f66694b121 100644 --- a/pkg/cli/flags.go +++ b/pkg/cli/flags.go @@ -358,6 +358,7 @@ func init() { VarFlag(f, &serverCfg.Stores, cliflags.Store) VarFlag(f, &serverCfg.StorageEngine, cliflags.StorageEngine) VarFlag(f, &serverCfg.MaxOffset, cliflags.MaxOffset) + StringFlag(f, &serverCfg.ClockDevicePath, cliflags.ClockDevice, "") StringFlag(f, &startCtx.listeningURLFile, cliflags.ListeningURLFile, startCtx.listeningURLFile) diff --git a/pkg/server/server.go b/pkg/server/server.go index 86e7762d5737..a4fddf16523d 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -230,7 +230,16 @@ func NewServer(cfg Config, stopper *stop.Stopper) (*Server, error) { panic(errors.New("no tracer set in AmbientCtx")) } - clock := hlc.NewClock(hlc.UnixNano, time.Duration(cfg.MaxOffset)) + var clock *hlc.Clock + if cfg.ClockDevicePath != "" { + clockSrc, err := hlc.MakeClockSource(context.Background(), cfg.ClockDevicePath) + if err != nil { + return nil, errors.Wrap(err, "instantiating clock source") + } + clock = hlc.NewClock(clockSrc.UnixNano, time.Duration(cfg.MaxOffset)) + } else { + clock = hlc.NewClock(hlc.UnixNano, time.Duration(cfg.MaxOffset)) + } s := &Server{ st: st, clock: clock, diff --git a/pkg/sql/colexec/external_hash_joiner_test.go b/pkg/sql/colexec/external_hash_joiner_test.go index 2153d1804454..b1e24b477c18 100644 --- a/pkg/sql/colexec/external_hash_joiner_test.go +++ b/pkg/sql/colexec/external_hash_joiner_test.go @@ -58,7 +58,7 @@ func TestExternalHashJoiner(t *testing.T) { // which the joiner spills to disk. for _, spillForced := range []bool{false, true} { flowCtx.Cfg.TestingKnobs.ForceDiskSpill = spillForced - for _, tcs := range [][]joinTestCase{hjTestCases, mjTestCases} { + for _, tcs := range [][]*joinTestCase{hjTestCases, mjTestCases} { for _, tc := range tcs { delegateFDAcquisitions := rng.Float64() < 0.5 t.Run(fmt.Sprintf("spillForced=%t/%s/delegateFDAcquisitions=%t", spillForced, tc.description, delegateFDAcquisitions), func(t *testing.T) { @@ -139,15 +139,17 @@ func TestExternalHashJoinerFallbackToSortMergeJoin(t *testing.T) { nBatches := 2 leftSource := newFiniteBatchSource(batch, nBatches) rightSource := newFiniteBatchSource(batch, nBatches) - spec := createSpecForHashJoiner(joinTestCase{ - joinType: sqlbase.JoinType_INNER, - leftTypes: sourceTypes, - leftOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightTypes: sourceTypes, - rightOutCols: []uint32{0}, - rightEqCols: []uint32{0}, - }) + tc := &joinTestCase{ + joinType: sqlbase.JoinType_INNER, + leftPhysTypes: sourceTypes, + leftOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightPhysTypes: sourceTypes, + rightOutCols: []uint32{0}, + rightEqCols: []uint32{0}, + } + tc.init() + spec := createSpecForHashJoiner(tc) var spilled bool queueCfg, cleanup := colcontainerutils.NewTestingDiskQueueCfg(t, true /* inMem */) defer cleanup() @@ -241,15 +243,17 @@ func BenchmarkExternalHashJoiner(b *testing.B) { if fullOuter { joinType = sqlbase.JoinType_FULL_OUTER } - spec := createSpecForHashJoiner(joinTestCase{ - joinType: joinType, - leftTypes: sourceTypes, - leftOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 2}, - rightTypes: sourceTypes, - rightOutCols: []uint32{2, 3}, - rightEqCols: []uint32{0, 1}, - }) + tc := &joinTestCase{ + joinType: joinType, + leftPhysTypes: sourceTypes, + leftOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 2}, + rightPhysTypes: sourceTypes, + rightOutCols: []uint32{2, 3}, + rightEqCols: []uint32{0, 1}, + } + tc.init() + spec := createSpecForHashJoiner(tc) b.Run(name, func(b *testing.B) { // 8 (bytes / int64) * nBatches (number of batches) * col.BatchSize() (rows / // batch) * nCols (number of columns / row) * 2 (number of sources). diff --git a/pkg/sql/colexec/hashjoiner_test.go b/pkg/sql/colexec/hashjoiner_test.go index d545567d4f4f..70cab53bee40 100644 --- a/pkg/sql/colexec/hashjoiner_test.go +++ b/pkg/sql/colexec/hashjoiner_test.go @@ -22,7 +22,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/col/coltypes" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/colexec/execerror" - "github.com/cockroachdb/cockroach/pkg/sql/colexec/typeconv" "github.com/cockroachdb/cockroach/pkg/sql/execinfra" "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" @@ -35,7 +34,7 @@ import ( var ( floats = []float64{0.314, 3.14, 31.4, 314} decs []apd.Decimal - hjTestCases []joinTestCase + hjTestCases []*joinTestCase ) func init() { @@ -48,11 +47,11 @@ func init() { } } - hjTestCases = []joinTestCase{ + hjTestCases = []*joinTestCase{ { - description: "0", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "0", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{ {0}, @@ -86,9 +85,9 @@ func init() { }, }, { - description: "1", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "1", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test an empty build table. leftTuples: tuples{}, @@ -113,9 +112,9 @@ func init() { }, }, { - description: "2", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "2", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{ {0}, @@ -148,9 +147,9 @@ func init() { }, }, { - description: "3", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "3", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test right outer join. leftTuples: tuples{ @@ -177,9 +176,9 @@ func init() { }, }, { - description: "4", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "4", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test right outer join with non-distinct left build table with an // unmatched row from the right followed by a matched one. This is a @@ -209,9 +208,9 @@ func init() { }, }, { - description: "5", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "5", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test null handling only on probe column. leftTuples: tuples{ @@ -235,9 +234,9 @@ func init() { }, }, { - description: "6", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "6", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test null handling only on build column. leftTuples: tuples{ @@ -266,9 +265,9 @@ func init() { }, }, { - description: "7", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + description: "7", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, // Test null handling in output columns. leftTuples: tuples{ @@ -300,9 +299,9 @@ func init() { }, }, { - description: "8", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "8", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test null handling in hash join key column. leftTuples: tuples{ @@ -335,9 +334,9 @@ func init() { }, { // Test handling of multiple column non-distinct equality keys. - description: "9", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + description: "9", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftTuples: tuples{ {0, 0, 1}, @@ -374,9 +373,9 @@ func init() { }, { // Test handling of duplicate equality keys that map to same buckets. - description: "10", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "10", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{ {0}, @@ -421,9 +420,9 @@ func init() { }, { // Test handling of duplicate equality keys. - description: "11", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "11", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{ {0}, @@ -460,9 +459,9 @@ func init() { }, { // Test handling of various output column coltypes. - description: "12", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int64, coltypes.Bytes, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Float64, coltypes.Int32}, + description: "12", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int64, coltypes.Bytes, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Float64, coltypes.Int32}, leftTuples: tuples{ {false, 5, "a", 10}, @@ -493,9 +492,9 @@ func init() { }, }, { - description: "13", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "13", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Reverse engineering hash table hash heuristic to find key values that // hash to the same bucket. @@ -526,9 +525,9 @@ func init() { }, }, { - description: "14", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "14", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, // Test a N:1 inner join where the right side key has duplicate values. leftTuples: tuples{ @@ -563,9 +562,9 @@ func init() { }, }, { - description: "15", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + description: "15", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, // Test inner join on multiple equality columns. leftTuples: tuples{ @@ -600,9 +599,9 @@ func init() { }, }, { - description: "16", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + description: "16", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, // Test multiple column with values that hash to the same bucket. leftTuples: tuples{ @@ -635,9 +634,9 @@ func init() { }, }, { - description: "17", - leftTypes: []coltypes.T{coltypes.Bytes, coltypes.Bool, coltypes.Int16, coltypes.Int32, coltypes.Int64, coltypes.Bytes}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int32, coltypes.Int16, coltypes.Bool, coltypes.Bytes}, + description: "17", + leftPhysTypes: []coltypes.T{coltypes.Bytes, coltypes.Bool, coltypes.Int16, coltypes.Int32, coltypes.Int64, coltypes.Bytes}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int32, coltypes.Int16, coltypes.Bool, coltypes.Bytes}, // Test multiple equality columns of different coltypes. leftTuples: tuples{ @@ -673,9 +672,9 @@ func init() { }, }, { - description: "18", - leftTypes: []coltypes.T{coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Float64}, + description: "18", + leftPhysTypes: []coltypes.T{coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Float64}, // Test equality columns of type float. leftTuples: tuples{ @@ -706,9 +705,9 @@ func init() { }, }, { - description: "19", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64, coltypes.Int64}, + description: "19", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64, coltypes.Int64}, // Test use right side as build table. leftTuples: tuples{ @@ -738,9 +737,9 @@ func init() { }, }, { - description: "20", - leftTypes: []coltypes.T{coltypes.Decimal}, - rightTypes: []coltypes.T{coltypes.Decimal}, + description: "20", + leftPhysTypes: []coltypes.T{coltypes.Decimal}, + rightPhysTypes: []coltypes.T{coltypes.Decimal}, // Test coltypes.Decimal type as equality column. leftTuples: tuples{ @@ -768,9 +767,9 @@ func init() { }, }, { - description: "21", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "21", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, joinType: sqlbase.JoinType_LEFT_SEMI, @@ -801,9 +800,9 @@ func init() { }, }, { - description: "22", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + description: "22", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, joinType: sqlbase.JoinType_LEFT_ANTI, @@ -832,9 +831,9 @@ func init() { }, }, { - description: "23", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + description: "23", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, // Test ON expression. leftTuples: tuples{ @@ -865,9 +864,9 @@ func init() { }, }, { - description: "24", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + description: "24", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, // Test ON expression. leftTuples: tuples{ @@ -902,7 +901,7 @@ func init() { // createSpecForHashJoiner creates a hash join processor spec based on a test // case. -func createSpecForHashJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { +func createSpecForHashJoiner(tc *joinTestCase) *execinfrapb.ProcessorSpec { hjSpec := &execinfrapb.HashJoinerSpec{ LeftEqColumns: tc.leftEqCols, RightEqColumns: tc.rightEqCols, @@ -913,14 +912,14 @@ func createSpecForHashJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { } projection := make([]uint32, 0, len(tc.leftOutCols)+len(tc.rightOutCols)) projection = append(projection, tc.leftOutCols...) - rColOffset := uint32(len(tc.leftTypes)) + rColOffset := uint32(len(tc.leftPhysTypes)) for _, outCol := range tc.rightOutCols { projection = append(projection, rColOffset+outCol) } return &execinfrapb.ProcessorSpec{ Input: []execinfrapb.InputSyncSpec{ - {ColumnTypes: typeconv.ToColumnTypes(tc.leftTypes)}, - {ColumnTypes: typeconv.ToColumnTypes(tc.rightTypes)}, + {ColumnTypes: tc.leftLogTypes}, + {ColumnTypes: tc.rightLogTypes}, }, Core: execinfrapb.ProcessorCoreUnion{ HashJoiner: hjSpec, @@ -936,11 +935,11 @@ func createSpecForHashJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { // against a hash join operator (either in-memory or disk-backed one) which is // created by the provided constructor. func runHashJoinTestCase( - t *testing.T, tc joinTestCase, hjOpConstructor func(sources []Operator) (Operator, error), + t *testing.T, tc *joinTestCase, hjOpConstructor func(sources []Operator) (Operator, error), ) { tc.init() inputs := []tuples{tc.leftTuples, tc.rightTuples} - typs := [][]coltypes.T{tc.leftTypes, tc.rightTypes} + typs := [][]coltypes.T{tc.leftPhysTypes, tc.rightPhysTypes} var runner testRunner if tc.skipAllNullsInjection { // We're omitting all nulls injection test. See comments for each such @@ -971,7 +970,7 @@ func TestHashJoiner(t *testing.T) { // it. continue } - for _, tcs := range [][]joinTestCase{hjTestCases, mjTestCases} { + for _, tcs := range [][]*joinTestCase{hjTestCases, mjTestCases} { for _, tc := range tcs { for _, tc := range tc.mutateTypes() { runHashJoinTestCase(t, tc, func(sources []Operator) (Operator, error) { diff --git a/pkg/sql/colexec/mergejoiner_test.go b/pkg/sql/colexec/mergejoiner_test.go index 42a93da21ee0..9e8e8ba4455f 100644 --- a/pkg/sql/colexec/mergejoiner_test.go +++ b/pkg/sql/colexec/mergejoiner_test.go @@ -18,7 +18,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/col/coltypes" "github.com/cockroachdb/cockroach/pkg/settings/cluster" - "github.com/cockroachdb/cockroach/pkg/sql/colexec/typeconv" "github.com/cockroachdb/cockroach/pkg/sql/execinfra" "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" @@ -31,7 +30,7 @@ import ( "github.com/stretchr/testify/require" ) -func createSpecForMergeJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { +func createSpecForMergeJoiner(tc *joinTestCase) *execinfrapb.ProcessorSpec { leftOrdering := execinfrapb.Ordering{} for i, eqCol := range tc.leftEqCols { leftOrdering.Columns = append( @@ -60,14 +59,14 @@ func createSpecForMergeJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { } projection := make([]uint32, 0, len(tc.leftOutCols)+len(tc.rightOutCols)) projection = append(projection, tc.leftOutCols...) - rColOffset := uint32(len(tc.leftTypes)) + rColOffset := uint32(len(tc.leftPhysTypes)) for _, outCol := range tc.rightOutCols { projection = append(projection, rColOffset+outCol) } return &execinfrapb.ProcessorSpec{ Input: []execinfrapb.InputSyncSpec{ - {ColumnTypes: typeconv.ToColumnTypes(tc.leftTypes)}, - {ColumnTypes: typeconv.ToColumnTypes(tc.rightTypes)}, + {ColumnTypes: tc.leftLogTypes}, + {ColumnTypes: tc.rightLogTypes}, }, Core: execinfrapb.ProcessorCoreUnion{ MergeJoiner: mjSpec, @@ -79,155 +78,155 @@ func createSpecForMergeJoiner(tc joinTestCase) *execinfrapb.ProcessorSpec { } } -var mjTestCases = []joinTestCase{ - { - description: "basic test", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {2}, {3}, {4}}, - }, - { - description: "basic test, no out cols", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{}, {}, {}, {}}, - }, - { - description: "basic test, out col on left", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {2}, {3}, {4}}, - }, - { - description: "basic test, out col on right", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {2}, {3}, {4}}, - }, - { - description: "basic test, L missing", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {3}, {4}}, - }, - { - description: "basic test, R missing", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {3}, {4}}, - }, - { - description: "basic test, L duplicate", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {2}, {3}, {4}}, - }, - { - description: "basic test, R duplicate", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {2}, {3}, {4}}, - }, - { - description: "basic test, R duplicate 2", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}}, - rightTuples: tuples{{1}, {1}, {2}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {2}}, - }, - { - description: "basic test, L+R duplicates", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {1}, {1}, {2}, {3}, {4}}, - }, - { - description: "basic test, L+R duplicate, multiple runs", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {2}, {2}, {3}, {4}}, - rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, - leftOutCols: []uint32{}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {2}, {2}, {2}, {3}, {4}}, - }, - { - description: "cross product test, batch size = col.BatchSize()", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {1}, {1}}, - rightTuples: tuples{{1}, {1}, {1}, {1}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}, +var mjTestCases = []*joinTestCase{ + { + description: "basic test", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {2}, {3}, {4}}, + }, + { + description: "basic test, no out cols", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{}, {}, {}, {}}, + }, + { + description: "basic test, out col on left", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {2}, {3}, {4}}, + }, + { + description: "basic test, out col on right", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {2}, {3}, {4}}, + }, + { + description: "basic test, L missing", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {3}, {4}}, + }, + { + description: "basic test, R missing", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {3}, {4}}, + }, + { + description: "basic test, L duplicate", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {2}, {3}, {4}}, + }, + { + description: "basic test, R duplicate", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {2}, {3}, {4}}, + }, + { + description: "basic test, R duplicate 2", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}}, + rightTuples: tuples{{1}, {1}, {2}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {2}}, + }, + { + description: "basic test, L+R duplicates", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {1}, {1}, {2}, {3}, {4}}, + }, + { + description: "basic test, L+R duplicate, multiple runs", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {2}, {2}, {3}, {4}}, + rightTuples: tuples{{1}, {1}, {2}, {3}, {4}}, + leftOutCols: []uint32{}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {2}, {2}, {2}, {3}, {4}}, + }, + { + description: "cross product test, batch size = col.BatchSize()", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {1}, {1}}, + rightTuples: tuples{{1}, {1}, {1}, {1}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}, }, { description: "cross product test, batch size = 4 (small even)", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{{1}, {1}, {1}, {1}}, rightTuples: tuples{{1}, {1}, {1}, {1}}, leftOutCols: []uint32{0}, @@ -239,8 +238,8 @@ var mjTestCases = []joinTestCase{ }, { description: "cross product test, batch size = 3 (small odd)", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{{1}, {1}, {1}, {1}}, rightTuples: tuples{{1}, {1}, {1}, {1}}, leftOutCols: []uint32{}, @@ -252,8 +251,8 @@ var mjTestCases = []joinTestCase{ }, { description: "cross product test, batch size = 1 (unit)", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftTuples: tuples{{1}, {1}, {1}, {1}}, rightTuples: tuples{{1}, {1}, {1}, {1}}, leftOutCols: []uint32{}, @@ -264,21 +263,21 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "multi output column test, basic", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 10, 1, 11}, {2, 20, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, + description: "multi output column test, basic", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 10, 1, 11}, {2, 20, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, }, { description: "multi output column test, batch size = 1", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, leftOutCols: []uint32{0, 1}, @@ -289,45 +288,45 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "multi output column test, test output coldata projection", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, - }, - { - description: "multi output column test, test output coldata projection", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{1}, - rightOutCols: []uint32{1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{10, 11}, {20, 12}, {30, 13}, {40, 14}}, - }, - { - description: "multi output column test, L run", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {2, 21}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 10, 1, 11}, {2, 20, 2, 12}, {2, 21, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, + description: "multi output column test, test output coldata projection", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 1}, {2, 2}, {3, 3}, {4, 4}}, + }, + { + description: "multi output column test, test output coldata projection", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{1}, + rightOutCols: []uint32{1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{10, 11}, {20, 12}, {30, 13}, {40, 14}}, + }, + { + description: "multi output column test, L run", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {2, 21}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 10, 1, 11}, {2, 20, 2, 12}, {2, 21, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, }, { description: "multi output column test, L run, batch size = 1", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, leftTuples: tuples{{1, 10}, {2, 20}, {2, 21}, {3, 30}, {4, 40}}, rightTuples: tuples{{1, 11}, {2, 12}, {3, 13}, {4, 14}}, leftOutCols: []uint32{0, 1}, @@ -338,21 +337,21 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "multi output column test, R run", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {1, 111}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 10, 1, 11}, {1, 10, 1, 111}, {2, 20, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, + description: "multi output column test, R run", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {1, 111}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 10, 1, 11}, {1, 10, 1, 111}, {2, 20, 2, 12}, {3, 30, 3, 13}, {4, 40, 4, 14}}, }, { description: "multi output column test, R run, batch size = 1", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, rightTuples: tuples{{1, 11}, {1, 111}, {2, 12}, {3, 13}, {4, 14}}, leftOutCols: []uint32{0, 1}, @@ -363,27 +362,27 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "logic test", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{-1, -1}, {0, 4}, {2, 1}, {3, 4}, {5, 4}}, - rightTuples: tuples{{0, 5}, {1, 3}, {3, 2}, {4, 6}}, - leftOutCols: []uint32{1}, - rightOutCols: []uint32{1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{4, 5}, {4, 2}}, - }, - { - description: "multi output column test, batch size = 1 and runs (to test saved output), reordered out columns", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{1, 0}, - rightOutCols: []uint32{1, 0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, + description: "logic test", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{-1, -1}, {0, 4}, {2, 1}, {3, 4}, {5, 4}}, + rightTuples: tuples{{0, 5}, {1, 3}, {3, 2}, {4, 6}}, + leftOutCols: []uint32{1}, + rightOutCols: []uint32{1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{4, 5}, {4, 2}}, + }, + { + description: "multi output column test, batch size = 1 and runs (to test saved output), reordered out columns", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{1, 0}, + rightOutCols: []uint32{1, 0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, expected: tuples{ {10, 1, 11, 1}, {10, 1, 11, 1}, @@ -398,15 +397,15 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "multi output column test, batch size = 1 and runs (to test saved output), reordered out columns that dont start at 0", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{1, 0}, - rightOutCols: []uint32{1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, + description: "multi output column test, batch size = 1 and runs (to test saved output), reordered out columns that dont start at 0", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{1, 0}, + rightOutCols: []uint32{1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, expected: tuples{ {10, 1, 11}, {10, 1, 11}, @@ -421,15 +420,15 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "equality column is correctly indexed", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{10, 1}, {10, 1}, {10, 1}, {20, 2}, {30, 3}, {40, 4}}, - rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{1, 0}, - rightOutCols: []uint32{1}, - leftEqCols: []uint32{1}, - rightEqCols: []uint32{0}, + description: "equality column is correctly indexed", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{10, 1}, {10, 1}, {10, 1}, {20, 2}, {30, 3}, {40, 4}}, + rightTuples: tuples{{1, 11}, {1, 11}, {2, 12}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{1, 0}, + rightOutCols: []uint32{1}, + leftEqCols: []uint32{1}, + rightEqCols: []uint32{0}, expected: tuples{ {1, 10, 11}, {1, 10, 11}, @@ -443,30 +442,30 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "multi column equality basic test", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 10}, {2, 20}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "multi column equality basic test", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 10}, {2, 20}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {1, 10, 1, 10}, {2, 20, 2, 20}, }, }, { - description: "multi column equality runs", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, - rightTuples: tuples{{1, 10}, {1, 10}, {2, 20}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "multi column equality runs", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {1, 10}, {1, 10}, {2, 20}, {3, 30}, {4, 40}}, + rightTuples: tuples{{1, 10}, {1, 10}, {2, 20}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {1, 10, 1, 10}, {1, 10, 1, 10}, @@ -478,30 +477,30 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "multi column non-consecutive equality cols", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 123, 1}, {1, 234, 10}}, - rightTuples: tuples{{1, 1, 345}, {1, 10, 456}}, - leftOutCols: []uint32{0, 2, 1}, - rightOutCols: []uint32{0, 2, 1}, - leftEqCols: []uint32{0, 2}, - rightEqCols: []uint32{0, 1}, + description: "multi column non-consecutive equality cols", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 123, 1}, {1, 234, 10}}, + rightTuples: tuples{{1, 1, 345}, {1, 10, 456}}, + leftOutCols: []uint32{0, 2, 1}, + rightOutCols: []uint32{0, 2, 1}, + leftEqCols: []uint32{0, 2}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {1, 1, 123, 1, 345, 1}, {1, 10, 234, 1, 456, 10}, }, }, { - description: "multi column equality: new batch ends run", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 1}, {1, 1}, {3, 3}, {4, 3}}, - rightTuples: tuples{{1, 1}, {1, 2}, {3, 3}, {3, 3}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "multi column equality: new batch ends run", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 1}, {1, 1}, {3, 3}, {4, 3}}, + rightTuples: tuples{{1, 1}, {1, 2}, {3, 3}, {3, 3}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {1, 1, 1, 1}, {1, 1, 1, 1}, @@ -510,15 +509,15 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "multi column equality: reordered eq columns", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 1}, {1, 1}, {3, 3}, {4, 3}}, - rightTuples: tuples{{1, 1}, {1, 2}, {3, 3}, {3, 3}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{1, 0}, + description: "multi column equality: reordered eq columns", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 1}, {1, 1}, {3, 3}, {4, 3}}, + rightTuples: tuples{{1, 1}, {1, 2}, {3, 3}, {3, 3}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{1, 0}, expected: tuples{ {1, 1, 1, 1}, {1, 1, 1, 1}, @@ -527,15 +526,15 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "cross batch, distinct group", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 2}, {1, 2}, {1, 2}, {2, 2}}, - rightTuples: tuples{{1, 2}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "cross batch, distinct group", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 2}, {1, 2}, {1, 2}, {2, 2}}, + rightTuples: tuples{{1, 2}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {1, 2, 1, 2}, {1, 2, 1, 2}, @@ -543,29 +542,29 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "templating basic test", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - leftTuples: tuples{{true, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{true, int16(10), 1.2}, {false, int16(20), 2.2}, {true, int16(30), 3.9}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{0, 1, 2}, - rightEqCols: []uint32{0, 1, 2}, + description: "templating basic test", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + leftTuples: tuples{{true, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{true, int16(10), 1.2}, {false, int16(20), 2.2}, {true, int16(30), 3.9}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{0, 1, 2}, + rightEqCols: []uint32{0, 1, 2}, expected: tuples{ {true, 10, 1.2, true, 10, 1.2}, }, }, { - description: "templating cross product test", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "templating cross product test", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {false, 10, 1.2, false, 10, 1.2}, {true, 20, 2.2, true, 20, 2.3}, @@ -573,15 +572,15 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "templating cross product test, output batch size 1", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "templating cross product test, output batch size 1", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {false, 10, 1.2, false, 10, 1.2}, {true, 20, 2.2, true, 20, 2.3}, @@ -590,15 +589,15 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 1, }, { - description: "templating cross product test, output batch size 2", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, + description: "templating cross product test, output batch size 2", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, expected: tuples{ {false, 10, 1.2, false, 10, 1.2}, {true, 20, 2.2, true, 20, 2.3}, @@ -607,15 +606,15 @@ var mjTestCases = []joinTestCase{ outputBatchSize: 2, }, { - description: "templating reordered eq columns", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{1, 0}, - rightEqCols: []uint32{1, 0}, + description: "templating reordered eq columns", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.3}, {true, int16(20), 2.4}, {true, int16(31), 3.9}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{1, 0}, + rightEqCols: []uint32{1, 0}, expected: tuples{ {false, 10, 1.2, false, 10, 1.2}, {true, 20, 2.2, true, 20, 2.3}, @@ -623,15 +622,15 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "templating reordered eq columns non symmetrical", - leftTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, - rightTypes: []coltypes.T{coltypes.Int16, coltypes.Float64, coltypes.Bool}, - leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, - rightTuples: tuples{{int16(10), 1.2, false}, {int16(20), 2.2, true}, {int16(21), 2.2, true}, {int16(30), 3.2, false}}, - leftOutCols: []uint32{0, 1, 2}, - rightOutCols: []uint32{0, 1, 2}, - leftEqCols: []uint32{2, 0}, - rightEqCols: []uint32{1, 2}, + description: "templating reordered eq columns non symmetrical", + leftPhysTypes: []coltypes.T{coltypes.Bool, coltypes.Int16, coltypes.Float64}, + rightPhysTypes: []coltypes.T{coltypes.Int16, coltypes.Float64, coltypes.Bool}, + leftTuples: tuples{{false, int16(10), 1.2}, {true, int16(20), 2.2}, {true, int16(30), 3.2}}, + rightTuples: tuples{{int16(10), 1.2, false}, {int16(20), 2.2, true}, {int16(21), 2.2, true}, {int16(30), 3.2, false}}, + leftOutCols: []uint32{0, 1, 2}, + rightOutCols: []uint32{0, 1, 2}, + leftEqCols: []uint32{2, 0}, + rightEqCols: []uint32{1, 2}, expected: tuples{ {false, 10, 1.2, 10, 1.2, false}, {true, 20, 2.2, 20, 2.2, true}, @@ -639,200 +638,200 @@ var mjTestCases = []joinTestCase{ }, }, { - description: "null handling", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{nil}, {0}}, - rightTuples: tuples{{nil}, {0}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, + description: "null handling", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{nil}, {0}}, + rightTuples: tuples{{nil}, {0}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, expected: tuples{ {0, 0}, }, }, { - description: "null handling multi column, nulls on left", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, 0}, {0, nil}}, - rightTuples: tuples{{nil, nil}, {0, 1}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, + description: "null handling multi column, nulls on left", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, 0}, {0, nil}}, + rightTuples: tuples{{nil, nil}, {0, 1}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, expected: tuples{ {0, nil, 0, 1}, }, }, { - description: "null handling multi column, nulls on right", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, 0}, {0, 1}}, - rightTuples: tuples{{nil, nil}, {0, nil}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, + description: "null handling multi column, nulls on right", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, 0}, {0, 1}}, + rightTuples: tuples{{nil, nil}, {0, nil}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, expected: tuples{ {0, 1, 0, nil}, }, }, { - description: "desc test", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{4}, {3}, {2}, {1}}, - rightTuples: tuples{{4}, {2}, {1}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{4, 4}, {2, 2}, {1, 1}}, + description: "desc test", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{4}, {3}, {2}, {1}}, + rightTuples: tuples{{4}, {2}, {1}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{4, 4}, {2, 2}, {1, 1}}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, }, { - description: "desc nulls test", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{4}, {3}, {nil}, {1}}, - rightTuples: tuples{{4}, {nil}, {2}, {1}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{4, 4}, {1, 1}}, + description: "desc nulls test", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{4}, {3}, {nil}, {1}}, + rightTuples: tuples{{4}, {nil}, {2}, {1}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{4, 4}, {1, 1}}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, }, { - description: "desc nulls test end on 0", - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{9}, {9}, {8}, {0}, {nil}}, - rightTuples: tuples{{9}, {9}, {8}, {0}, {nil}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{9, 9}, {9, 9}, {9, 9}, {9, 9}, {8, 8}, {0, 0}}, + description: "desc nulls test end on 0", + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{9}, {9}, {8}, {0}, {nil}}, + rightTuples: tuples{{9}, {9}, {8}, {0}, {nil}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{9, 9}, {9, 9}, {9, 9}, {9, 9}, {8, 8}, {0, 0}}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, }, { - description: "non-equality columns with nulls", - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, nil}, {2, 2}, {2, 2}, {3, nil}, {4, nil}}, - rightTuples: tuples{{1, 1}, {2, nil}, {2, nil}, {3, nil}, {4, 4}, {4, 4}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil, 1, 1}, {2, 2, 2, nil}, {2, 2, 2, nil}, {2, 2, 2, nil}, {2, 2, 2, nil}, {3, nil, 3, nil}, {4, nil, 4, 4}, {4, nil, 4, 4}}, - }, - { - description: "basic LEFT OUTER JOIN test, L and R exhausted at the same time", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, - rightTuples: tuples{{0}, {2}, {3}, {4}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, - }, - { - description: "basic LEFT OUTER JOIN test, R exhausted first", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil}, {1, nil}, {3, 3}, {5, nil}, {6, nil}, {7, nil}}, - }, - { - description: "basic LEFT OUTER JOIN test, L exhausted first", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{3, 3}, {5, nil}, {6, 6}, {7, nil}}, - }, - { - description: "multi output column LEFT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 10, 1, nil}, {2, 20, nil, nil}, {3, nil, 3, 13}, {4, 40, 4, 14}}, - }, - { - description: "null in equality column LEFT OUTER JOIN", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil}, {nil}, {1}, {3}}, - rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {3, 3, 3}}, - }, - { - description: "multi equality column LEFT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, - rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{nil, nil, nil, nil}, {nil, 10, nil, nil}, {1, nil, nil, nil}, {1, 10, nil, nil}, {2, 20, 2, 20}, {4, 40, nil, nil}}, - }, - { - description: "multi equality column (long runs on left) LEFT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, - rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{1, 9, nil, nil}, {1, 10, nil, nil}, {1, 10, nil, nil}, {1, 11, 1, 11}, {1, 11, 1, 11}, {2, 20, nil, nil}, {2, 20, nil, nil}, {2, 21, 2, 21}, {2, 22, nil, nil}, {2, 22, nil, nil}}, + description: "non-equality columns with nulls", + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, nil}, {2, 2}, {2, 2}, {3, nil}, {4, nil}}, + rightTuples: tuples{{1, 1}, {2, nil}, {2, nil}, {3, nil}, {4, 4}, {4, 4}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil, 1, 1}, {2, 2, 2, nil}, {2, 2, 2, nil}, {2, 2, 2, nil}, {2, 2, 2, nil}, {3, nil, 3, nil}, {4, nil, 4, 4}, {4, nil, 4, 4}}, + }, + { + description: "basic LEFT OUTER JOIN test, L and R exhausted at the same time", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, + rightTuples: tuples{{0}, {2}, {3}, {4}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, + }, + { + description: "basic LEFT OUTER JOIN test, R exhausted first", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil}, {1, nil}, {3, 3}, {5, nil}, {6, nil}, {7, nil}}, + }, + { + description: "basic LEFT OUTER JOIN test, L exhausted first", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{3, 3}, {5, nil}, {6, 6}, {7, nil}}, + }, + { + description: "multi output column LEFT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 10, 1, nil}, {2, 20, nil, nil}, {3, nil, 3, 13}, {4, 40, 4, 14}}, + }, + { + description: "null in equality column LEFT OUTER JOIN", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil}, {nil}, {1}, {3}}, + rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {3, 3, 3}}, + }, + { + description: "multi equality column LEFT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, + rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{nil, nil, nil, nil}, {nil, 10, nil, nil}, {1, nil, nil, nil}, {1, 10, nil, nil}, {2, 20, 2, 20}, {4, 40, nil, nil}}, + }, + { + description: "multi equality column (long runs on left) LEFT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, + rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{1, 9, nil, nil}, {1, 10, nil, nil}, {1, 10, nil, nil}, {1, 11, 1, 11}, {1, 11, 1, 11}, {2, 20, nil, nil}, {2, 20, nil, nil}, {2, 21, 2, 21}, {2, 22, nil, nil}, {2, 22, nil, nil}}, }, { description: "3 equality column LEFT OUTER JOIN test with nulls DESC ordering", joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -846,8 +845,8 @@ var mjTestCases = []joinTestCase{ { description: "3 equality column LEFT OUTER JOIN test with nulls mixed ordering", joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_ASC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_ASC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -861,8 +860,8 @@ var mjTestCases = []joinTestCase{ { description: "single column DESC with nulls on the left LEFT OUTER JOIN", joinType: sqlbase.JoinType_LEFT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{1}, {1}, {1}, {nil}, {nil}, {nil}}, @@ -874,101 +873,101 @@ var mjTestCases = []joinTestCase{ expected: tuples{{1, 1}, {1, 1}, {1, 1}, {nil, nil}, {nil, nil}, {nil, nil}}, }, { - description: "basic RIGHT OUTER JOIN test, L and R exhausted at the same time", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, - }, - { - description: "basic RIGHT OUTER JOIN test, R exhausted first", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, 2}, {3, 3}, {nil, 4}}, - }, - { - description: "basic RIGHT OUTER JOIN test, L exhausted first", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, 2}, {3, 3}, {nil, 4}, {6, 6}, {nil, 8}, {nil, 9}}, - }, - { - description: "multi output column RIGHT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - rightTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil, 1, 10}, {nil, nil, 2, 20}, {3, 13, 3, nil}, {4, 14, 4, 40}}, - }, - { - description: "null in equality column RIGHT OUTER JOIN", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, - rightTuples: tuples{{nil}, {nil}, {1}, {3}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {3, 3, 3}}, - }, - { - description: "multi equality column RIGHT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, - rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{nil, nil, nil, nil}, {nil, nil, nil, 10}, {nil, nil, 1, nil}, {nil, nil, 1, 10}, {2, 20, 2, 20}, {nil, nil, 4, 40}}, - }, - { - description: "multi equality column (long runs on right) RIGHT OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, - rightTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{nil, nil, 1, 9}, {nil, nil, 1, 10}, {nil, nil, 1, 10}, {1, 11, 1, 11}, {1, 11, 1, 11}, {nil, nil, 2, 20}, {nil, nil, 2, 20}, {2, 21, 2, 21}, {nil, nil, 2, 22}, {nil, nil, 2, 22}}, + description: "basic RIGHT OUTER JOIN test, L and R exhausted at the same time", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, + }, + { + description: "basic RIGHT OUTER JOIN test, R exhausted first", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, 2}, {3, 3}, {nil, 4}}, + }, + { + description: "basic RIGHT OUTER JOIN test, L exhausted first", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, 2}, {3, 3}, {nil, 4}, {6, 6}, {nil, 8}, {nil, 9}}, + }, + { + description: "multi output column RIGHT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + rightTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil, 1, 10}, {nil, nil, 2, 20}, {3, 13, 3, nil}, {4, 14, 4, 40}}, + }, + { + description: "null in equality column RIGHT OUTER JOIN", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, + rightTuples: tuples{{nil}, {nil}, {1}, {3}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {3, 3, 3}}, + }, + { + description: "multi equality column RIGHT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, + rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{nil, nil, nil, nil}, {nil, nil, nil, 10}, {nil, nil, 1, nil}, {nil, nil, 1, 10}, {2, 20, 2, 20}, {nil, nil, 4, 40}}, + }, + { + description: "multi equality column (long runs on right) RIGHT OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_RIGHT_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, + rightTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{nil, nil, 1, 9}, {nil, nil, 1, 10}, {nil, nil, 1, 10}, {1, 11, 1, 11}, {1, 11, 1, 11}, {nil, nil, 2, 20}, {nil, nil, 2, 20}, {2, 21, 2, 21}, {nil, nil, 2, 22}, {nil, nil, 2, 22}}, }, { description: "3 equality column RIGHT OUTER JOIN test with nulls DESC ordering", joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{4, 3, 3}, {nil, 2, nil}, {nil, 1, 3}}, @@ -982,8 +981,8 @@ var mjTestCases = []joinTestCase{ { description: "3 equality column RIGHT OUTER JOIN test with nulls mixed ordering", joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_ASC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_ASC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{4, 3, 3}, {nil, 2, nil}, {nil, 1, 3}}, @@ -997,8 +996,8 @@ var mjTestCases = []joinTestCase{ { description: "single column DESC with nulls on the right RIGHT OUTER JOIN", joinType: sqlbase.JoinType_RIGHT_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{1}}, @@ -1010,101 +1009,101 @@ var mjTestCases = []joinTestCase{ expected: tuples{{1, 1}, {1, 1}, {1, 1}, {nil, nil}, {nil, nil}, {nil, nil}}, }, { - description: "basic FULL OUTER JOIN test, L and R exhausted at the same time", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, - rightTuples: tuples{{1}, {2}, {3}, {4}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{-1, nil}, {nil, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, - }, - { - description: "basic FULL OUTER JOIN test, R exhausted first", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil}, {1, nil}, {nil, 2}, {3, 3}, {nil, 4}, {5, nil}, {6, nil}, {7, nil}}, - }, - { - description: "basic FULL OUTER JOIN test, L exhausted first", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, 2}, {3, 3}, {nil, 4}, {5, nil}, {6, 6}, {7, nil}, {nil, 8}, {nil, 9}}, - }, - { - description: "multi output column FULL OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - rightTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, nil, 1, 10}, {nil, nil, 2, 20}, {3, 13, 3, nil}, {4, 14, 4, 40}}, - }, - { - description: "null in equality column FULL OUTER JOIN", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, - rightTuples: tuples{{nil}, {nil}, {1}, {3}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, 1, nil}, {nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {2, 2, nil}, {3, 3, 3}}, - }, - { - description: "multi equality column FULL OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, - rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{nil, nil, nil, nil}, {nil, nil, nil, nil}, {nil, 10, nil, nil}, {nil, nil, nil, 10}, {1, nil, nil, nil}, {1, nil, nil, nil}, {nil, nil, 1, nil}, {nil, nil, 1, 10}, {2, 20, 2, 20}, {3, 30, nil, nil}, {nil, nil, 4, 40}}, - }, - { - description: "multi equality column (long runs on right) FULL OUTER JOIN test with nulls", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, - rightTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{0, 1}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{1, 8, nil, nil}, {nil, nil, 1, 9}, {nil, nil, 1, 10}, {nil, nil, 1, 10}, {1, 11, 1, 11}, {1, 11, 1, 11}, {nil, nil, 2, 20}, {nil, nil, 2, 20}, {2, 21, 2, 21}, {nil, nil, 2, 22}, {nil, nil, 2, 22}, {2, 23, nil, nil}}, + description: "basic FULL OUTER JOIN test, L and R exhausted at the same time", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, + rightTuples: tuples{{1}, {2}, {3}, {4}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{-1, nil}, {nil, 1}, {2, 2}, {3, 3}, {4, 4}, {4, 4}, {4, 4}, {4, 4}}, + }, + { + description: "basic FULL OUTER JOIN test, R exhausted first", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil}, {1, nil}, {nil, 2}, {3, 3}, {nil, 4}, {5, nil}, {6, nil}, {7, nil}}, + }, + { + description: "basic FULL OUTER JOIN test, L exhausted first", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}, {6}, {8}, {9}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, 2}, {3, 3}, {nil, 4}, {5, nil}, {6, 6}, {7, nil}, {nil, 8}, {nil, 9}}, + }, + { + description: "multi output column FULL OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + rightTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, nil, 1, 10}, {nil, nil, 2, 20}, {3, 13, 3, nil}, {4, 14, 4, 40}}, + }, + { + description: "null in equality column FULL OUTER JOIN", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, + rightTuples: tuples{{nil}, {nil}, {1}, {3}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, 1, nil}, {nil, nil, nil}, {nil, nil, nil}, {1, 1, 1}, {2, 2, nil}, {3, 3, 3}}, + }, + { + description: "multi equality column FULL OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, + rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{nil, nil, nil, nil}, {nil, nil, nil, nil}, {nil, 10, nil, nil}, {nil, nil, nil, 10}, {1, nil, nil, nil}, {1, nil, nil, nil}, {nil, nil, 1, nil}, {nil, nil, 1, 10}, {2, 20, 2, 20}, {3, 30, nil, nil}, {nil, nil, 4, 40}}, + }, + { + description: "multi equality column (long runs on right) FULL OUTER JOIN test with nulls", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, + rightTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{0, 1}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{1, 8, nil, nil}, {nil, nil, 1, 9}, {nil, nil, 1, 10}, {nil, nil, 1, 10}, {1, 11, 1, 11}, {1, 11, 1, 11}, {nil, nil, 2, 20}, {nil, nil, 2, 20}, {2, 21, 2, 21}, {nil, nil, 2, 22}, {nil, nil, 2, 22}, {2, 23, nil, nil}}, }, { description: "3 equality column FULL OUTER JOIN test with nulls DESC ordering", joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{4, 3, 3}, {nil, 2, nil}, {nil, 1, 3}}, @@ -1118,8 +1117,8 @@ var mjTestCases = []joinTestCase{ { description: "3 equality column FULL OUTER JOIN test with nulls mixed ordering", joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_ASC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_ASC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{4, 3, 3}, {nil, 2, nil}, {nil, 1, 3}}, @@ -1133,8 +1132,8 @@ var mjTestCases = []joinTestCase{ { description: "single column DESC with nulls on the right FULL OUTER JOIN", joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{1}}, @@ -1146,114 +1145,114 @@ var mjTestCases = []joinTestCase{ expected: tuples{{1, 1}, {1, 1}, {1, 1}, {nil, nil}, {nil, nil}, {nil, nil}}, }, { - description: "FULL OUTER JOIN test with nulls and Bytes", - joinType: sqlbase.JoinType_FULL_OUTER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Bytes}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Bytes}, - leftTuples: tuples{{nil, "0"}, {1, "10"}, {2, "20"}, {3, nil}, {4, "40"}}, - rightTuples: tuples{{1, nil}, {3, "13"}, {4, nil}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{1}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil, "0", nil}, {1, "10", nil}, {2, "20", nil}, {3, nil, "13"}, {4, "40", nil}}, - }, - { - description: "basic LEFT SEMI JOIN test, L and R exhausted at the same time", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, - rightTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{2}, {3}, {4}, {4}}, - }, - { - description: "basic LEFT SEMI JOIN test, R exhausted first", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{3}}, - }, - { - description: "basic LEFT SEMI JOIN test, L exhausted first", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {3}, {3}, {4}, {6}, {8}, {9}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{3}, {6}}, - }, - { - description: "multi output column LEFT SEMI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1, 10}, {3, nil}, {4, 40}}, - }, - { - description: "null in equality column LEFT SEMI JOIN", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil}, {nil}, {1}, {3}}, - rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {3}}, - }, - { - description: "multi equality column LEFT SEMI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, - rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{2, 20}}, - }, - { - description: "multi equality column (long runs on left) LEFT SEMI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {1, 11}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, - rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{1, 11}, {1, 11}, {1, 11}, {2, 21}}, + description: "FULL OUTER JOIN test with nulls and Bytes", + joinType: sqlbase.JoinType_FULL_OUTER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Bytes}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Bytes}, + leftTuples: tuples{{nil, "0"}, {1, "10"}, {2, "20"}, {3, nil}, {4, "40"}}, + rightTuples: tuples{{1, nil}, {3, "13"}, {4, nil}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{1}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil, "0", nil}, {1, "10", nil}, {2, "20", nil}, {3, nil, "13"}, {4, "40", nil}}, + }, + { + description: "basic LEFT SEMI JOIN test, L and R exhausted at the same time", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, + rightTuples: tuples{{-1}, {2}, {3}, {4}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{2}, {3}, {4}, {4}}, + }, + { + description: "basic LEFT SEMI JOIN test, R exhausted first", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{3}}, + }, + { + description: "basic LEFT SEMI JOIN test, L exhausted first", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {3}, {3}, {4}, {6}, {8}, {9}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{3}, {6}}, + }, + { + description: "multi output column LEFT SEMI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1, 10}, {3, nil}, {4, 40}}, + }, + { + description: "null in equality column LEFT SEMI JOIN", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil}, {nil}, {1}, {3}}, + rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {3}}, + }, + { + description: "multi equality column LEFT SEMI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, + rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{2, 20}}, + }, + { + description: "multi equality column (long runs on left) LEFT SEMI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_SEMI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {1, 11}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, + rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{1, 11}, {1, 11}, {1, 11}, {2, 21}}, }, { description: "3 equality column LEFT SEMI JOIN test with nulls DESC ordering", joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -1270,8 +1269,8 @@ var mjTestCases = []joinTestCase{ { description: "3 equality column LEFT SEMI JOIN test with nulls mixed ordering", joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_ASC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_ASC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -1288,8 +1287,8 @@ var mjTestCases = []joinTestCase{ { description: "single column DESC with nulls on the left LEFT SEMI JOIN", joinType: sqlbase.JoinType_LEFT_SEMI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{1}, {1}, {1}, {nil}, {nil}, {nil}}, @@ -1301,101 +1300,101 @@ var mjTestCases = []joinTestCase{ expected: tuples{{1}, {1}, {1}}, }, { - description: "basic LEFT ANTI JOIN test, L and R exhausted at the same time", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, - rightTuples: tuples{{-1}, {2}, {4}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {3}}, - }, - { - description: "basic LEFT ANTI JOIN test, R exhausted first", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {4}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{1}, {1}, {5}, {6}, {7}}, - }, - { - description: "basic LEFT ANTI JOIN test, L exhausted first", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, - leftTuples: tuples{{3}, {5}, {6}, {7}}, - rightTuples: tuples{{2}, {3}, {3}, {3}, {4}, {6}, {8}, {9}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{5}, {7}}, - }, - { - description: "multi output column LEFT ANTI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{2, 20}}, - }, - { - description: "null in equality column LEFT ANTI JOIN", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil}, {nil}, {1}, {3}}, - rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, - leftOutCols: []uint32{0}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - expected: tuples{{nil}, {nil}}, - }, - { - description: "multi equality column LEFT ANTI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, - rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {4, 40}}, - }, - { - description: "multi equality column (long runs on left) LEFT ANTI JOIN test with nulls", - joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {1, 11}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, - rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0, 1}, - rightEqCols: []uint32{0, 1}, - expected: tuples{{1, 9}, {1, 10}, {1, 10}, {2, 20}, {2, 20}, {2, 22}, {2, 22}}, + description: "basic LEFT ANTI JOIN test, L and R exhausted at the same time", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {2}, {3}, {4}, {4}}, + rightTuples: tuples{{-1}, {2}, {4}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {3}}, + }, + { + description: "basic LEFT ANTI JOIN test, R exhausted first", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{1}, {1}, {3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {4}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{1}, {1}, {5}, {6}, {7}}, + }, + { + description: "basic LEFT ANTI JOIN test, L exhausted first", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, + leftTuples: tuples{{3}, {5}, {6}, {7}}, + rightTuples: tuples{{2}, {3}, {3}, {3}, {4}, {6}, {8}, {9}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{5}, {7}}, + }, + { + description: "multi output column LEFT ANTI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{2, 20}}, + }, + { + description: "null in equality column LEFT ANTI JOIN", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil}, {nil}, {1}, {3}}, + rightTuples: tuples{{nil, 1}, {1, 1}, {2, 2}, {3, 3}}, + leftOutCols: []uint32{0}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + expected: tuples{{nil}, {nil}}, + }, + { + description: "multi equality column LEFT ANTI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {2, 20}, {4, 40}}, + rightTuples: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, nil}, {2, 20}, {3, 30}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{nil, nil}, {nil, 10}, {1, nil}, {1, 10}, {4, 40}}, + }, + { + description: "multi equality column (long runs on left) LEFT ANTI JOIN test with nulls", + joinType: sqlbase.JoinType_LEFT_ANTI, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{1, 9}, {1, 10}, {1, 10}, {1, 11}, {1, 11}, {1, 11}, {2, 20}, {2, 20}, {2, 21}, {2, 22}, {2, 22}}, + rightTuples: tuples{{1, 8}, {1, 11}, {1, 11}, {2, 21}, {2, 23}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0, 1}, + rightEqCols: []uint32{0, 1}, + expected: tuples{{1, 9}, {1, 10}, {1, 10}, {2, 20}, {2, 20}, {2, 22}, {2, 22}}, }, { description: "3 equality column LEFT ANTI JOIN test with nulls DESC ordering", joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -1409,8 +1408,8 @@ var mjTestCases = []joinTestCase{ { description: "3 equality column LEFT ANTI JOIN test with nulls mixed ordering", joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64, coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_ASC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_ASC, execinfrapb.Ordering_Column_DESC, execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{2, 3, 1}, {2, nil, 1}, {nil, 1, 3}}, @@ -1424,8 +1423,8 @@ var mjTestCases = []joinTestCase{ { description: "single column DESC with nulls on the left LEFT ANTI JOIN", joinType: sqlbase.JoinType_LEFT_ANTI, - leftTypes: []coltypes.T{coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64}, + leftPhysTypes: []coltypes.T{coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64}, leftDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, rightDirections: []execinfrapb.Ordering_Column_Direction{execinfrapb.Ordering_Column_DESC}, leftTuples: tuples{{1}, {1}, {1}, {nil}, {nil}, {nil}}, @@ -1437,46 +1436,46 @@ var mjTestCases = []joinTestCase{ expected: tuples{{nil}, {nil}, {nil}}, }, { - description: "INNER JOIN test with ON expression (filter only on left)", - joinType: sqlbase.JoinType_INNER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - onExpr: execinfrapb.Expression{Expr: "@1 < 4"}, - expected: tuples{{1, 10}, {3, nil}}, - }, - { - description: "INNER JOIN test with ON expression (filter only on right)", - joinType: sqlbase.JoinType_INNER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - onExpr: execinfrapb.Expression{Expr: "@4 < 14"}, - expected: tuples{{3, nil}}, - }, - { - description: "INNER JOIN test with ON expression (filter on both)", - joinType: sqlbase.JoinType_INNER, - leftTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - rightTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, - leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, - rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, - leftOutCols: []uint32{0, 1}, - rightOutCols: []uint32{}, - leftEqCols: []uint32{0}, - rightEqCols: []uint32{0}, - onExpr: execinfrapb.Expression{Expr: "@2 + @3 < 50"}, - expected: tuples{{1, 10}, {4, 40}}, + description: "INNER JOIN test with ON expression (filter only on left)", + joinType: sqlbase.JoinType_INNER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + onExpr: execinfrapb.Expression{Expr: "@1 < 4"}, + expected: tuples{{1, 10}, {3, nil}}, + }, + { + description: "INNER JOIN test with ON expression (filter only on right)", + joinType: sqlbase.JoinType_INNER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + onExpr: execinfrapb.Expression{Expr: "@4 < 14"}, + expected: tuples{{3, nil}}, + }, + { + description: "INNER JOIN test with ON expression (filter on both)", + joinType: sqlbase.JoinType_INNER, + leftPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + rightPhysTypes: []coltypes.T{coltypes.Int64, coltypes.Int64}, + leftTuples: tuples{{nil, 0}, {1, 10}, {2, 20}, {3, nil}, {4, 40}}, + rightTuples: tuples{{1, nil}, {3, 13}, {4, 14}}, + leftOutCols: []uint32{0, 1}, + rightOutCols: []uint32{}, + leftEqCols: []uint32{0}, + rightEqCols: []uint32{0}, + onExpr: execinfrapb.Expression{Expr: "@2 + @3 < 50"}, + expected: tuples{{1, 10}, {4, 40}}, }, } @@ -1537,7 +1536,7 @@ func TestMergeJoiner(t *testing.T) { for _, memoryLimit := range []int64{1, defaultMemoryLimit} { t.Run(fmt.Sprintf("MemoryLimit=%s/%s", humanizeutil.IBytes(memoryLimit), tc.description), func(t *testing.T) { runner(t, []tuples{tc.leftTuples, tc.rightTuples}, - [][]coltypes.T{tc.leftTypes, tc.rightTypes}, + [][]coltypes.T{tc.leftPhysTypes, tc.rightPhysTypes}, tc.expected, mergeJoinVerifier, func(input []Operator) (Operator, error) { spec := createSpecForMergeJoiner(tc) diff --git a/pkg/sql/colexec/typeconv/typeconv.go b/pkg/sql/colexec/typeconv/typeconv.go index 1af1ed16ffdc..d2568f7a65e1 100644 --- a/pkg/sql/colexec/typeconv/typeconv.go +++ b/pkg/sql/colexec/typeconv/typeconv.go @@ -70,46 +70,6 @@ func FromColumnTypes(cts []types.T) ([]coltypes.T, error) { return typs, nil } -// ToColumnType converts a types.T that corresponds to the column type. Note -// that due to the fact that multiple types.T's are represented by a single -// column type, this conversion might return the type that is unexpected. -// NOTE: this should only be used in tests. -func ToColumnType(t coltypes.T) *types.T { - switch t { - case coltypes.Bool: - return types.Bool - case coltypes.Bytes: - return types.Bytes - case coltypes.Decimal: - return types.Decimal - case coltypes.Int16: - return types.Int2 - case coltypes.Int32: - return types.Int4 - case coltypes.Int64: - return types.Int - case coltypes.Float64: - return types.Float - case coltypes.Timestamp: - return types.Timestamp - case coltypes.Interval: - return types.Interval - } - execerror.VectorizedInternalPanic(fmt.Sprintf("unexpected coltype %s", t.String())) - return nil -} - -// ToColumnTypes calls ToColumnType on each element of typs returning the -// resulting slice. -func ToColumnTypes(typs []coltypes.T) []types.T { - cts := make([]types.T, len(typs)) - for i := range cts { - t := ToColumnType(typs[i]) - cts[i] = *t - } - return cts -} - // GetDatumToPhysicalFn returns a function for converting a datum of the given // ColumnType to the corresponding Go type. func GetDatumToPhysicalFn(ct *types.T) func(tree.Datum) (interface{}, error) { diff --git a/pkg/sql/colexec/utils_test.go b/pkg/sql/colexec/utils_test.go index 5a1e55f1926f..1672104a3c99 100644 --- a/pkg/sql/colexec/utils_test.go +++ b/pkg/sql/colexec/utils_test.go @@ -25,6 +25,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/col/coldata" "github.com/cockroachdb/cockroach/pkg/col/coltypes" "github.com/cockroachdb/cockroach/pkg/sql/colexec/execerror" + "github.com/cockroachdb/cockroach/pkg/sql/colexec/typeconv" "github.com/cockroachdb/cockroach/pkg/sql/execinfra" "github.com/cockroachdb/cockroach/pkg/sql/execinfrapb" "github.com/cockroachdb/cockroach/pkg/sql/parser" @@ -1348,16 +1349,22 @@ func (c *chunkingBatchSource) reset() { // joinTestCase is a helper struct shared by the hash and merge join unit // tests. Not all fields have to be filled in, but init() method *must* be // called. +// NOTE: either logical or physical types *must* be filled in for both inputs. +// Note, however, that if physical types are provided, we will be using lossful +// type conversion during init(). If you want to use specific logical types, +// you should set logical types then. type joinTestCase struct { description string joinType sqlbase.JoinType leftTuples tuples - leftTypes []coltypes.T + leftLogTypes []types.T + leftPhysTypes []coltypes.T leftOutCols []uint32 leftEqCols []uint32 leftDirections []execinfrapb.Ordering_Column_Direction rightTuples tuples - rightTypes []coltypes.T + rightLogTypes []types.T + rightPhysTypes []coltypes.T rightOutCols []uint32 rightEqCols []uint32 rightDirections []execinfrapb.Ordering_Column_Direction @@ -1375,24 +1382,76 @@ func (tc *joinTestCase) init() { } if len(tc.leftDirections) == 0 { - tc.leftDirections = make([]execinfrapb.Ordering_Column_Direction, len(tc.leftTypes)) + tc.leftDirections = make([]execinfrapb.Ordering_Column_Direction, len(tc.leftPhysTypes)) for i := range tc.leftDirections { tc.leftDirections[i] = execinfrapb.Ordering_Column_ASC } } if len(tc.rightDirections) == 0 { - tc.rightDirections = make([]execinfrapb.Ordering_Column_Direction, len(tc.rightTypes)) + tc.rightDirections = make([]execinfrapb.Ordering_Column_Direction, len(tc.rightPhysTypes)) for i := range tc.rightDirections { tc.rightDirections[i] = execinfrapb.Ordering_Column_ASC } } + + toLogType := func(t coltypes.T) *types.T { + switch t { + case coltypes.Bool: + return types.Bool + case coltypes.Bytes: + return types.Bytes + case coltypes.Decimal: + return types.Decimal + case coltypes.Int16: + return types.Int2 + case coltypes.Int32: + return types.Int4 + case coltypes.Int64: + return types.Int + case coltypes.Float64: + return types.Float + case coltypes.Timestamp: + return types.Timestamp + case coltypes.Interval: + return types.Interval + } + execerror.VectorizedInternalPanic(fmt.Sprintf("unexpected coltype %s", t.String())) + return nil + } + toLogTypes := func(typs []coltypes.T) []types.T { + cts := make([]types.T, len(typs)) + for i := range cts { + t := toLogType(typs[i]) + cts[i] = *t + } + return cts + } + var err error + if tc.leftPhysTypes == nil { + tc.leftPhysTypes, err = typeconv.FromColumnTypes(tc.leftLogTypes) + if err != nil { + execerror.VectorizedInternalPanic(err) + } + } + if tc.leftLogTypes == nil { + tc.leftLogTypes = toLogTypes(tc.leftPhysTypes) + } + if tc.rightPhysTypes == nil { + tc.rightPhysTypes, err = typeconv.FromColumnTypes(tc.rightLogTypes) + if err != nil { + execerror.VectorizedInternalPanic(err) + } + } + if tc.rightLogTypes == nil { + tc.rightLogTypes = toLogTypes(tc.rightPhysTypes) + } } // mutateTypes returns a slice of joinTestCases with varied types. Assumes // the input is made up of just int64s. Calling this -func (tc *joinTestCase) mutateTypes() []joinTestCase { - ret := []joinTestCase{*tc} +func (tc *joinTestCase) mutateTypes() []*joinTestCase { + ret := []*joinTestCase{tc} for _, typ := range []coltypes.T{coltypes.Decimal, coltypes.Bytes} { if typ == coltypes.Bytes { @@ -1403,11 +1462,13 @@ func (tc *joinTestCase) mutateTypes() []joinTestCase { } } newTc := *tc - newTc.leftTypes = make([]coltypes.T, len(tc.leftTypes)) - newTc.rightTypes = make([]coltypes.T, len(tc.rightTypes)) - copy(newTc.leftTypes, tc.leftTypes) - copy(newTc.rightTypes, tc.rightTypes) - for _, typs := range [][]coltypes.T{newTc.leftTypes, newTc.rightTypes} { + newTc.leftPhysTypes = make([]coltypes.T, len(tc.leftPhysTypes)) + newTc.rightPhysTypes = make([]coltypes.T, len(tc.rightPhysTypes)) + newTc.leftLogTypes = nil + newTc.rightLogTypes = nil + copy(newTc.leftPhysTypes, tc.leftPhysTypes) + copy(newTc.rightPhysTypes, tc.rightPhysTypes) + for _, typs := range [][]coltypes.T{newTc.leftPhysTypes, newTc.rightPhysTypes} { for i := range typs { if typs[i] != coltypes.Int64 { // We currently can only mutate test cases that are made up of int64 @@ -1438,7 +1499,7 @@ func (tc *joinTestCase) mutateTypes() []joinTestCase { } } } - ret = append(ret, newTc) + ret = append(ret, &newTc) } return ret } diff --git a/pkg/util/hlc/hlc_clock_device_linux.go b/pkg/util/hlc/hlc_clock_device_linux.go new file mode 100644 index 000000000000..50c0cd639861 --- /dev/null +++ b/pkg/util/hlc/hlc_clock_device_linux.go @@ -0,0 +1,79 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +// +build linux + +package hlc + +/* +#include +*/ +import "C" + +import ( + "context" + "os" + + "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/cockroachdb/errors" +) + +// ClockSource contains the handle of the clock device as well as the +// clock id. +type ClockSource struct { + // clockDevice is not used after the device is open but is here to prevent the GC + // from closing the device and invalidating the clockDeviceID. + clockDevice *os.File + clockDeviceID uintptr +} + +// MakeClockSource creates a new ClockSource for the given device path. +func MakeClockSource(ctx context.Context, clockDevicePath string) (ClockSource, error) { + var result ClockSource + var err error + result.clockDevice, err = os.Open(clockDevicePath) + if err != nil { + return result, errors.Wrapf(err, "cannot open %s", clockDevicePath) + } + + clockDeviceFD := result.clockDevice.Fd() + // For clarification of how the clock id is computed: + // https://lore.kernel.org/patchwork/patch/868609/ + // https://github.com/torvalds/linux/blob/7e63420847ae5f1036e4f7c42f0b3282e73efbc2/tools/testing/selftests/ptp/testptp.c#L87 + clockID := (^clockDeviceFD << 3) | 3 + log.Infof( + ctx, + "opened clock device %s with fd %d, mod_fd %x", + clockDevicePath, + clockDeviceFD, + clockID, + ) + var ts C.struct_timespec + _, err = C.clock_gettime(C.clockid_t(clockID), &ts) + if err != nil { + return result, errors.Wrap(err, "UseClockDevice: error calling clock_gettime") + } + result.clockDeviceID = clockID + + return result, nil +} + +// UnixNano returns the clock device's physical nanosecond +// unix epoch timestamp as a convenience to create a HLC via +// c := hlc.NewClock(dev.UnixNano, ...). +func (p ClockSource) UnixNano() int64 { + var ts C.struct_timespec + _, err := C.clock_gettime(C.clockid_t(p.clockDeviceID), &ts) + if err != nil { + panic(err) + } + + return int64(ts.tv_sec)*1e9 + int64(ts.tv_nsec) +} diff --git a/pkg/util/hlc/hlc_clock_device_stub.go b/pkg/util/hlc/hlc_clock_device_stub.go new file mode 100644 index 000000000000..f2f32391d168 --- /dev/null +++ b/pkg/util/hlc/hlc_clock_device_stub.go @@ -0,0 +1,34 @@ +// Copyright 2017 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +// +build !linux + +package hlc + +import ( + "context" + + "github.com/pkg/errors" +) + +// ClockSource contains the handle of the clock device as well as the +// clock id. +type ClockSource struct { +} + +// UnixNano is not used on platforms other than Linux +func (p ClockSource) UnixNano() int64 { + panic(errors.New("clock device not supported on this platform")) +} + +// MakeClockSource us not used on platforms other than Linux +func MakeClockSource(_ context.Context, _ string) (ClockSource, error) { + return ClockSource{}, errors.New("clock device not supported on this platform") +}