Skip to content

Commit 82a1c7d

Browse files
craig[bot]dhartunianKeithChRaduBerindearulajmani
committed
153372: server: add Transaction Diagnostic Bundle APIs r=kyle-a-wong a=dhartunian This commit adds 3 new endpoints to the status server to support: - creating transaction diagnostic bundle requests - cancelling transaction diagnostic bundle requests - listing all outstanding transaction diagnostic bundle requests A new `TxnDiagnosticsRequester` interface is defined in `transaction_diagnostic_requests.go` which the `TxnRegistry` now implements to support the create and cancel operations since they need to interact with the registry at run-time. Resolves: [CRDB-53544](https://cockroachlabs.atlassian.net/browse/CRDB-53544) Epic: [CRDB-53541](https://cockroachlabs.atlassian.net/browse/CRDB-53541) Release note: None 153916: changefeedccl: support EXCLUDE TABLES in DB-level feeds r=andyyang890 a=KeithCh Support the ability to exclude tables from being watched in a database-level feed. An example usage is: CREATE DATABASE FOR CHANGEFEED defaultdb EXCLUDE TABLES foo,fizz.buzz,defaultdb.bar.tab,notdefaultdb.bar.tab; The table names above in the EXCLUDE TABLES list will be resolved as such: Non-qualified table name foo: - defaultdb.public.foo Partially-qualified table name fizz.buzz: - defaultdb.fizz.buzz Fully-qualified table name defaultdb.bar.tab: - defaultdb.bar.tab Fully-qualified table name notdefaultdb.bar.tab: - Statement error; changefeed job will not be created Note that partially qualified table names in the form \<database\>.\<table\> are not supported. Partially qualfied table names are always assumed to be \<schema\>.\<table\>. Resolves: #147424 Release note: none 153966: go.mod: bump Pebble to e1277c42a560 r=RaduBerinde a=RaduBerinde Changes: * [`e1277c42`](cockroachdb/pebble@e1277c42) cache: separate hit/miss metrics by level * [`bf48872f`](cockroachdb/pebble@bf48872f) block: hide cache hits/misses from the level checker * [`0c63ea83`](cockroachdb/pebble@0c63ea83) metrics: more granular block cache metrics * [`96bb7581`](cockroachdb/pebble@96bb7581) metricsutil: add Window data structure * [`8b8ee488`](cockroachdb/pebble@8b8ee488) cache: improve BenchmarkCacheGet * [`4f3e287b`](cockroachdb/pebble@4f3e287b) pebble: deflake TestCompactionDeleteOnlyHints * [`6c6fd755`](cockroachdb/pebble@6c6fd755) cache: don't mark blocks as accessed for background work * [`6e9ddf29`](cockroachdb/pebble@6e9ddf29) cockroachkvs: avoid cockroachKeysSeeker.init allocation * [`f3afdb60`](cockroachdb/pebble@f3afdb60) cockroachkvs: add BenchmarkInitDataBlockMetadata * [`489b133b`](cockroachdb/pebble@489b133b) colblk: remove BlockDecoder allocation * [`5c08fa34`](cockroachdb/pebble@5c08fa34) colblk: add BenchmarkInitDataBlockMetadata * [`998a55aa`](cockroachdb/pebble@998a55aa) Revert "cache: use malloc instead of calloc" * [`3c70d62d`](cockroachdb/pebble@3c70d62d) db: reduce numOps in TestWALHardCrashRandomized * [`9086c4be`](cockroachdb/pebble@9086c4be) db: reduce numOps in TestWALFailoverRandomized * [`4aab1726`](cockroachdb/pebble@4aab1726) db: remove duplicate TestFileCacheClockPro * [`73bba8fb`](cockroachdb/pebble@73bba8fb) db: reduce TestOpenCloseOpenClose configurations * [`8e019e4e`](cockroachdb/pebble@8e019e4e) db: make TestCompaction/value_separation faster * [`1e1841c7`](cockroachdb/pebble@1e1841c7) db: make TestCompaction/l0_to_lbase_compaction faster Release note: none. Epic: none. 154070: batcheval: make TestExportCmd work with secondary tenants r=stevendanna a=arulajmani Closes #109429 Release note: None 154161: cli: skip TestTSDumpUploadWithEmbeddedMetadataDataDriven under race r=kyle-a-wong a=kyle-a-wong This test fails in bazel under race, so we are skipping for now. Part-of: CRDB-53617 Epic: None Release note: None 154168: roachtest: fix log file in slow-drain test r=miraradeva a=miraradeva The test was looking for a specific log message, which recently moved to the KV distribution channel. This commit points the test to the right log file. Fixes: #154153 Fixes: #154138 Release note: None 154169: ci,ui: fix cluster-ui-release "check if published" step r=kyle-a-wong a=kyle-a-wong The check for whether a version exists in npm is too liberal with its pattern matching, resulting in pre-release branches to cause other releases to fail to publish. Now, a pre-release version will not cause a potential failure in publish a regular version release. Epic: None Release note: None Updated script on the right, old on the left: <img width="1715" height="471" alt="image" src="https://github.com/user-attachments/assets/f01c415d-d176-40d5-af83-ba169429813c" /> Co-authored-by: David Hartunian <[email protected]> Co-authored-by: Keith Chow <[email protected]> Co-authored-by: Radu Berinde <[email protected]> Co-authored-by: Arul Ajmani <[email protected]> Co-authored-by: Kyle Wong <[email protected]> Co-authored-by: Mira Radeva <[email protected]>
8 parents 36e539b + d6e563a + 35d0006 + f27190b + 97ea5bc + 6ec01fb + bbe67e9 + b163243 commit 82a1c7d

File tree

35 files changed

+1226
-84
lines changed

35 files changed

+1226
-84
lines changed

.github/workflows/cluster-ui-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
run: |
5959
PACKAGE_VERSION=$(cat ./package.json | jq -r ".version");
6060
VERSIONS=$(npm view @cockroachlabs/cluster-ui versions)
61-
if [[ $VERSIONS == *"$PACKAGE_VERSION"* ]]; then
61+
if [[ $VERSIONS == *\'"$PACKAGE_VERSION"\'* ]]; then
6262
echo "published=yes" >> $GITHUB_OUTPUT
6363
echo
6464
echo "🛑 Cluster UI package version $PACKAGE_VERSION is already published"

DEPS.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,10 +1830,10 @@ def go_deps():
18301830
patches = [
18311831
"@com_github_cockroachdb_cockroach//build/patches:com_github_cockroachdb_pebble.patch",
18321832
],
1833-
sha256 = "ce6b413d464aa7d86272d5b70b34cfe911c05f4dd4ce540cabaf7899c766aba3",
1834-
strip_prefix = "github.com/cockroachdb/[email protected]20250918210818-53f12aa6852b",
1833+
sha256 = "2fefabece81a88650b7562c3d1b2498b57f32624453b9b277ee34e5b7bfc8afc",
1834+
strip_prefix = "github.com/cockroachdb/[email protected]20250923154941-e1277c42a560",
18351835
urls = [
1836-
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20250918210818-53f12aa6852b.zip",
1836+
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20250923154941-e1277c42a560.zip",
18371837
],
18381838
)
18391839
go_repository(

build/bazelutil/distdir_files.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ DISTDIR_FILES = {
356356
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/gostdlib/com_github_cockroachdb_gostdlib-v1.19.0.zip": "c4d516bcfe8c07b6fc09b8a9a07a95065b36c2855627cb3514e40c98f872b69e",
357357
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/logtags/com_github_cockroachdb_logtags-v0.0.0-20241215232642-bb51bb14a506.zip": "920068af09e3846d9ebb4e4a7787ff1dd10f3989c5f940ad861b0f6a9f824f6e",
358358
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/metamorphic/com_github_cockroachdb_metamorphic-v0.0.0-20231108215700-4ba948b56895.zip": "28c8cf42192951b69378cf537be5a9a43f2aeb35542908cc4fe5f689505853ea",
359-
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20250918210818-53f12aa6852b.zip": "ce6b413d464aa7d86272d5b70b34cfe911c05f4dd4ce540cabaf7899c766aba3",
359+
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/pebble/com_github_cockroachdb_pebble-v0.0.0-20250923154941-e1277c42a560.zip": "2fefabece81a88650b7562c3d1b2498b57f32624453b9b277ee34e5b7bfc8afc",
360360
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/redact/com_github_cockroachdb_redact-v1.1.6.zip": "018eccb5fb9ca52d43ec9eaf213539d01c1f2b94e0e822406ebfb2e9321ef6cf",
361361
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/returncheck/com_github_cockroachdb_returncheck-v0.0.0-20200612231554-92cdbca611dd.zip": "ce92ba4352deec995b1f2eecf16eba7f5d51f5aa245a1c362dfe24c83d31f82b",
362362
"https://storage.googleapis.com/cockroach-godeps/gomod/github.com/cockroachdb/stress/com_github_cockroachdb_stress-v0.0.0-20220803192808-1806698b1b7b.zip": "3fda531795c600daf25532a4f98be2a1335cd1e5e182c72789bca79f5f69fcc1",

docs/generated/http/full.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4719,6 +4719,191 @@ Support status: [reserved](#support-status)
47194719

47204720

47214721

4722+
## CreateTransactionDiagnosticsReport
4723+
4724+
`POST /_status/txndiagreports`
4725+
4726+
4727+
4728+
Support status: [reserved](#support-status)
4729+
4730+
#### Request Parameters
4731+
4732+
4733+
4734+
4735+
createTransactionDiagnosticsReportRequest is a message that captures a
4736+
user's requst to capture a transaction diagnostic bundle.
4737+
4738+
4739+
| Field | Type | Label | Description | Support status |
4740+
| ----- | ---- | ----- | ----------- | -------------- |
4741+
| transaction_fingerprint_id | [bytes](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-bytes) | | | [reserved](#support-status) |
4742+
| statement_fingerprint_ids | [bytes](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-bytes) | repeated | | [reserved](#support-status) |
4743+
| min_execution_latency | [google.protobuf.Duration](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-google.protobuf.Duration) | | | [reserved](#support-status) |
4744+
| expires_at | [google.protobuf.Duration](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-google.protobuf.Duration) | | | [reserved](#support-status) |
4745+
| sampling_probability | [double](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-double) | | | [reserved](#support-status) |
4746+
| redacted | [bool](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportRequest-bool) | | | [reserved](#support-status) |
4747+
4748+
4749+
4750+
4751+
4752+
4753+
4754+
#### Response Parameters
4755+
4756+
4757+
4758+
4759+
4760+
4761+
4762+
| Field | Type | Label | Description | Support status |
4763+
| ----- | ---- | ----- | ----------- | -------------- |
4764+
| report | [TransactionDiagnosticsReport](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-cockroach.server.serverpb.TransactionDiagnosticsReport) | | | [reserved](#support-status) |
4765+
4766+
4767+
4768+
4769+
4770+
4771+
<a name="cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-cockroach.server.serverpb.TransactionDiagnosticsReport"></a>
4772+
#### TransactionDiagnosticsReport
4773+
4774+
TransactionDiagnosticsReport is a message that represents a
4775+
diagnostics capture request for a given transaction.
4776+
4777+
| Field | Type | Label | Description | Support status |
4778+
| ----- | ---- | ----- | ----------- | -------------- |
4779+
| id | [int64](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-int64) | | | [reserved](#support-status) |
4780+
| completed | [bool](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-bool) | | | [reserved](#support-status) |
4781+
| transaction_fingerprint_id | [bytes](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-bytes) | | TODO(davidh): should these be strings or int64??? I think bytes is most correct. | [reserved](#support-status) |
4782+
| statement_fingerprint_ids | [bytes](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-bytes) | repeated | | [reserved](#support-status) |
4783+
| transaction_fingerprint | [string](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-string) | | | [reserved](#support-status) |
4784+
| transaction_diagnostics_id | [int64](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-int64) | | | [reserved](#support-status) |
4785+
| requested_at | [google.protobuf.Timestamp](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-google.protobuf.Timestamp) | | | [reserved](#support-status) |
4786+
| min_execution_latency | [google.protobuf.Duration](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-google.protobuf.Duration) | | | [reserved](#support-status) |
4787+
| expires_at | [google.protobuf.Timestamp](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-google.protobuf.Timestamp) | | | [reserved](#support-status) |
4788+
| sampling_probability | [double](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-double) | | | [reserved](#support-status) |
4789+
| redacted | [bool](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-bool) | | | [reserved](#support-status) |
4790+
| username | [string](#cockroach.server.serverpb.CreateTransactionDiagnosticsReportResponse-string) | | | [reserved](#support-status) |
4791+
4792+
4793+
4794+
4795+
4796+
4797+
## CancelTransactionDiagnosticsReport
4798+
4799+
`POST /_status/txndiagreports/cancel`
4800+
4801+
4802+
4803+
Support status: [reserved](#support-status)
4804+
4805+
#### Request Parameters
4806+
4807+
4808+
4809+
4810+
4811+
4812+
4813+
| Field | Type | Label | Description | Support status |
4814+
| ----- | ---- | ----- | ----------- | -------------- |
4815+
| request_id | [int64](#cockroach.server.serverpb.CancelTransactionDiagnosticsReportRequest-int64) | | | [reserved](#support-status) |
4816+
4817+
4818+
4819+
4820+
4821+
4822+
4823+
#### Response Parameters
4824+
4825+
4826+
4827+
4828+
4829+
4830+
4831+
| Field | Type | Label | Description | Support status |
4832+
| ----- | ---- | ----- | ----------- | -------------- |
4833+
| canceled | [bool](#cockroach.server.serverpb.CancelTransactionDiagnosticsReportResponse-bool) | | canceled indicates whether the request for the given fingerprint was actually canceled. | [reserved](#support-status) |
4834+
| error | [string](#cockroach.server.serverpb.CancelTransactionDiagnosticsReportResponse-string) | | error is set only if canceled is false. | [reserved](#support-status) |
4835+
4836+
4837+
4838+
4839+
4840+
4841+
4842+
## TransactionDiagnosticsRequests
4843+
4844+
`GET /_status/txndiagreports`
4845+
4846+
4847+
4848+
Support status: [reserved](#support-status)
4849+
4850+
#### Request Parameters
4851+
4852+
4853+
4854+
4855+
4856+
4857+
4858+
4859+
4860+
4861+
4862+
4863+
4864+
#### Response Parameters
4865+
4866+
4867+
4868+
4869+
4870+
4871+
4872+
| Field | Type | Label | Description | Support status |
4873+
| ----- | ---- | ----- | ----------- | -------------- |
4874+
| reports | [TransactionDiagnosticsReport](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-cockroach.server.serverpb.TransactionDiagnosticsReport) | repeated | | [reserved](#support-status) |
4875+
4876+
4877+
4878+
4879+
4880+
4881+
<a name="cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-cockroach.server.serverpb.TransactionDiagnosticsReport"></a>
4882+
#### TransactionDiagnosticsReport
4883+
4884+
TransactionDiagnosticsReport is a message that represents a
4885+
diagnostics capture request for a given transaction.
4886+
4887+
| Field | Type | Label | Description | Support status |
4888+
| ----- | ---- | ----- | ----------- | -------------- |
4889+
| id | [int64](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-int64) | | | [reserved](#support-status) |
4890+
| completed | [bool](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-bool) | | | [reserved](#support-status) |
4891+
| transaction_fingerprint_id | [bytes](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-bytes) | | TODO(davidh): should these be strings or int64??? I think bytes is most correct. | [reserved](#support-status) |
4892+
| statement_fingerprint_ids | [bytes](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-bytes) | repeated | | [reserved](#support-status) |
4893+
| transaction_fingerprint | [string](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-string) | | | [reserved](#support-status) |
4894+
| transaction_diagnostics_id | [int64](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-int64) | | | [reserved](#support-status) |
4895+
| requested_at | [google.protobuf.Timestamp](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-google.protobuf.Timestamp) | | | [reserved](#support-status) |
4896+
| min_execution_latency | [google.protobuf.Duration](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-google.protobuf.Duration) | | | [reserved](#support-status) |
4897+
| expires_at | [google.protobuf.Timestamp](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-google.protobuf.Timestamp) | | | [reserved](#support-status) |
4898+
| sampling_probability | [double](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-double) | | | [reserved](#support-status) |
4899+
| redacted | [bool](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-bool) | | | [reserved](#support-status) |
4900+
| username | [string](#cockroach.server.serverpb.TransactionDiagnosticsReportsResponse-string) | | | [reserved](#support-status) |
4901+
4902+
4903+
4904+
4905+
4906+
47224907
## JobRegistryStatus
47234908

47244909
`GET /_status/job_registry/{node_id}`

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ require (
142142
github.com/cockroachdb/go-test-teamcity v0.0.0-20191211140407-cff980ad0a55
143143
github.com/cockroachdb/gostdlib v1.19.0
144144
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506
145-
github.com/cockroachdb/pebble v0.0.0-20250918210818-53f12aa6852b
145+
github.com/cockroachdb/pebble v0.0.0-20250923154941-e1277c42a560
146146
github.com/cockroachdb/redact v1.1.6
147147
github.com/cockroachdb/returncheck v0.0.0-20200612231554-92cdbca611dd
148148
github.com/cockroachdb/stress v0.0.0-20220803192808-1806698b1b7b

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -577,8 +577,8 @@ github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 h1:ASDL+UJcILM
577577
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506/go.mod h1:Mw7HqKr2kdtu6aYGn3tPmAftiP3QPX63LdK/zcariIo=
578578
github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895 h1:XANOgPYtvELQ/h4IrmPAohXqe2pWA8Bwhejr3VQoZsA=
579579
github.com/cockroachdb/metamorphic v0.0.0-20231108215700-4ba948b56895/go.mod h1:aPd7gM9ov9M8v32Yy5NJrDyOcD8z642dqs+F0CeNXfA=
580-
github.com/cockroachdb/pebble v0.0.0-20250918210818-53f12aa6852b h1:3SqE/JRApTxaGjSQC3En4sEzQ/FHDPYVVMO7aRtgPc8=
581-
github.com/cockroachdb/pebble v0.0.0-20250918210818-53f12aa6852b/go.mod h1:H/DxkYtsYVJwPFLikOL9yzb/PV7oIkz44CUmn4KecKg=
580+
github.com/cockroachdb/pebble v0.0.0-20250923154941-e1277c42a560 h1:jf/rjcPdZkA4qwbsmuJFZ7jQbssRedM67THQXtnChVQ=
581+
github.com/cockroachdb/pebble v0.0.0-20250923154941-e1277c42a560/go.mod h1:H/DxkYtsYVJwPFLikOL9yzb/PV7oIkz44CUmn4KecKg=
582582
github.com/cockroachdb/redact v1.1.6 h1:zXJBwDZ84xJNlHl1rMyCojqyIxv+7YUpQiJLQ7n4314=
583583
github.com/cockroachdb/redact v1.1.6/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
584584
github.com/cockroachdb/returncheck v0.0.0-20200612231554-92cdbca611dd h1:KFOt5I9nEKZgCnOSmy8r4Oykh8BYQO8bFOTgHDS8YZA=

pkg/ccl/changefeedccl/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ go_library(
120120
"//pkg/sql/rowenc",
121121
"//pkg/sql/rowexec",
122122
"//pkg/sql/sem/asof",
123+
"//pkg/sql/sem/catconstants",
123124
"//pkg/sql/sem/catid",
124125
"//pkg/sql/sem/eval",
125126
"//pkg/sql/sem/tree",

pkg/ccl/changefeedccl/changefeed.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package changefeedccl
88
import (
99
"context"
1010
"encoding/json"
11+
"fmt"
1112

1213
"github.com/cockroachdb/cockroach/pkg/ccl/changefeedccl/changefeedbase"
1314
"github.com/cockroachdb/cockroach/pkg/cloud"
@@ -113,10 +114,12 @@ func getTargetsFromDatabaseSpec(
113114
if err != nil {
114115
return err
115116
}
117+
tableDescToSchemaName := make(map[catalog.TableDescriptor]string)
116118
tables, err := descs.GetAllTablesInDatabase(ctx, txn.KV(), databaseDescriptor)
117119
if err != nil {
118120
return err
119121
}
122+
dbName := databaseDescriptor.GetName()
120123
for _, desc := range tables.OrderedDescriptors() {
121124
tableDesc, ok := desc.(catalog.TableDescriptor)
122125
if !ok {
@@ -126,6 +129,20 @@ func getTargetsFromDatabaseSpec(
126129
if !tableDesc.IsPhysicalTable() {
127130
continue
128131
}
132+
if ts.FilterList != nil && ts.FilterList.FilterType == jobspb.FilterList_EXCLUDE_TABLES {
133+
if _, ok := tableDescToSchemaName[tableDesc]; !ok {
134+
schemaID := tableDesc.GetParentSchemaID()
135+
schema, err := descs.ByIDWithLeased(txn.KV()).Get().Schema(ctx, schemaID)
136+
if err != nil {
137+
return err
138+
}
139+
tableDescToSchemaName[tableDesc] = schema.GetName()
140+
}
141+
fullyQualifiedTableName := fmt.Sprintf("%s.%s.%s", dbName, tableDescToSchemaName[tableDesc], tableDesc.GetName())
142+
if _, ok := ts.FilterList.Tables[fullyQualifiedTableName]; ok {
143+
continue
144+
}
145+
}
129146
var tableType jobspb.ChangefeedTargetSpecification_TargetType
130147
if len(tableDesc.GetFamilies()) == 1 {
131148
tableType = jobspb.ChangefeedTargetSpecification_PRIMARY_FAMILY_ONLY

pkg/ccl/changefeedccl/changefeed_stmt.go

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
4747
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgnotice"
4848
"github.com/cockroachdb/cockroach/pkg/sql/sem/asof"
49+
"github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants"
4950
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
5051
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
5152
"github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb"
@@ -65,6 +66,7 @@ import (
6566
"github.com/cockroachdb/cockroach/pkg/util/uuid"
6667
"github.com/cockroachdb/errors"
6768
"github.com/cockroachdb/redact"
69+
pbtypes "github.com/gogo/protobuf/types"
6870
)
6971

7072
// featureChangefeedEnabled is used to enable and disable the CHANGEFEED feature.
@@ -631,11 +633,22 @@ func createChangefeedJobRecord(
631633
if len(targetDatabaseDescs) == 0 || len(targetDatabaseDescs) > 1 {
632634
return nil, changefeedbase.Targets{}, errors.Errorf("changefeed only supports one database target")
633635
}
634-
if targetDatabaseDescs[0].GetID() == keys.SystemDatabaseID {
636+
targetDatabaseDesc := targetDatabaseDescs[0]
637+
if targetDatabaseDesc.GetID() == keys.SystemDatabaseID {
635638
return nil, changefeedbase.Targets{}, errors.Errorf("changefeed cannot target the system database")
636639
}
640+
if changefeedStmt.FilterOption != nil {
641+
fqTableNames, err := getFullyQualifiedTableNames(
642+
targetDatabaseDesc.GetName(), changefeedStmt.FilterOption.Tables,
643+
)
644+
if err != nil {
645+
return nil, changefeedbase.Targets{}, err
646+
}
647+
changefeedStmt.FilterOption.Tables = fqTableNames
648+
}
649+
targetSpec := getDatabaseTargetSpec(targetDatabaseDesc, changefeedStmt.FilterOption)
637650
details = jobspb.ChangefeedDetails{
638-
TargetSpecifications: getDatabaseTargets(targetDatabaseDescs),
651+
TargetSpecifications: []jobspb.ChangefeedTargetSpecification{targetSpec},
639652
SinkURI: sinkURI,
640653
StatementTime: statementTime,
641654
EndTime: endTime,
@@ -1144,19 +1157,53 @@ func getTargetsAndTables(
11441157
return targets, tables, nil
11451158
}
11461159

1147-
func getDatabaseTargets(
1148-
targetDatabaseDescs []catalog.DatabaseDescriptor,
1149-
) []jobspb.ChangefeedTargetSpecification {
1150-
targets := make([]jobspb.ChangefeedTargetSpecification, len(targetDatabaseDescs))
1160+
func getDatabaseTargetSpec(
1161+
targetDatabaseDesc catalog.DatabaseDescriptor, filterOpt *tree.ChangefeedFilterOption,
1162+
) jobspb.ChangefeedTargetSpecification {
1163+
target := jobspb.ChangefeedTargetSpecification{
1164+
DescID: targetDatabaseDesc.GetID(),
1165+
Type: jobspb.ChangefeedTargetSpecification_DATABASE,
1166+
StatementTimeName: targetDatabaseDesc.GetName(),
1167+
}
1168+
if filterOpt != nil {
1169+
filterTables := make(map[string]pbtypes.Empty)
1170+
for _, table := range filterOpt.Tables {
1171+
filterTables[table.FQString()] = pbtypes.Empty{}
1172+
}
1173+
target.FilterList = &jobspb.FilterList{
1174+
FilterType: jobspb.FilterList_FilterType(filterOpt.FilterType),
1175+
Tables: filterTables,
1176+
}
1177+
}
1178+
return target
1179+
}
11511180

1152-
for i, desc := range targetDatabaseDescs {
1153-
targets[i] = jobspb.ChangefeedTargetSpecification{
1154-
DescID: desc.GetID(),
1155-
Type: jobspb.ChangefeedTargetSpecification_DATABASE,
1156-
StatementTimeName: desc.GetName(),
1181+
func getFullyQualifiedTableNames(
1182+
targetDatabase string, tableNames tree.TableNames,
1183+
) (tree.TableNames, error) {
1184+
var fqTableNames tree.TableNames
1185+
1186+
for _, tableName := range tableNames {
1187+
if tableName.SchemaName == "" {
1188+
// The table name is non-qualified e.g. foo. This will resolve to <targetDatabase>.public.foo.
1189+
tableName.SchemaName = catconstants.PublicSchemaName
1190+
tableName.CatalogName = tree.Name(targetDatabase)
1191+
} else if tableName.CatalogName == "" {
1192+
// The table name is partially qualified e.g. foo.bar. This will resolve to
1193+
// <targetDatabase>.foo.bar.
1194+
tableName.CatalogName = tree.Name(targetDatabase)
1195+
} else {
1196+
// Table name is fully qualfied e.g. foo.bar.fizz. This will resolve to
1197+
// foo.bar.fizz unless foo != <targetDatabase>, in which case it would fail.
1198+
if tableName.CatalogName != tree.Name(targetDatabase) {
1199+
return nil, errors.AssertionFailedf(
1200+
"table %q must be in target database %q", tableName.FQString(), targetDatabase,
1201+
)
1202+
}
11571203
}
1204+
fqTableNames = append(fqTableNames, tableName)
11581205
}
1159-
return targets
1206+
return fqTableNames, nil
11601207
}
11611208

11621209
func validateSink(

0 commit comments

Comments
 (0)