github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/delegate/show_partitions.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package delegate 12 13 import ( 14 "fmt" 15 16 "github.com/cockroachdb/cockroach/pkg/sql/lex" 17 "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" 18 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 19 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 20 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 21 "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" 22 "github.com/cockroachdb/errors" 23 ) 24 25 func (d *delegator) delegateShowPartitions(n *tree.ShowPartitions) (tree.Statement, error) { 26 sqltelemetry.IncrementShowCounter(sqltelemetry.Partitions) 27 if n.IsTable { 28 flags := cat.Flags{AvoidDescriptorCaches: true, NoTableStats: true} 29 tn := n.Table.ToTableName() 30 31 dataSource, resName, err := d.catalog.ResolveDataSource(d.ctx, flags, &tn) 32 if err != nil { 33 return nil, err 34 } 35 if err := d.catalog.CheckAnyPrivilege(d.ctx, dataSource); err != nil { 36 return nil, err 37 } 38 39 // We use the raw_config_sql from the partition_lookup result to get the 40 // official zone config for the partition, and use the full_config_sql from the zones table 41 // which is the result of looking up the partition's inherited zone configuraion. 42 const showTablePartitionsQuery = ` 43 SELECT 44 tables.database_name, 45 tables.name AS table_name, 46 partitions.name AS partition_name, 47 partitions.parent_name AS parent_partition, 48 partitions.column_names, 49 concat(tables.name, '@', table_indexes.index_name) AS index_name, 50 coalesce(partitions.list_value, partitions.range_value) as partition_value, 51 replace(regexp_extract(partition_lookup.raw_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as zone_config, 52 replace(regexp_extract(zones.full_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as full_zone_config 53 FROM 54 %[3]s.crdb_internal.partitions 55 JOIN %[3]s.crdb_internal.tables ON partitions.table_id = tables.table_id 56 JOIN %[3]s.crdb_internal.table_indexes ON 57 table_indexes.descriptor_id = tables.table_id 58 AND table_indexes.index_id = partitions.index_id 59 LEFT JOIN %[3]s.crdb_internal.zones ON 60 partitions.zone_id = zones.zone_id 61 AND partitions.subzone_id = zones.subzone_id 62 LEFT JOIN %[3]s.crdb_internal.zones AS partition_lookup ON 63 partition_lookup.database_name = tables.database_name 64 AND partition_lookup.table_name = tables.name 65 AND partition_lookup.index_name = table_indexes.index_name 66 AND partition_lookup.partition_name = partitions.name 67 WHERE 68 tables.name = %[1]s AND tables.database_name = %[2]s; 69 ` 70 return parse(fmt.Sprintf(showTablePartitionsQuery, 71 lex.EscapeSQLString(resName.Table()), 72 lex.EscapeSQLString(resName.Catalog()), 73 resName.CatalogName.String())) 74 } else if n.IsDB { 75 const showDatabasePartitionsQuery = ` 76 SELECT 77 tables.database_name, 78 tables.name AS table_name, 79 partitions.name AS partition_name, 80 partitions.parent_name AS parent_partition, 81 partitions.column_names, 82 concat(tables.name, '@', table_indexes.index_name) AS index_name, 83 coalesce(partitions.list_value, partitions.range_value) as partition_value, 84 replace(regexp_extract(partition_lookup.raw_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as zone_config, 85 replace(regexp_extract(zones.full_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as full_zone_config 86 FROM 87 %[1]s.crdb_internal.partitions 88 JOIN %[1]s.crdb_internal.tables ON partitions.table_id = tables.table_id 89 JOIN %[1]s.crdb_internal.table_indexes ON 90 table_indexes.descriptor_id = tables.table_id 91 AND table_indexes.index_id = partitions.index_id 92 LEFT JOIN %[1]s.crdb_internal.zones ON 93 partitions.zone_id = zones.zone_id 94 AND partitions.subzone_id = zones.subzone_id 95 LEFT JOIN %[1]s.crdb_internal.zones AS partition_lookup ON 96 partition_lookup.database_name = tables.database_name 97 AND partition_lookup.table_name = tables.name 98 AND partition_lookup.index_name = table_indexes.index_name 99 AND partition_lookup.partition_name = partitions.name 100 WHERE 101 tables.database_name = %[2]s 102 ORDER BY 103 tables.name, partitions.name; 104 ` 105 // Note: n.Database.String() != string(n.Database) 106 return parse(fmt.Sprintf(showDatabasePartitionsQuery, n.Database.String(), lex.EscapeSQLString(string(n.Database)))) 107 } 108 109 flags := cat.Flags{AvoidDescriptorCaches: true, NoTableStats: true} 110 tn := n.Index.Table 111 112 // Throw a more descriptive error if the user did not use the index hint syntax. 113 if tn.ObjectName == "" { 114 err := errors.New("no table specified") 115 err = pgerror.WithCandidateCode(err, pgcode.InvalidParameterValue) 116 err = errors.WithHint(err, "Specify a table using the hint syntax of table@index") 117 return nil, err 118 } 119 120 dataSource, resName, err := d.catalog.ResolveDataSource(d.ctx, flags, &tn) 121 if err != nil { 122 return nil, err 123 } 124 125 if err := d.catalog.CheckAnyPrivilege(d.ctx, dataSource); err != nil { 126 return nil, err 127 } 128 129 // Force resolution of the index. 130 _, _, err = cat.ResolveTableIndex(d.ctx, d.catalog, flags, &n.Index) 131 if err != nil { 132 return nil, err 133 } 134 135 const showIndexPartitionsQuery = ` 136 SELECT 137 tables.database_name, 138 tables.name AS table_name, 139 partitions.name AS partition_name, 140 partitions.parent_name AS parent_partition, 141 partitions.column_names, 142 concat(tables.name, '@', table_indexes.index_name) AS index_name, 143 coalesce(partitions.list_value, partitions.range_value) as partition_value, 144 replace(regexp_extract(partition_lookup.raw_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as zone_config, 145 replace(regexp_extract(zones.full_config_sql, 'CONFIGURE ZONE USING\n((?s:.)*)'), e'\t', '') as full_zone_config 146 FROM 147 %[5]s.crdb_internal.partitions 148 JOIN %[5]s.crdb_internal.table_indexes ON 149 partitions.index_id = table_indexes.index_id 150 AND partitions.table_id = table_indexes.descriptor_id 151 JOIN %[5]s.crdb_internal.tables ON table_indexes.descriptor_id = tables.table_id 152 LEFT JOIN %[5]s.crdb_internal.zones ON 153 partitions.zone_id = zones.zone_id 154 AND partitions.subzone_id = zones.subzone_id 155 LEFT JOIN %[5]s.crdb_internal.zones AS partition_lookup ON 156 partition_lookup.database_name = tables.database_name 157 AND partition_lookup.table_name = tables.name 158 AND partition_lookup.index_name = table_indexes.index_name 159 AND partition_lookup.partition_name = partitions.name 160 WHERE 161 table_indexes.index_name = %[1]s AND tables.name = %[2]s; 162 ` 163 return parse(fmt.Sprintf(showIndexPartitionsQuery, 164 lex.EscapeSQLString(n.Index.Index.String()), 165 lex.EscapeSQLString(resName.Table()), 166 resName.Table(), 167 n.Index.Index.String(), 168 // note: CatalogName.String() != Catalog() 169 resName.CatalogName.String())) 170 }