Skip to content

Commit 2b3a170

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 889f8fc commit 2b3a170

Some content is hidden

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

54 files changed

+924
-67
lines changed

pkg/backup/backup_test.go

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

3606+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=false)")
36063607
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
36073608
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
36083609
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
3610+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=true)")
36093611
sqlDB.Exec(t, `CREATE TABLE other.sometable AS SELECT * FROM data.sometable`)
36103612
sqlDB.Exec(t, `DROP TABLE data.sometable`)
36113613
sqlDB.Exec(t, `CREATE INDEX ON data.teller (name)`)
36123614
sqlDB.Exec(t, `INSERT INTO data.bank VALUES (2, 2), (4, 4)`)
36133615
sqlDB.Exec(t, `INSERT INTO data.teller VALUES (2, 'craig')`)
36143616
sqlDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts[6])
36153617

3618+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=false)")
36163619
sqlDB.Exec(t, `TRUNCATE TABLE data.bank`)
3620+
sqlDB.Exec(t, "ALTER TABLE data.bank SET (schema_locked=true)")
36173621
sqlDB.Exec(t, `INSERT INTO data.bank VALUES (2, 2), (4, 4)`)
36183622
sqlDB.Exec(t, `DROP TABLE other.sometable`)
36193623
sqlDB.QueryRow(t, `SELECT cluster_logical_timestamp()`).Scan(&ts[7])
@@ -5037,7 +5041,9 @@ func TestBackupRestoreIncrementalTruncateTable(t *testing.T) {
50375041
sqlDB.Exec(t, `INSERT INTO data.t VALUES ('before')`)
50385042
sqlDB.Exec(t, `BACKUP DATABASE data INTO $1`, full)
50395043
sqlDB.Exec(t, `UPDATE data.t SET s = 'after'`)
5044+
sqlDB.Exec(t, "ALTER TABLE data.t SET (schema_locked=false)")
50405045
sqlDB.Exec(t, `TRUNCATE data.t`)
5046+
sqlDB.Exec(t, "ALTER TABLE data.t SET (schema_locked=true)")
50415047

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

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
@@ -520,7 +520,9 @@ func TestSQLSink(t *testing.T) {
520520
sqlDB.CheckQueryResults(t, `SELECT key, value FROM sink ORDER BY PRIMARY KEY sink`,
521521
[][]string{{`k1`, `v0`}},
522522
)
523+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
523524
sqlDB.Exec(t, `TRUNCATE sink`)
525+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
524526

525527
// Verify the implicit flushing
526528
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`0`}})
@@ -532,7 +534,9 @@ func TestSQLSink(t *testing.T) {
532534
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`3`}})
533535
require.NoError(t, sink.Flush(ctx))
534536
sqlDB.CheckQueryResults(t, `SELECT count(*) FROM sink`, [][]string{{`4`}})
537+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
535538
sqlDB.Exec(t, `TRUNCATE sink`)
539+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
536540

537541
// Two tables interleaved in time
538542
var pool testAllocPool
@@ -544,7 +548,9 @@ func TestSQLSink(t *testing.T) {
544548
sqlDB.CheckQueryResults(t, `SELECT topic, key, value FROM sink ORDER BY PRIMARY KEY sink`,
545549
[][]string{{`bar`, `kbar`, `v0`}, {`foo`, `kfoo`, `v0`}, {`foo`, `kfoo`, `v1`}},
546550
)
551+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
547552
sqlDB.Exec(t, `TRUNCATE sink`)
553+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
548554

549555
// Multiple keys interleaved in time. Use sqlSinkNumPartitions+1 keys to
550556
// guarantee that at lease two of them end up in the same partition.
@@ -569,7 +575,9 @@ func TestSQLSink(t *testing.T) {
569575
{`2`, `v0`, `v1`},
570576
},
571577
)
578+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=false)`)
572579
sqlDB.Exec(t, `TRUNCATE sink`)
580+
sqlDB.Exec(t, `ALTER TABLE sink SET (schema_locked=true)`)
573581

574582
// Emit resolved
575583
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/server/application_api/metrics_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ func TestStoreProcedureCallStatementMetrics(t *testing.T) {
338338
)
339339

340340
_, err := db.Exec(`
341-
CREATE TABLE tbl (id SERIAL PRIMARY KEY, t text UNIQUE);
341+
CREATE TABLE tbl (id SERIAL PRIMARY KEY, t text UNIQUE) WITH (schema_locked=false);
342342
INSERT INTO tbl (t) VALUES ('d');`)
343343
require.NoError(t, err)
344344

@@ -529,7 +529,7 @@ func TestUDFStatementMetrics(t *testing.T) {
529529
)
530530

531531
_, err := db.Exec(`
532-
CREATE TABLE tbl (id SERIAL PRIMARY KEY, t text UNIQUE);
532+
CREATE TABLE tbl (id SERIAL PRIMARY KEY, t text UNIQUE) WITH (schema_locked=false);
533533
INSERT INTO tbl (t) VALUES ('d');`)
534534
require.NoError(t, err)
535535

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
}

0 commit comments

Comments
 (0)