@@ -231,26 +231,78 @@ func TestDatabaseLevelChangefeedWithIncludeFilter(t *testing.T) {
231
231
defer log .Scope (t ).Close (t )
232
232
233
233
testFn := func (t * testing.T , s TestServer , f cdctest.TestFeedFactory ) {
234
- expectSuccess := func (stmt string ) {
235
- successfulFeed := feed (t , f , stmt )
236
- defer closeFeed (t , successfulFeed )
237
- _ , err := successfulFeed .Next ()
238
- require .NoError (t , err )
239
- }
240
234
sqlDB := sqlutils .MakeSQLRunner (s .DB )
241
- sqlDB .Exec (t , `CREATE TABLE foo (a INT PRIMARY KEY, b STRING)` )
242
- sqlDB .Exec (t , `INSERT INTO foo VALUES (0, 'initial')` )
243
- sqlDB .Exec (t , `UPSERT INTO foo VALUES (0, 'updated')` )
244
- sqlDB .Exec (t , `CREATE TABLE foo2 (a INT PRIMARY KEY, b STRING)` )
245
- sqlDB .Exec (t , `INSERT INTO foo2 VALUES (0, 'initial')` )
246
- sqlDB .Exec (t , `UPSERT INTO foo2 VALUES (0, 'updated')` )
235
+ for i := range 4 {
236
+ name := fmt .Sprintf ("foo%d" , i + 1 )
237
+ sqlDB .Exec (t , fmt .Sprintf (`CREATE TABLE %s (a INT PRIMARY KEY, b STRING)` , name ))
238
+ sqlDB .Exec (t , fmt .Sprintf (`INSERT INTO %s VALUES (0, 'initial')` , name ))
239
+ sqlDB .Exec (t , fmt .Sprintf (`UPSERT INTO %s VALUES (0, 'updated')` , name ))
240
+ }
241
+
242
+ sqlDB .Exec (t , `CREATE SCHEMA private` )
243
+ sqlDB .Exec (t , `CREATE TABLE private.foo1 (a INT PRIMARY KEY, b STRING)` )
244
+ sqlDB .Exec (t , `INSERT INTO private.foo1 VALUES (0, 'initial')` )
245
+ // Test that if there are multiple tables with the same name the correct
246
+ // one will still be found using the default schema of public.
247
+ feed1 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo1` )
248
+ defer closeFeed (t , feed1 )
249
+ assertPayloads (t , feed1 , []string {
250
+ `foo1: [0]->{"after": {"a": 0, "b": "updated"}}` ,
251
+ })
252
+
253
+ // Test that we can include multiple tables.
254
+ feed2 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo1,foo2` )
255
+ defer closeFeed (t , feed2 )
256
+ assertPayloads (t , feed2 , []string {
257
+ `foo1: [0]->{"after": {"a": 0, "b": "updated"}}` ,
258
+ `foo2: [0]->{"after": {"a": 0, "b": "updated"}}` ,
259
+ })
247
260
248
- expectSuccess (`CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo` )
249
- expectSuccess (`CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo,foo2` )
250
- expectSuccess (`CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES d.bar.fizz, foo.foo2, foo` )
261
+ // Test that we can handle fully qualified, partially qualified, and unqualified
262
+ // table names.
263
+ feed3 := feed (t , f ,
264
+ `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES d.public.foo2, public.foo3, foo4` )
265
+ defer closeFeed (t , feed3 )
266
+ assertPayloads (t , feed3 , []string {
267
+ `foo2: [0]->{"after": {"a": 0, "b": "updated"}}` ,
268
+ `foo3: [0]->{"after": {"a": 0, "b": "updated"}}` ,
269
+ `foo4: [0]->{"after": {"a": 0, "b": "updated"}}` ,
270
+ })
271
+
272
+ // Test that we can handle tables that don't exist.
273
+ feed4 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo1,bob` )
274
+ defer closeFeed (t , feed4 )
275
+ assertPayloads (t , feed4 , []string {
276
+ `foo1: [0]->{"after": {"a": 0, "b": "updated"}}` ,
277
+ })
278
+
279
+ // Test that fully qualified table names outside of the target database will
280
+ // cause an error.
281
+ expectErrCreatingFeed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES fizz.buzz.foo` ,
282
+ `table "fizz.buzz.foo" must be in target database "d"` )
283
+
284
+ // Table patterns are not supported.
251
285
expectErrCreatingFeed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo.*` ,
252
286
`at or near "*": syntax error` )
253
- // TODO(#147421): Assert payload once the filter works
287
+
288
+ // Test that name resolution is not dependent on search_path() or current DB.
289
+ sqlDB .Exec (t , `CREATE DATABASE notd` )
290
+ sqlDB .Exec (t , `USE notd` )
291
+ sqlDB .Exec (t , `SET search_path TO notpublic` )
292
+ feed5 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES foo1, private.foo1` )
293
+ defer closeFeed (t , feed5 )
294
+ assertPayloads (t , feed5 , []string {
295
+ `foo1: [0]->{"after": {"a": 0, "b": "updated"}}` ,
296
+ `foo1: [0]->{"after": {"a": 0, "b": "initial"}}` ,
297
+ })
298
+
299
+ // Test that partially qualified table names are always assumed to be
300
+ // <schema>.<table>.
301
+ feed6 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d INCLUDE TABLES d.foo1, public.foo2` )
302
+ defer closeFeed (t , feed6 )
303
+ assertPayloads (t , feed6 , []string {
304
+ `foo2: [0]->{"after": {"a": 0, "b": "updated"}}` ,
305
+ })
254
306
}
255
307
cdcTest (t , testFn , feedTestEnterpriseSinks )
256
308
}
@@ -300,8 +352,10 @@ func TestDatabaseLevelChangefeedWithExcludeFilter(t *testing.T) {
300
352
`foo4: [0]->{"after": {"a": 0, "b": "updated"}}` ,
301
353
})
302
354
303
- // Test that we can handle fully qualfied, partially qualified, and unqualified table names.
304
- feed4 := feed (t , f , `CREATE CHANGEFEED FOR DATABASE d EXCLUDE TABLES d.public.foo2, public.foo3, foo4` )
355
+ // Test that we can handle fully qualified, partially qualified, and unqualified
356
+ // table names.
357
+ feed4 := feed (t , f ,
358
+ `CREATE CHANGEFEED FOR DATABASE d EXCLUDE TABLES d.public.foo2, public.foo3, foo4` )
305
359
defer closeFeed (t , feed4 )
306
360
assertPayloads (t , feed4 , []string {
307
361
`foo1: [0]->{"after": {"a": 0, "b": "initial"}}` ,
0 commit comments