Skip to content

Commit ab2abec

Browse files
committed
sql: enforce schema_locked for TRUNCATE
Previously, we were completely ignoring schema_locked for the TRUNCATE command, which could changefeeds to break. To address this, this patch blocks TRUNCATE on schema_locked tables. Fixes: #151941 Release note (bug fix): schema_locked was not enforced on the TRUNCATE command, which could cause changefeed jobs to fail.
1 parent f3b1122 commit ab2abec

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+912
-62
lines changed

pkg/backup/backup_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3589,17 +3589,21 @@ func TestRestoreAsOfSystemTime(t *testing.T) {
35893589
sqlDB.Exec(t, `ALTER TABLE data.bank ADD COLUMN points_balance INT DEFAULT 50`)
35903590
sqlDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts[5])
35913591

3592+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=false)")
35923593
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
35933594
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
35943595
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
3596+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=true)")
35953597
sqlDB.Exec(t, `CREATE TABLE other.sometable AS SELECT * FROM data.sometable`)
35963598
sqlDB.Exec(t, `DROP TABLE data.sometable`)
35973599
sqlDB.Exec(t, `CREATE INDEX ON data.teller (name)`)
35983600
sqlDB.Exec(t, `INSERT INTO data.bank VALUES (2, 2), (4, 4)`)
35993601
sqlDB.Exec(t, `INSERT INTO data.teller VALUES (2, 'craig')`)
36003602
sqlDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts[6])
36013603

3604+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=false)")
36023605
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
3606+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=true)")
36033607
sqlDB.Exec(t, `INSERT INTO data.bank VALUES (2, 2), (4, 4)`)
36043608
sqlDB.Exec(t, `DROP TABLE other.sometable`)
36053609
sqlDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts[7])
@@ -5023,7 +5027,9 @@ func TestBackupRestoreIncrementalTruncateTable(t *testing.T) {
50235027
sqlDB.Exec(t, `INSERT INTO data.t VALUES ('before')`)
50245028
sqlDB.Exec(t, `BACKUP DATABASE data INTO $1`, full)
50255029
sqlDB.Exec(t, `UPDATE data.t SET s = 'after'`)
5030+
sqlDB.Exec(t, "ALTER TABLE data.t SET (schema_locked=false)")
50265031
sqlDB.Exec(t, `TRUNCATE data.t`)
5032+
sqlDB.Exec(t, "ALTER TABLE data.t SET (schema_locked=true)")
50275033

50285034
sqlDB.Exec(t, "BACKUP DATABASE data INTO $1", full)
50295035
}

pkg/bench/rttanalysis/truncate_bench_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,36 @@ func init() {
1212
reg.Register("Truncate", []RoundTripBenchTestCase{
1313
{
1414
Name: "truncate 1 column 0 rows",
15-
Setup: "CREATE TABLE t(x INT);",
15+
Setup: "CREATE TABLE t(x INT) WITH (schema_locked=false);",
1616
Stmt: "TRUNCATE t",
1717
},
1818
{
1919
Name: "truncate 1 column 1 row",
20-
Setup: `CREATE TABLE t(x INT);
20+
Setup: `CREATE TABLE t(x INT) WITH (schema_locked=false);
2121
INSERT INTO t (x) VALUES (1);`,
2222
Stmt: "TRUNCATE t",
2323
},
2424
{
2525
Name: "truncate 1 column 2 rows",
26-
Setup: `CREATE TABLE t(x INT);
26+
Setup: `CREATE TABLE t(x INT) WITH (schema_locked=false);
2727
INSERT INTO t (x) VALUES (1);
2828
INSERT INTO t (x) VALUES (2);`,
2929
Stmt: "TRUNCATE t",
3030
},
3131
{
3232
Name: "truncate 2 column 0 rows",
33-
Setup: `CREATE TABLE t(x INT, y INT);`,
33+
Setup: `CREATE TABLE t(x INT, y INT) WITH (schema_locked=false);`,
3434
Stmt: "TRUNCATE t",
3535
},
3636
{
3737
Name: "truncate 2 column 1 rows",
38-
Setup: `CREATE TABLE t(x INT, y INT);
38+
Setup: `CREATE TABLE t(x INT, y INT) WITH (schema_locked=false);
3939
INSERT INTO t (x, y) VALUES (1, 1);`,
4040
Stmt: "TRUNCATE t",
4141
},
4242
{
4343
Name: "truncate 2 column 2 rows",
44-
Setup: `CREATE TABLE t(x INT, y INT);
44+
Setup: `CREATE TABLE t(x INT, y INT) WITH (schema_locked=false);
4545
INSERT INTO t (x, y) VALUES (1, 1);
4646
INSERT INTO t (x,y) VALUES (2, 2);`,
4747
Stmt: "TRUNCATE t",

pkg/ccl/changefeedccl/sink_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,9 @@ func TestSQLSink(t *testing.T) {
519519
sqlDB.CheckQueryResults(t, `SELECT key, value FROM sink ORDER BY PRIMARY KEY sink`,
520520
[][]string{{`k1`, `v0`}},
521521
)
522+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
522523
sqlDB.Exec(t, `TRUNCATE sink`)
524+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
523525

524526
// Verify the implicit flushing
525527
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`0`}})
@@ -531,7 +533,9 @@ func TestSQLSink(t *testing.T) {
531533
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`3`}})
532534
require.NoError(t, sink.Flush(ctx))
533535
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`4`}})
536+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
534537
sqlDB.Exec(t, `TRUNCATE sink`)
538+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
535539

