Skip to content

Commit

Permalink
sql: Fixing show partitions and show ranges to work on not current da…
Browse files Browse the repository at this point in the history
…tabase

show partitions and show ranges did not work correctly when the database
the object was within was not the current database. This PR updates show
partitions and show ranges to fix this and adds regression tests.

Fixes #40448.

Release note: None
  • Loading branch information
rohany authored and Rohan Yadav committed Sep 10, 2019
1 parent ba30aa9 commit 7af579c
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 34 deletions.
64 changes: 64 additions & 0 deletions pkg/ccl/logictestccl/testdata/logic_test/partitioning
Original file line number Diff line number Diff line change
Expand Up @@ -859,3 +859,67 @@ CREATE TABLE t (a INT PRIMARY KEY, b INT, INDEX (b)) PARTITION BY LIST (a) (

statement ok
RESET sql_safe_updates

# regression tests for #40450
statement ok
CREATE DATABASE d_show_partitions

statement ok
CREATE TABLE d_show_partitions.t (x INT PRIMARY KEY) PARTITION BY LIST (x) ( PARTITION p1 VALUES IN (1))

query TTTTTTTT
SHOW PARTITIONS FROM DATABASE d_show_partitions
----
d_show_partitions t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM TABLE d_show_partitions.t
----
d_show_partitions t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM INDEX d_show_partitions.t@primary
----
d_show_partitions t p1 NULL x t@primary (1) NULL

statement ok
CREATE DATABASE "show partitions"

statement ok
CREATE TABLE "show partitions".t (x INT PRIMARY KEY) PARTITION BY LIST (x) ( PARTITION p1 VALUES IN (1))

query TTTTTTTT
SHOW PARTITIONS FROM DATABASE "show partitions"
----
show partitions t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM TABLE "show partitions".t
----
show partitions t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM INDEX "show partitions".t@primary
----
show partitions t p1 NULL x t@primary (1) NULL

statement ok
CREATE DATABASE """"

statement ok
CREATE TABLE """".t (x INT PRIMARY KEY) PARTITION BY LIST (x) ( PARTITION p1 VALUES IN (1))

query TTTTTTTT
SHOW PARTITIONS FROM DATABASE """"
----
" t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM TABLE """".t
----
" t p1 NULL x t@primary (1) NULL

query TTTTTTTT
SHOW PARTITIONS FROM INDEX """".t@primary
----
" t p1 NULL x t@primary (1) NULL
30 changes: 18 additions & 12 deletions pkg/sql/delegate/show_partitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,23 @@ func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Stateme
coalesce(partitions.list_value, partitions.range_value) as partition_value,
replace(regexp_extract(config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as zone_config
FROM
crdb_internal.partitions
JOIN crdb_internal.tables ON partitions.table_id = tables.table_id
JOIN crdb_internal.table_indexes ON
%[3]s.crdb_internal.partitions
JOIN %[3]s.crdb_internal.tables ON partitions.table_id = tables.table_id
JOIN %[3]s.crdb_internal.table_indexes ON
table_indexes.descriptor_id = tables.table_id
AND table_indexes.index_id = partitions.index_id
LEFT JOIN crdb_internal.zones ON
LEFT JOIN %[3]s.crdb_internal.zones ON
zones.database_name = tables.database_name
AND zones.table_name = tables.name
AND zones.index_name = table_indexes.index_name
AND zones.partition_name = partitions.name
WHERE
tables.name = %[1]s AND tables.database_name = %[2]s;
`
return parse(fmt.Sprintf(showTablePartitionsQuery, lex.EscapeSQLString(resName.Table()), lex.EscapeSQLString(resName.Catalog())))
return parse(fmt.Sprintf(showTablePartitionsQuery,
lex.EscapeSQLString(resName.Table()),
lex.EscapeSQLString(resName.Catalog()),
resName.CatalogName.String()))
} else if n.IsDB {
const showDatabasePartitionsQuery = `
SELECT
Expand Down Expand Up @@ -86,7 +89,8 @@ func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Stateme
ORDER BY
tables.name, partitions.name;
`
return parse(fmt.Sprintf(showDatabasePartitionsQuery, n.Object, lex.EscapeSQLString(n.Object)))
// Note: n.Database.String() != string(n.Database)
return parse(fmt.Sprintf(showDatabasePartitionsQuery, n.Database.String(), lex.EscapeSQLString(string(n.Database))))
}

flags := cat.Flags{AvoidDescriptorCaches: true, NoTableStats: true}
Expand All @@ -112,7 +116,7 @@ func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Stateme
// is a dirty hack that needs to be fixed.
const showIndexPartitionsQuery = `
WITH
dummy AS (SELECT * FROM %[3]s@%[4]s LIMIT 0)
dummy AS (SELECT * FROM %[5]s.%[3]s@%[4]s LIMIT 0)
SELECT
tables.database_name,
tables.name AS table_name,
Expand All @@ -123,12 +127,12 @@ func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Stateme
coalesce(partitions.list_value, partitions.range_value) as partition_value,
replace(regexp_extract(config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as zone_config
FROM
crdb_internal.partitions
JOIN crdb_internal.table_indexes ON
%[5]s.crdb_internal.partitions
JOIN %[5]s.crdb_internal.table_indexes ON
partitions.index_id = table_indexes.index_id
AND partitions.table_id = table_indexes.descriptor_id
JOIN crdb_internal.tables ON table_indexes.descriptor_id = tables.table_id
LEFT JOIN crdb_internal.zones ON
JOIN %[5]s.crdb_internal.tables ON table_indexes.descriptor_id = tables.table_id
LEFT JOIN %[5]s.crdb_internal.zones ON
zones.database_name = tables.database_name
AND zones.table_name = tables.name
AND zones.index_name = table_indexes.index_name
Expand All @@ -140,5 +144,7 @@ func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Stateme
lex.EscapeSQLString(n.Index.Index.String()),
lex.EscapeSQLString(resName.Table()),
resName.Table(),
n.Index.Index.String()))
n.Index.Index.String(),
// note: CatalogName.String() != Catalog()
resName.CatalogName.String()))
}
19 changes: 10 additions & 9 deletions pkg/sql/delegate/show_ranges.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ func (d *delegator) delegateShowRanges(n *tree.ShowRanges) (tree.Statement, erro
WHERE database_name=%[2]s
ORDER BY table_name, r.start_key
`
return parse(fmt.Sprintf(dbQuery, n.DatabaseName, lex.EscapeSQLString(n.DatabaseName)))
// Note: n.DatabaseName.String() != string(n.DatabaseName)
return parse(fmt.Sprintf(dbQuery, n.DatabaseName.String(), lex.EscapeSQLString(string(n.DatabaseName))))
}

idx, _, err := cat.ResolveTableIndex(
idx, resName, err := cat.ResolveTableIndex(
d.ctx, d.catalog, cat.Flags{AvoidDescriptorCaches: true}, &n.TableOrIndex,
)
if err != nil {
Expand All @@ -69,19 +70,19 @@ func (d *delegator) delegateShowRanges(n *tree.ShowRanges) (tree.Statement, erro
endKey := hex.EncodeToString([]byte(span.EndKey))
return parse(fmt.Sprintf(`
SELECT
CASE WHEN r.start_key <= x'%s' THEN NULL ELSE crdb_internal.pretty_key(r.start_key, 2) END AS start_key,
CASE WHEN r.end_key >= x'%s' THEN NULL ELSE crdb_internal.pretty_key(r.end_key, 2) END AS end_key,
CASE WHEN r.start_key <= x'%[1]s' THEN NULL ELSE crdb_internal.pretty_key(r.start_key, 2) END AS start_key,
CASE WHEN r.end_key >= x'%[2]s' THEN NULL ELSE crdb_internal.pretty_key(r.end_key, 2) END AS end_key,
range_id,
range_size / 1000000 as range_size_mb,
lease_holder,
gossip_nodes.locality as lease_holder_locality,
replicas,
replica_localities
FROM crdb_internal.ranges AS r
LEFT JOIN crdb_internal.gossip_nodes ON lease_holder = node_id
WHERE (r.start_key < x'%s')
AND (r.end_key > x'%s') ORDER BY r.start_key
FROM %[3]s.crdb_internal.ranges AS r
LEFT JOIN %[3]s.crdb_internal.gossip_nodes ON lease_holder = node_id
WHERE (r.start_key < x'%[2]s')
AND (r.end_key > x'%[1]s') ORDER BY r.start_key
`,
startKey, endKey, endKey, startKey,
startKey, endKey, resName.CatalogName.String(), // note: CatalogName.String() != Catalog()
))
}
46 changes: 45 additions & 1 deletion pkg/sql/logictest/testdata/logic_test/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ CREATE INDEX idx on t1(v1,v2,v3) INTERLEAVE IN PARENT t(v1,v2)

# We expect the splits for the index to be the same as the splits for t.
query TTTI colnames,rowsort
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX t1@idx]
SELECT start_key, end_key, replicas, lease_holder FROM [SHOW RANGES FROM INDEX t1@idx]
----
start_key end_key replicas lease_holder
NULL /1 {1} 1
Expand Down Expand Up @@ -364,3 +364,47 @@ start_key start_pretty end_key
[196 137 246 123] /Table/60/1/123 Ċ /Table/60/2 d c · {1} 1
Ċ /Table/60/2 [196 138 136] /Table/60/2/0 d c c_i_idx {1} 1
[196 138 136] /Table/60/2/0 [255 255] /Max d c c_i_idx {1} 1


# Due to asynchronous splitting of ranges, we cannot guarantee the output
# of the show ranges from database command. The test below just ensures that
# the command gets parsed and evaluated correctly.

# regression tests for #40450
statement ok
CREATE DATABASE "show ranges"

statement ok
CREATE TABLE "show ranges".t (x INT PRIMARY KEY)

statement ok
SHOW RANGES FROM DATABASE "show ranges"

query TT
SELECT start_key, end_key FROM [SHOW RANGES FROM TABLE "show ranges".t]
----
NULL NULL

query TT
SELECT start_key, end_key FROM [SHOW RANGES FROM INDEX "show ranges".t@primary]
----
NULL NULL

statement ok
CREATE DATABASE """"

statement ok
CREATE TABLE """".t (x INT PRIMARY KEY)

statement ok
SHOW RANGES FROM DATABASE """"

query TT
SELECT start_key, end_key FROM [SHOW RANGES FROM TABLE """".t]
----
NULL NULL

query TT
SELECT start_key, end_key FROM [SHOW RANGES FROM INDEX """".t@primary]
----
NULL NULL
8 changes: 4 additions & 4 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -3445,15 +3445,15 @@ show_columns_stmt:
show_partitions_stmt:
SHOW PARTITIONS FROM TABLE table_name
{
$$.val = &tree.ShowPartitions{Object: $5.unresolvedObjectName().String(), IsTable: true, Table: $5.unresolvedObjectName()}
$$.val = &tree.ShowPartitions{IsTable: true, Table: $5.unresolvedObjectName()}
}
| SHOW PARTITIONS FROM DATABASE database_name
{
$$.val = &tree.ShowPartitions{Object: $5, IsDB: true}
$$.val = &tree.ShowPartitions{IsDB: true, Database: tree.Name($5)}
}
| SHOW PARTITIONS FROM INDEX table_index_name
{
$$.val = &tree.ShowPartitions{Object: $5.newTableIndexName().String(), IsIndex: true, Index: $5.tableIndexName()}
$$.val = &tree.ShowPartitions{IsIndex: true, Index: $5.tableIndexName()}
}
| SHOW PARTITIONS error // SHOW HELP: SHOW PARTITIONS

Expand Down Expand Up @@ -3854,7 +3854,7 @@ show_ranges_stmt:
}
| SHOW RANGES FROM DATABASE database_name
{
$$.val = &tree.ShowRanges{DatabaseName: $5}
$$.val = &tree.ShowRanges{DatabaseName: tree.Name($5)}
}
| SHOW RANGES error // SHOW HELP: SHOW RANGES

Expand Down
18 changes: 10 additions & 8 deletions pkg/sql/sem/tree/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,15 @@ func (node *ShowRoles) Format(ctx *FmtCtx) {
// ShowRanges represents a SHOW RANGES statement.
type ShowRanges struct {
TableOrIndex TableIndexName
DatabaseName string
DatabaseName Name
}

// Format implements the NodeFormatter interface.
func (node *ShowRanges) Format(ctx *FmtCtx) {
ctx.WriteString("SHOW RANGES FROM ")
if node.DatabaseName != "" {
ctx.WriteString("DATABASE ")
ctx.WriteString(node.DatabaseName)
ctx.FormatNode(&node.DatabaseName)
} else if node.TableOrIndex.Index != "" {
ctx.WriteString("INDEX ")
ctx.FormatNode(&node.TableOrIndex)
Expand Down Expand Up @@ -450,9 +450,8 @@ func (node *ShowHistogram) Format(ctx *FmtCtx) {

// ShowPartitions represents a SHOW PARTITIONS statement.
type ShowPartitions struct {
Object string

IsDB bool
IsDB bool
Database Name

IsIndex bool
Index TableIndexName
Expand All @@ -464,10 +463,13 @@ type ShowPartitions struct {
// Format implements the NodeFormatter interface.
func (node *ShowPartitions) Format(ctx *FmtCtx) {
if node.IsDB {
ctx.Printf("SHOW PARTITIONS FROM DATABASE %s", node.Object)
ctx.Printf("SHOW PARTITIONS FROM DATABASE ")
ctx.FormatNode(&node.Database)
} else if node.IsIndex {
ctx.Printf("SHOW PARTITIONS FROM INDEX %s", node.Object)
ctx.Printf("SHOW PARTITIONS FROM INDEX ")
ctx.FormatNode(&node.Index)
} else {
ctx.Printf("SHOW PARTITIONS FROM TABLE %s", node.Object)
ctx.Printf("SHOW PARTITIONS FROM TABLE ")
ctx.FormatNode(node.Table)
}
}

0 comments on commit 7af579c

Please sign in to comment.