Skip to content

Commit 39c8068

Browse files
craig[bot]yuzefovich
craig[bot]
andcommitted
Merge #65516
65516: sql: fix panic in CTAS with some virtual tables r=yuzefovich a=yuzefovich CTAS creates a fake planner that doesn't have `sqlStatsCollector` set (which lives on the `connExecutor`), so the usage of several virtual tables in CTAS would previously lead to a crash. The proper fix doesn't appear to be easy, so this commit prohibits the usage of those virtual tables in CTAS context. Fixes: #65512. Release note (bug fix): CockroachDB would previously crash when attempting to create a table using CREATE TABLE ... AS syntax where AS part selects from `crdb_internal.node_statement_statistics`, `crdb_internal.node_transaction_statistics`, or `crdb_internal.node_txn_stats` virtual tables. Co-authored-by: Yahor Yuzefovich <[email protected]>
2 parents 074841d + 03ca31b commit 39c8068

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

pkg/sql/crdb_internal.go

+19-12
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,16 @@ func execStatVar(count int64, n roachpb.NumericStat) tree.Datum {
836836
return tree.NewDFloat(tree.DFloat(n.GetVariance(count)))
837837
}
838838

839+
// getSQLStats retrieves a sqlStats object from the planner or returns an error
840+
// if not available. virtualTableName specifies the virtual table for which this
841+
// sqlStats object is needed.
842+
func getSQLStats(p *planner, virtualTableName string) (*sqlStats, error) {
843+
if p.extendedEvalCtx.sqlStatsCollector == nil || p.extendedEvalCtx.sqlStatsCollector.sqlStats == nil {
844+
return nil, errors.Newf("%s cannot be used in CREATE TABLE AS", virtualTableName)
845+
}
846+
return p.extendedEvalCtx.sqlStatsCollector.sqlStats, nil
847+
}
848+
839849
var crdbInternalStmtStatsTable = virtualSchemaTable{
840850
comment: `statement statistics (in-memory, not durable; local node only). ` +
841851
`This table is wiped periodically (by default, at least every two hours)`,
@@ -890,10 +900,9 @@ CREATE TABLE crdb_internal.node_statement_statistics (
890900
"user %s does not have %s privilege", p.User(), roleoption.VIEWACTIVITY)
891901
}
892902

893-
sqlStats := p.extendedEvalCtx.sqlStatsCollector.sqlStats
894-
if sqlStats == nil {
895-
return errors.AssertionFailedf(
896-
"cannot access sql statistics from this context")
903+
sqlStats, err := getSQLStats(p, "crdb_internal.node_statement_statistics")
904+
if err != nil {
905+
return err
897906
}
898907

899908
nodeID, _ := p.execCfg.NodeID.OptionalNodeID() // zero if not available
@@ -1045,10 +1054,9 @@ CREATE TABLE crdb_internal.node_transaction_statistics (
10451054
return pgerror.Newf(pgcode.InsufficientPrivilege,
10461055
"user %s does not have %s privilege", p.User(), roleoption.VIEWACTIVITY)
10471056
}
1048-
sqlStats := p.extendedEvalCtx.sqlStatsCollector.sqlStats
1049-
if sqlStats == nil {
1050-
return errors.AssertionFailedf(
1051-
"cannot access sql statistics from this context")
1057+
sqlStats, err := getSQLStats(p, "crdb_internal.node_transaction_statistics")
1058+
if err != nil {
1059+
return err
10521060
}
10531061

10541062
nodeID, _ := p.execCfg.NodeID.OptionalNodeID() // zero if not available
@@ -1154,10 +1162,9 @@ CREATE TABLE crdb_internal.node_txn_stats (
11541162
return err
11551163
}
11561164

1157-
sqlStats := p.extendedEvalCtx.sqlStatsCollector.sqlStats
1158-
if sqlStats == nil {
1159-
return errors.AssertionFailedf(
1160-
"cannot access sql statistics from this context")
1165+
sqlStats, err := getSQLStats(p, "crdb_internal.node_txn_stats")
1166+
if err != nil {
1167+
return err
11611168
}
11621169

11631170
nodeID, _ := p.execCfg.NodeID.OptionalNodeID() // zero if not available

pkg/sql/logictest/testdata/logic_test/create_table

+12
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,15 @@ CREATE TABLE error (a INT, b INT, INDEX idx (a), UNIQUE INDEX idx (b))
430430

431431
statement error pgcode 42P07 duplicate index name: \"idx\"
432432
CREATE TABLE error (a INT, b INT, UNIQUE INDEX idx (a), UNIQUE INDEX idx (b))
433+
434+
# Regression test for using some virtual tables in CREATE TABLE AS which is not
435+
# supported at the moment (#65512).
436+
437+
query error crdb_internal.node_statement_statistics cannot be used in CREATE TABLE AS
438+
CREATE TABLE ctas AS (SELECT * FROM crdb_internal.node_statement_statistics);
439+
440+
query error crdb_internal.node_transaction_statistics cannot be used in CREATE TABLE AS
441+
CREATE TABLE ctas AS (SELECT * FROM crdb_internal.node_transaction_statistics);
442+
443+
query error crdb_internal.node_txn_stats cannot be used in CREATE TABLE AS
444+
CREATE TABLE ctas AS (SELECT * FROM crdb_internal.node_txn_stats);

0 commit comments

Comments
 (0)