536540
// Two tables interleaved in time
537541
var pool testAllocPool
@@ -543,7 +547,9 @@ func TestSQLSink(t *testing.T) {
543547
sqlDB.CheckQueryResults(t, `SELECT topic, key, value FROM sink ORDER BY PRIMARY KEY sink`,
544548
[][]string{{`bar`, `kbar`, `v0`}, {`foo`, `kfoo`, `v0`}, {`foo`, `kfoo`, `v1`}},
545549
)
550+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
546551
sqlDB.Exec(t, `TRUNCATE sink`)
552+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
547553

548554
// Multiple keys interleaved in time. Use sqlSinkNumPartitions+1 keys to
549555
// guarantee that at lease two of them end up in the same partition.
@@ -568,7 +574,9 @@ func TestSQLSink(t *testing.T) {
568574
{`2`, `v0`, `v1`},
569575
},
570576
)
577+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
571578
sqlDB.Exec(t, `TRUNCATE sink`)
579+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
572580

573581
// Emit resolved
574582
var e testEncoder

pkg/ccl/logictestccl/testdata/logic_test/partitioning

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,9 +1517,15 @@ bar CREATE TABLE public.bar (
15171517
gc.ttlseconds = 150;
15181518

15191519

1520+
statement ok
1521+
ALTER TABLE bar SET (schema_locked=false)
1522+
15201523
statement ok
15211524
TRUNCATE bar;
15221525

1526+
statement ok
1527+
ALTER TABLE bar RESET (schema_locked)
1528+
15231529
query TT
15241530
SHOW CREATE TABLE bar;
15251531
----

pkg/ccl/multiregionccl/unique_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,10 @@ CREATE TABLE u (
150150
r.Exec(t, `SELECT crdb_internal.revalidate_unique_constraint('u', 'u_v_key')`)
151151

152152
// Clean up.
153-
_, err = db.Exec(`TRUNCATE test.t`)
154-
require.NoError(t, err)
153+
r.Exec(t, `ALTER TABLE test.t SET (schema_locked=false)`)
154+
r.Exec(t, `TRUNCATE test.t`)
155+
r.Exec(t, `ALTER TABLE test.t SET (schema_locked=true)`)
156+
155157
})
156158

