@@ -2874,65 +2874,195 @@ func TestSubQueryAndQueryWithLimit(t *testing.T) {
28742874 assert .Equal (t , `type:INT64 value:"100"` , sbc2 .Queries [1 ].BindVariables ["__upper_limit" ].String ())
28752875}
28762876
2877- func TestSelectUsingMultiEqualOnLookupColumn (t * testing.T ) {
2878- executor , sbc1 , sbc2 , sbclookup , _ := createExecutorEnv (t )
2877+ func TestSelectUsingLookupColumn (t * testing.T ) {
2878+ t .Run ("using multi value tuple" , func (t * testing.T ) {
2879+ ctx := context .Background ()
28792880
2880- // No results on shard `-20` (`sbc1`), but some lookup results on shard `40-60` (`sbc2`)
2881- sbclookup .SetResults ([]* sqltypes.Result {{
2882- Fields : []* querypb.Field {
2883- {Name : "lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2884- {Name : "keyspace_id" , Type : sqltypes .VarBinary , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_BINARY_FLAG )},
2885- },
2886- Rows : [][]sqltypes.Value {{
2887- sqltypes .NewInt32 (2 ),
2888- sqltypes .MakeTrusted (sqltypes .VarBinary , []byte ("\x45 " )),
2889- }},
2890- }})
2881+ // Special setup: Don't use createExecutorEnv.
2882+ cell := "aa"
2883+ hc := discovery .NewFakeHealthCheck (nil )
28912884
2892- sbc1 .SetResults ([]* sqltypes.Result {{
2893- Fields : []* querypb.Field {
2894- {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2895- {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
2896- },
2897- Rows : [][]sqltypes.Value {},
2898- }})
2885+ u := createSandbox (KsTestUnsharded )
2886+ s := createSandbox (KsTestSharded )
28992887
2900- sbc2 .SetResults ([]* sqltypes.Result {{
2901- Fields : []* querypb.Field {
2902- {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2903- {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
2904- },
2905- Rows : [][]sqltypes.Value {{
2906- sqltypes .NewInt32 (2 ),
2907- sqltypes .NewVarChar ("baz" ),
2908- }},
2909- }})
2888+ s .VSchema = executorVSchema
2889+ u .VSchema = unshardedVSchema
29102890
2911- result , err := exec (executor , NewSafeSession (& vtgatepb.Session {
2912- TargetString : KsTestSharded ,
2913- }), "select nv_lu_col, other from t2_lookup WHERE (nv_lu_col = 1 AND other = 'bar') OR (nv_lu_col = 2 AND other = 'baz') OR (nv_lu_col = 3 AND other = 'qux') OR (nv_lu_col = 4 AND other = 'brz') OR (nv_lu_col = 5 AND other = 'brz')" )
2891+ serv := newSandboxForCells (ctx , []string {cell })
2892+ resolver := newTestResolver (ctx , hc , serv , cell )
29142893
2915- require .NoError (t , err )
2894+ shards := []string {"-20" , "20-40" , "40-60" , "60-80" , "80-a0" , "a0-c0" , "c0-e0" , "e0-" }
2895+ sbcs := []* sandboxconn.SandboxConn {}
2896+ for _ , shard := range shards {
2897+ sbcs = append (sbcs , hc .AddTestTablet (cell , shard , 1 , "TestExecutor" , shard , topodatapb .TabletType_PRIMARY , true , 1 , nil ))
2898+ }
29162899
2917- require .Len (t , sbc1 .Queries , 0 )
2918- require .Len (t , sbc2 .Queries , 1 )
2900+ sbclookup := hc .AddTestTablet (cell , "0" , 1 , KsTestUnsharded , "0" , topodatapb .TabletType_PRIMARY , true , 1 , nil )
29192901
2920- require . Equal ( t , [] * querypb. BoundQuery {{
2921- Sql : "select nv_lu_col, other from t2_lookup where nv_lu_col = 1 and other = 'bar' or nv_lu_col = 2 and other = 'baz' or nv_lu_col = 3 and other = 'qux' or nv_lu_col = 4 and other = 'brz' or nv_lu_col = 5 and other = 'brz'" ,
2922- BindVariables : map [ string ] * querypb. BindVariable {},
2923- }}, sbc2 . Queries )
2902+ executor := createExecutor ( ctx , serv , cell , resolver )
2903+ defer executor . Close ()
2904+ logChan := executor . queryLogger . Subscribe ( "Test" )
2905+ defer executor . queryLogger . Unsubscribe ( logChan )
29242906
2925- wantResult := & sqltypes.Result {
2926- Fields : []* querypb.Field {
2927- {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2928- {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
2929- },
2930- Rows : [][]sqltypes.Value {{
2931- sqltypes .NewInt32 (2 ),
2932- sqltypes .NewVarChar ("baz" ),
2933- }},
2934- }
2935- require .Equal (t , wantResult , result )
2907+ // Only lookup results on shard `40-60` (`sbc[2]`)
2908+ sbclookup .SetResults ([]* sqltypes.Result {{
2909+ Fields : []* querypb.Field {
2910+ {Name : "lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2911+ {Name : "keyspace_id" , Type : sqltypes .VarBinary , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_BINARY_FLAG )},
2912+ },
2913+ Rows : [][]sqltypes.Value {{
2914+ sqltypes .NewInt32 (2 ),
2915+ sqltypes .MakeTrusted (sqltypes .VarBinary , []byte ("\x45 " )),
2916+ }},
2917+ }})
2918+
2919+ sbcs [2 ].SetResults ([]* sqltypes.Result {{
2920+ Fields : []* querypb.Field {
2921+ {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2922+ {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
2923+ },
2924+ Rows : [][]sqltypes.Value {{
2925+ sqltypes .NewInt32 (2 ),
2926+ sqltypes .NewVarChar ("baz" ),
2927+ }},
2928+ }})
2929+
2930+ result , err := exec (executor , NewSafeSession (& vtgatepb.Session {
2931+ TargetString : KsTestSharded ,
2932+ }), "select nv_lu_col, other from t2_lookup WHERE (nv_lu_col, other) IN ((1, 'bar'), (2, 'baz'), (3, 'qux'), (4, 'brz'), (5, 'brz'))" )
2933+
2934+ require .NoError (t , err )
2935+
2936+ require .Len (t , sbclookup .Queries , 1 )
2937+ require .Len (t , sbcs [0 ].Queries , 0 )
2938+ require .Len (t , sbcs [1 ].Queries , 0 )
2939+ require .Len (t , sbcs [2 ].Queries , 1 )
2940+ require .Len (t , sbcs [3 ].Queries , 0 )
2941+ require .Len (t , sbcs [4 ].Queries , 0 )
2942+ require .Len (t , sbcs [5 ].Queries , 0 )
2943+ require .Len (t , sbcs [6 ].Queries , 0 )
2944+ require .Len (t , sbcs [7 ].Queries , 0 )
2945+
2946+ require .Equal (t , []* querypb.BoundQuery {{
2947+ Sql : "select nv_lu_col, other from t2_lookup where (nv_lu_col, other) in ((1, 'bar'), (2, 'baz'), (3, 'qux'), (4, 'brz'), (5, 'brz'))" ,
2948+ BindVariables : map [string ]* querypb.BindVariable {},
2949+ }}, sbcs [2 ].Queries )
2950+
2951+ wantResult := & sqltypes.Result {
2952+ Fields : []* querypb.Field {
2953+ {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2954+ {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
2955+ },
2956+ Rows : [][]sqltypes.Value {{
2957+ sqltypes .NewInt32 (2 ),
2958+ sqltypes .NewVarChar ("baz" ),
2959+ }},
2960+ }
2961+ require .Equal (t , wantResult , result )
2962+ })
2963+
2964+ t .Run ("using disjunction of conjunctions" , func (t * testing.T ) {
2965+ ctx := context .Background ()
2966+
2967+ // Special setup: Don't use createExecutorEnv.
2968+ cell := "aa"
2969+ hc := discovery .NewFakeHealthCheck (nil )
2970+
2971+ u := createSandbox (KsTestUnsharded )
2972+ s := createSandbox (KsTestSharded )
2973+
2974+ s .VSchema = executorVSchema
2975+ u .VSchema = unshardedVSchema
2976+
2977+ serv := newSandboxForCells (ctx , []string {cell })
2978+ resolver := newTestResolver (ctx , hc , serv , cell )
2979+
2980+ shards := []string {"-20" , "20-40" , "40-60" , "60-80" , "80-a0" , "a0-c0" , "c0-e0" , "e0-" }
2981+ sbcs := []* sandboxconn.SandboxConn {}
2982+ for _ , shard := range shards {
2983+ sbcs = append (sbcs , hc .AddTestTablet (cell , shard , 1 , "TestExecutor" , shard , topodatapb .TabletType_PRIMARY , true , 1 , nil ))
2984+ }
2985+
2986+ sbclookup := hc .AddTestTablet (cell , "0" , 1 , KsTestUnsharded , "0" , topodatapb .TabletType_PRIMARY , true , 1 , nil )
2987+
2988+ executor := createExecutor (ctx , serv , cell , resolver )
2989+ defer executor .Close ()
2990+ logChan := executor .queryLogger .Subscribe ("Test" )
2991+ defer executor .queryLogger .Unsubscribe (logChan )
2992+
2993+ // Only lookup results on shard `40-60` (`sbc[2]`)
2994+ sbclookup .SetResults ([]* sqltypes.Result {{
2995+ Fields : []* querypb.Field {
2996+ {Name : "lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
2997+ {Name : "keyspace_id" , Type : sqltypes .VarBinary , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_BINARY_FLAG )},
2998+ },
2999+ Rows : [][]sqltypes.Value {{
3000+ sqltypes .NewInt32 (2 ),
3001+ sqltypes .MakeTrusted (sqltypes .VarBinary , []byte ("\x45 " )),
3002+ }},
3003+ }})
3004+
3005+ emptyResult := []* sqltypes.Result {{
3006+ Fields : []* querypb.Field {
3007+ {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
3008+ {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
3009+ },
3010+ Rows : [][]sqltypes.Value {},
3011+ }}
3012+
3013+ sbcs [0 ].SetResults (emptyResult )
3014+ sbcs [1 ].SetResults (emptyResult )
3015+ sbcs [2 ].SetResults ([]* sqltypes.Result {{
3016+ Fields : []* querypb.Field {
3017+ {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
3018+ {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
3019+ },
3020+ Rows : [][]sqltypes.Value {{
3021+ sqltypes .NewInt32 (2 ),
3022+ sqltypes .NewVarChar ("baz" ),
3023+ }},
3024+ }})
3025+ sbcs [3 ].SetResults (emptyResult )
3026+ sbcs [4 ].SetResults (emptyResult )
3027+ sbcs [5 ].SetResults (emptyResult )
3028+ sbcs [6 ].SetResults (emptyResult )
3029+ sbcs [7 ].SetResults (emptyResult )
3030+
3031+ result , err := exec (executor , NewSafeSession (& vtgatepb.Session {
3032+ TargetString : KsTestSharded ,
3033+ }), "select nv_lu_col, other from t2_lookup WHERE (nv_lu_col = 1 AND other = 'bar') OR (nv_lu_col = 2 AND other = 'baz') OR (nv_lu_col = 3 AND other = 'qux') OR (nv_lu_col = 4 AND other = 'brz') OR (nv_lu_col = 5 AND other = 'brz')" )
3034+
3035+ require .NoError (t , err )
3036+
3037+ // We end up doing a scatter query here, so no queries are sent to the lookup table
3038+ require .Len (t , sbclookup .Queries , 0 )
3039+ require .Len (t , sbcs [0 ].Queries , 1 )
3040+ require .Len (t , sbcs [1 ].Queries , 1 )
3041+ require .Len (t , sbcs [2 ].Queries , 1 )
3042+ require .Len (t , sbcs [3 ].Queries , 1 )
3043+ require .Len (t , sbcs [4 ].Queries , 1 )
3044+ require .Len (t , sbcs [5 ].Queries , 1 )
3045+ require .Len (t , sbcs [6 ].Queries , 1 )
3046+ require .Len (t , sbcs [7 ].Queries , 1 )
3047+
3048+ for _ , sbc := range sbcs {
3049+ require .Equal (t , []* querypb.BoundQuery {{
3050+ Sql : "select nv_lu_col, other from t2_lookup where nv_lu_col = 1 and other = 'bar' or nv_lu_col = 2 and other = 'baz' or nv_lu_col = 3 and other = 'qux' or nv_lu_col = 4 and other = 'brz' or nv_lu_col = 5 and other = 'brz'" ,
3051+ BindVariables : map [string ]* querypb.BindVariable {},
3052+ }}, sbc .Queries )
3053+ }
3054+ wantResult := & sqltypes.Result {
3055+ Fields : []* querypb.Field {
3056+ {Name : "nv_lu_col" , Type : sqltypes .Int32 , Charset : collations .CollationBinaryID , Flags : uint32 (querypb .MySqlFlag_NUM_FLAG )},
3057+ {Name : "other" , Type : sqltypes .VarChar , Charset : collations .CollationUtf8mb4ID },
3058+ },
3059+ Rows : [][]sqltypes.Value {{
3060+ sqltypes .NewInt32 (2 ),
3061+ sqltypes .NewVarChar ("baz" ),
3062+ }},
3063+ }
3064+ require .Equal (t , wantResult , result )
3065+ })
29363066}
29373067
29383068func TestCrossShardSubqueryStream (t * testing.T ) {
0 commit comments