157159
t.Run("validate_implicitly_partitioned_primary_index", func(t *testing.T) {
@@ -192,8 +194,9 @@ CREATE TABLE u (
192194
r.Exec(t, `SELECT crdb_internal.revalidate_unique_constraint('u', 'u_v_key')`)
193195

194196
// Clean up.
195-
_, err = db.Exec(`TRUNCATE test.u`)
196-
require.NoError(t, err)
197+
r.Exec(t, `ALTER TABLE test.u SET (schema_locked=false)`)
198+
r.Exec(t, `TRUNCATE test.u`)
199+
r.Exec(t, `ALTER TABLE test.u SET (schema_locked=true)`)
197200
})
198201

199202
t.Run("validate_implicitly_partitioned_secondary_index", func(t *testing.T) {
@@ -234,8 +237,9 @@ CREATE TABLE u (
234237
r.Exec(t, `SELECT crdb_internal.revalidate_unique_constraint('u', 'u_pkey')`)
235238

236239
// Clean up.
237-
_, err = db.Exec(`TRUNCATE test.u`)
238-
require.NoError(t, err)
240+
r.Exec(t, `ALTER TABLE test.u SET (schema_locked=false)`)
241+
r.Exec(t, `TRUNCATE test.u`)
242+
r.Exec(t, `ALTER TABLE test.u SET (schema_locked=true)`)
239243
})
240244

241245
}

pkg/cli/interactive_tests/test_copy.tcl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ eexpect root@
1010
send "drop table if exists t;\r"
1111
eexpect "DROP TABLE"
1212
eexpect root@
13-
send "create table t (id INT PRIMARY KEY, t TEXT);\r"
13+
send "create table t (id INT PRIMARY KEY, t TEXT) WITH (schema_locked=false);\r"
1414
eexpect "CREATE TABLE"
1515
eexpect root@
1616

pkg/crosscluster/logical/logical_replication_job_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -797,15 +797,16 @@ func TestLogicalReplicationWithPhantomDelete(t *testing.T) {
797797
skip.UnderDeadlock(t)
798798
defer log.Scope(t).Close(t)
799799

800-
ctx := context.Background()
801-
802-
tc, s, serverASQL, serverBSQL := setupLogicalTestServer(t, ctx, testClusterBaseClusterArgs, 1)
803-
defer tc.Stopper().Stop(ctx)
804-
805-
serverAURL := replicationtestutils.GetExternalConnectionURI(t, s, s, serverutils.DBName("a"))
806-
807800
for _, mode := range []string{"validated", "immediate"} {
808801
t.Run(mode, func(t *testing.T) {
802+
ctx := context.Background()
803+
tc, s, serverASQL, serverBSQL := setupLogicalTestServer(t, ctx, testClusterBaseClusterArgs, 1)
804+
defer tc.Stopper().Stop(ctx)
805+
806+
serverAURL := replicationtestutils.GetExternalConnectionURI(t, s, s, serverutils.DBName("a"))
807+
serverASQL.Exec(t, "ALTER TABLE tab SET (schema_locked = false)")
808+
serverBSQL.Exec(t, "ALTER TABLE tab SET (schema_locked = false)")
809+
809810
serverASQL.Exec(t, "TRUNCATE tab")
810811
serverBSQL.Exec(t, "TRUNCATE tab")
811812
var jobBID jobspb.JobID

pkg/sql/comment_on_column_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestCommentOnColumn(t *testing.T) {
2626
if _, err := db.Exec(`
2727
CREATE DATABASE d;
2828
SET DATABASE = d;
29-
CREATE TABLE t (c1 INT, c2 INT, c3 INT);
29+
CREATE TABLE t (c1 INT, c2 INT, c3 INT) WITH (schema_locked=false);
3030
`); err != nil {
3131
t.Fatal(err)
3232
}

pkg/sql/comment_on_index_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestCommentOnIndex(t *testing.T) {
2222
if _, err := db.Exec(`
2323
CREATE DATABASE d;
2424
SET DATABASE = d;
25-
CREATE TABLE t (c INT, INDEX t_c_idx (c));
25+
CREATE TABLE t (c INT, INDEX t_c_idx (c)) WITH (schema_locked=false);
2626
`); err != nil {
2727
t.Fatal(err)
2828
}

pkg/sql/comment_on_table_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestCommentOnTable(t *testing.T) {
2222
if _, err := db.Exec(`
2323
CREATE DATABASE d;
2424
SET DATABASE = d;
25-
CREATE TABLE t (i INT );
25+
CREATE TABLE t (i INT ) WITH (schema_locked=false);
2626
`); err != nil {
2727
t.Fatal(err)
2828
}

0 commit comments

Comments
 (0)