github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/opt_catalog.go (about) 1 // Copyright 2018 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 sql 12 13 import ( 14 "context" 15 "math" 16 "time" 17 18 "github.com/cockroachdb/cockroach/pkg/config" 19 "github.com/cockroachdb/cockroach/pkg/config/zonepb" 20 "github.com/cockroachdb/cockroach/pkg/keys" 21 "github.com/cockroachdb/cockroach/pkg/kv" 22 "github.com/cockroachdb/cockroach/pkg/roachpb" 23 "github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver" 24 "github.com/cockroachdb/cockroach/pkg/sql/opt/cat" 25 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 26 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 27 "github.com/cockroachdb/cockroach/pkg/sql/privilege" 28 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 29 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 30 "github.com/cockroachdb/cockroach/pkg/sql/stats" 31 "github.com/cockroachdb/cockroach/pkg/sql/types" 32 "github.com/cockroachdb/cockroach/pkg/util" 33 "github.com/cockroachdb/errors" 34 ) 35 36 // optCatalog implements the cat.Catalog interface over the SchemaResolver 37 // interface for the use of the new optimizer. The interfaces are simplified to 38 // only include what the optimizer needs, and certain common lookups are cached 39 // for faster performance. 40 type optCatalog struct { 41 // planner needs to be set via a call to init before calling other methods. 42 planner *planner 43 44 // cfg is the gossiped and cached system config. It may be nil if the node 45 // does not yet have it available. 46 cfg *config.SystemConfig 47 48 // dataSources is a cache of table and view objects that's used to satisfy 49 // repeated calls for the same data source. 50 // Note that the data source object might still need to be recreated if 51 // something outside of the descriptor has changed (e.g. table stats). 52 dataSources map[*sqlbase.ImmutableTableDescriptor]cat.DataSource 53 54 // tn is a temporary name used during resolution to avoid heap allocation. 55 tn tree.TableName 56 } 57 58 var _ cat.Catalog = &optCatalog{} 59 60 // init initializes an optCatalog instance (which the caller can pre-allocate). 61 // The instance can be used across multiple queries, but reset() should be 62 // called for each query. 63 func (oc *optCatalog) init(planner *planner) { 64 oc.planner = planner 65 oc.dataSources = make(map[*sqlbase.ImmutableTableDescriptor]cat.DataSource) 66 } 67 68 // reset prepares the optCatalog to be used for a new query. 69 func (oc *optCatalog) reset() { 70 // If we have accumulated too many tables in our map, throw everything away. 71 // This deals with possible edge cases where we do a lot of DDL in a 72 // long-lived session. 73 if len(oc.dataSources) > 100 { 74 oc.dataSources = make(map[*sqlbase.ImmutableTableDescriptor]cat.DataSource) 75 } 76 77 oc.cfg = oc.planner.execCfg.Gossip.DeprecatedSystemConfig(47150) 78 } 79 80 // optSchema is a wrapper around sqlbase.DatabaseDescriptor that implements the 81 // cat.Object and cat.Schema interfaces. 82 type optSchema struct { 83 planner *planner 84 desc *sqlbase.DatabaseDescriptor 85 86 name cat.SchemaName 87 } 88 89 // ID is part of the cat.Object interface. 90 func (os *optSchema) ID() cat.StableID { 91 return cat.StableID(os.desc.ID) 92 } 93 94 // PostgresDescriptorID is part of the cat.Object interface. 95 func (os *optSchema) PostgresDescriptorID() cat.StableID { 96 return cat.StableID(os.desc.ID) 97 } 98 99 // Equals is part of the cat.Object interface. 100 func (os *optSchema) Equals(other cat.Object) bool { 101 otherSchema, ok := other.(*optSchema) 102 return ok && os.desc.ID == otherSchema.desc.ID 103 } 104 105 // Name is part of the cat.Schema interface. 106 func (os *optSchema) Name() *cat.SchemaName { 107 return &os.name 108 } 109 110 // GetDataSourceNames is part of the cat.Schema interface. 111 func (os *optSchema) GetDataSourceNames(ctx context.Context) ([]cat.DataSourceName, error) { 112 return resolver.GetObjectNames( 113 ctx, 114 os.planner.Txn(), 115 os.planner, 116 os.planner.ExecCfg().Codec, 117 os.desc, 118 os.name.Schema(), 119 true, /* explicitPrefix */ 120 ) 121 } 122 123 // ResolveSchema is part of the cat.Catalog interface. 124 func (oc *optCatalog) ResolveSchema( 125 ctx context.Context, flags cat.Flags, name *cat.SchemaName, 126 ) (cat.Schema, cat.SchemaName, error) { 127 if flags.AvoidDescriptorCaches { 128 defer func(prev bool) { 129 oc.planner.avoidCachedDescriptors = prev 130 }(oc.planner.avoidCachedDescriptors) 131 oc.planner.avoidCachedDescriptors = true 132 } 133 134 oc.tn.ObjectNamePrefix = *name 135 found, desc, err := oc.tn.ObjectNamePrefix.Resolve( 136 ctx, 137 oc.planner, 138 oc.planner.CurrentDatabase(), 139 oc.planner.CurrentSearchPath(), 140 ) 141 if err != nil { 142 return nil, cat.SchemaName{}, err 143 } 144 if !found { 145 if !name.ExplicitSchema && !name.ExplicitCatalog { 146 return nil, cat.SchemaName{}, pgerror.New( 147 pgcode.InvalidName, "no database specified", 148 ) 149 } 150 return nil, cat.SchemaName{}, pgerror.Newf( 151 pgcode.InvalidSchemaName, "target database or schema does not exist", 152 ) 153 } 154 return &optSchema{ 155 planner: oc.planner, 156 desc: desc.(*DatabaseDescriptor), 157 name: oc.tn.ObjectNamePrefix, 158 }, oc.tn.ObjectNamePrefix, nil 159 } 160 161 // ResolveDataSource is part of the cat.Catalog interface. 162 func (oc *optCatalog) ResolveDataSource( 163 ctx context.Context, flags cat.Flags, name *cat.DataSourceName, 164 ) (cat.DataSource, cat.DataSourceName, error) { 165 if flags.AvoidDescriptorCaches { 166 defer func(prev bool) { 167 oc.planner.avoidCachedDescriptors = prev 168 }(oc.planner.avoidCachedDescriptors) 169 oc.planner.avoidCachedDescriptors = true 170 } 171 172 oc.tn = *name 173 desc, err := resolver.ResolveExistingTableObject(ctx, oc.planner, &oc.tn, tree.ObjectLookupFlagsWithRequired(), resolver.ResolveAnyDescType) 174 if err != nil { 175 return nil, cat.DataSourceName{}, err 176 } 177 ds, err := oc.dataSourceForDesc(ctx, flags, desc, &oc.tn) 178 if err != nil { 179 return nil, cat.DataSourceName{}, err 180 } 181 return ds, oc.tn, nil 182 } 183 184 // ResolveDataSourceByID is part of the cat.Catalog interface. 185 func (oc *optCatalog) ResolveDataSourceByID( 186 ctx context.Context, flags cat.Flags, dataSourceID cat.StableID, 187 ) (_ cat.DataSource, isAdding bool, _ error) { 188 if flags.AvoidDescriptorCaches { 189 defer func(prev bool) { 190 oc.planner.avoidCachedDescriptors = prev 191 }(oc.planner.avoidCachedDescriptors) 192 oc.planner.avoidCachedDescriptors = true 193 } 194 195 tableLookup, err := oc.planner.LookupTableByID(ctx, sqlbase.ID(dataSourceID)) 196 197 if err != nil || tableLookup.IsAdding { 198 if errors.Is(err, sqlbase.ErrDescriptorNotFound) || tableLookup.IsAdding { 199 return nil, tableLookup.IsAdding, sqlbase.NewUndefinedRelationError(&tree.TableRef{TableID: int64(dataSourceID)}) 200 } 201 return nil, false, err 202 } 203 204 // The name is only used for virtual tables, which can't be looked up by ID. 205 ds, err := oc.dataSourceForDesc(ctx, cat.Flags{}, tableLookup.Desc, &tree.TableName{}) 206 return ds, false, err 207 } 208 209 func getDescForCatalogObject(o cat.Object) (sqlbase.DescriptorProto, error) { 210 switch t := o.(type) { 211 case *optSchema: 212 return t.desc, nil 213 case *optTable: 214 return t.desc, nil 215 case *optVirtualTable: 216 return t.desc, nil 217 case *optView: 218 return t.desc, nil 219 case *optSequence: 220 return t.desc, nil 221 default: 222 return nil, errors.AssertionFailedf("invalid object type: %T", o) 223 } 224 } 225 226 func getDescForDataSource(o cat.DataSource) (*sqlbase.ImmutableTableDescriptor, error) { 227 switch t := o.(type) { 228 case *optTable: 229 return t.desc, nil 230 case *optVirtualTable: 231 return t.desc, nil 232 case *optView: 233 return t.desc, nil 234 case *optSequence: 235 return t.desc, nil 236 default: 237 return nil, errors.AssertionFailedf("invalid object type: %T", o) 238 } 239 } 240 241 // CheckPrivilege is part of the cat.Catalog interface. 242 func (oc *optCatalog) CheckPrivilege(ctx context.Context, o cat.Object, priv privilege.Kind) error { 243 desc, err := getDescForCatalogObject(o) 244 if err != nil { 245 return err 246 } 247 return oc.planner.CheckPrivilege(ctx, desc, priv) 248 } 249 250 // CheckAnyPrivilege is part of the cat.Catalog interface. 251 func (oc *optCatalog) CheckAnyPrivilege(ctx context.Context, o cat.Object) error { 252 desc, err := getDescForCatalogObject(o) 253 if err != nil { 254 return err 255 } 256 return oc.planner.CheckAnyPrivilege(ctx, desc) 257 } 258 259 // HasAdminRole is part of the cat.Catalog interface. 260 func (oc *optCatalog) HasAdminRole(ctx context.Context) (bool, error) { 261 return oc.planner.HasAdminRole(ctx) 262 } 263 264 // RequireAdminRole is part of the cat.Catalog interface. 265 func (oc *optCatalog) RequireAdminRole(ctx context.Context, action string) error { 266 return oc.planner.RequireAdminRole(ctx, action) 267 } 268 269 // FullyQualifiedName is part of the cat.Catalog interface. 270 func (oc *optCatalog) FullyQualifiedName( 271 ctx context.Context, ds cat.DataSource, 272 ) (cat.DataSourceName, error) { 273 return oc.fullyQualifiedNameWithTxn(ctx, ds, oc.planner.Txn()) 274 } 275 276 func (oc *optCatalog) fullyQualifiedNameWithTxn( 277 ctx context.Context, ds cat.DataSource, txn *kv.Txn, 278 ) (cat.DataSourceName, error) { 279 if vt, ok := ds.(*optVirtualTable); ok { 280 // Virtual tables require special handling, because they can have multiple 281 // effective instances that utilize the same descriptor. 282 return vt.name, nil 283 } 284 285 desc, err := getDescForDataSource(ds) 286 if err != nil { 287 return cat.DataSourceName{}, err 288 } 289 290 dbID := desc.ParentID 291 dbDesc, err := sqlbase.GetDatabaseDescFromID(ctx, txn, oc.codec(), dbID) 292 if err != nil { 293 return cat.DataSourceName{}, err 294 } 295 return tree.MakeTableName(tree.Name(dbDesc.Name), tree.Name(desc.Name)), nil 296 } 297 298 // dataSourceForDesc returns a data source wrapper for the given descriptor. 299 // The wrapper might come from the cache, or it may be created now. 300 func (oc *optCatalog) dataSourceForDesc( 301 ctx context.Context, 302 flags cat.Flags, 303 desc *sqlbase.ImmutableTableDescriptor, 304 name *cat.DataSourceName, 305 ) (cat.DataSource, error) { 306 if desc.IsTable() { 307 // Tables require invalidation logic for cached wrappers. 308 return oc.dataSourceForTable(ctx, flags, desc, name) 309 } 310 311 ds, ok := oc.dataSources[desc] 312 if ok { 313 return ds, nil 314 } 315 316 switch { 317 case desc.IsView(): 318 ds = newOptView(desc) 319 320 case desc.IsSequence(): 321 ds = newOptSequence(desc) 322 323 default: 324 return nil, errors.AssertionFailedf("unexpected table descriptor: %+v", desc) 325 } 326 327 oc.dataSources[desc] = ds 328 return ds, nil 329 } 330 331 // dataSourceForTable returns a table data source wrapper for the given descriptor. 332 // The wrapper might come from the cache, or it may be created now. 333 func (oc *optCatalog) dataSourceForTable( 334 ctx context.Context, 335 flags cat.Flags, 336 desc *sqlbase.ImmutableTableDescriptor, 337 name *cat.DataSourceName, 338 ) (cat.DataSource, error) { 339 if desc.IsVirtualTable() { 340 // Virtual tables can have multiple effective instances that utilize the 341 // same descriptor, so we can't cache them (see the comment for 342 // optVirtualTable.id for more information). 343 return newOptVirtualTable(ctx, oc, desc, name) 344 } 345 346 // Even if we have a cached data source, we still have to cross-check that 347 // statistics and the zone config haven't changed. 348 var tableStats []*stats.TableStatistic 349 if !flags.NoTableStats { 350 var err error 351 tableStats, err = oc.planner.execCfg.TableStatsCache.GetTableStats(context.TODO(), desc.ID) 352 if err != nil { 353 // Ignore any error. We still want to be able to run queries even if we lose 354 // access to the statistics table. 355 // TODO(radu): at least log the error. 356 tableStats = nil 357 } 358 } 359 360 zoneConfig, err := oc.getZoneConfig(desc) 361 if err != nil { 362 return nil, err 363 } 364 365 // Check to see if there's already a data source wrapper for this descriptor, 366 // and it was created with the same stats and zone config. 367 if ds, ok := oc.dataSources[desc]; ok && !ds.(*optTable).isStale(tableStats, zoneConfig) { 368 return ds, nil 369 } 370 371 ds, err := newOptTable(desc, oc.codec(), tableStats, zoneConfig) 372 if err != nil { 373 return nil, err 374 } 375 oc.dataSources[desc] = ds 376 return ds, nil 377 } 378 379 var emptyZoneConfig = &zonepb.ZoneConfig{} 380 381 // getZoneConfig returns the ZoneConfig data structure for the given table. 382 // ZoneConfigs are stored in protobuf binary format in the SystemConfig, which 383 // is gossiped around the cluster. Note that the returned ZoneConfig might be 384 // somewhat stale, since it's taken from the gossiped SystemConfig. 385 func (oc *optCatalog) getZoneConfig( 386 desc *sqlbase.ImmutableTableDescriptor, 387 ) (*zonepb.ZoneConfig, error) { 388 // Lookup table's zone if system config is available (it may not be as node 389 // is starting up and before it's received the gossiped config). If it is 390 // not available, use an empty config that has no zone constraints. 391 if oc.cfg == nil || desc.IsVirtualTable() { 392 return emptyZoneConfig, nil 393 } 394 zone, err := oc.cfg.GetZoneConfigForObject(uint32(desc.ID)) 395 if err != nil { 396 return nil, err 397 } 398 if zone == nil { 399 // This can happen with tests that override the hook. 400 zone = emptyZoneConfig 401 } 402 return zone, err 403 } 404 405 func (oc *optCatalog) codec() keys.SQLCodec { 406 return oc.planner.ExecCfg().Codec 407 } 408 409 // optView is a wrapper around sqlbase.ImmutableTableDescriptor that implements 410 // the cat.Object, cat.DataSource, and cat.View interfaces. 411 type optView struct { 412 desc *sqlbase.ImmutableTableDescriptor 413 } 414 415 var _ cat.View = &optView{} 416 417 func newOptView(desc *sqlbase.ImmutableTableDescriptor) *optView { 418 return &optView{desc: desc} 419 } 420 421 // ID is part of the cat.Object interface. 422 func (ov *optView) ID() cat.StableID { 423 return cat.StableID(ov.desc.ID) 424 } 425 426 // PostgresDescriptorID is part of the cat.Object interface. 427 func (ov *optView) PostgresDescriptorID() cat.StableID { 428 return cat.StableID(ov.desc.ID) 429 } 430 431 // Equals is part of the cat.Object interface. 432 func (ov *optView) Equals(other cat.Object) bool { 433 otherView, ok := other.(*optView) 434 if !ok { 435 return false 436 } 437 return ov.desc.ID == otherView.desc.ID && ov.desc.Version == otherView.desc.Version 438 } 439 440 // Name is part of the cat.View interface. 441 func (ov *optView) Name() tree.Name { 442 return tree.Name(ov.desc.Name) 443 } 444 445 // IsSystemView is part of the cat.View interface. 446 func (ov *optView) IsSystemView() bool { 447 return ov.desc.IsVirtualTable() 448 } 449 450 // Query is part of the cat.View interface. 451 func (ov *optView) Query() string { 452 return ov.desc.ViewQuery 453 } 454 455 // ColumnNameCount is part of the cat.View interface. 456 func (ov *optView) ColumnNameCount() int { 457 return len(ov.desc.Columns) 458 } 459 460 // ColumnName is part of the cat.View interface. 461 func (ov *optView) ColumnName(i int) tree.Name { 462 return tree.Name(ov.desc.Columns[i].Name) 463 } 464 465 // optSequence is a wrapper around sqlbase.ImmutableTableDescriptor that 466 // implements the cat.Object and cat.DataSource interfaces. 467 type optSequence struct { 468 desc *sqlbase.ImmutableTableDescriptor 469 } 470 471 var _ cat.DataSource = &optSequence{} 472 var _ cat.Sequence = &optSequence{} 473 474 func newOptSequence(desc *sqlbase.ImmutableTableDescriptor) *optSequence { 475 return &optSequence{desc: desc} 476 } 477 478 // ID is part of the cat.Object interface. 479 func (os *optSequence) ID() cat.StableID { 480 return cat.StableID(os.desc.ID) 481 } 482 483 // PostgresDescriptorID is part of the cat.Object interface. 484 func (os *optSequence) PostgresDescriptorID() cat.StableID { 485 return cat.StableID(os.desc.ID) 486 } 487 488 // Equals is part of the cat.Object interface. 489 func (os *optSequence) Equals(other cat.Object) bool { 490 otherSeq, ok := other.(*optSequence) 491 if !ok { 492 return false 493 } 494 return os.desc.ID == otherSeq.desc.ID && os.desc.Version == otherSeq.desc.Version 495 } 496 497 // Name is part of the cat.Sequence interface. 498 func (os *optSequence) Name() tree.Name { 499 return tree.Name(os.desc.Name) 500 } 501 502 // SequenceMarker is part of the cat.Sequence interface. 503 func (os *optSequence) SequenceMarker() {} 504 505 // optTable is a wrapper around sqlbase.ImmutableTableDescriptor that caches 506 // index wrappers and maintains a ColumnID => Column mapping for fast lookup. 507 type optTable struct { 508 desc *sqlbase.ImmutableTableDescriptor 509 510 // indexes are the inlined wrappers for the table's primary and secondary 511 // indexes. 512 indexes []optIndex 513 514 // codec is capable of encoding sql table keys. 515 codec keys.SQLCodec 516 517 // rawStats stores the original table statistics slice. Used for a fast-path 518 // check that the statistics haven't changed. 519 rawStats []*stats.TableStatistic 520 521 // stats are the inlined wrappers for table statistics. 522 stats []optTableStat 523 524 zone *zonepb.ZoneConfig 525 526 // family is the inlined wrapper for the table's primary family. The primary 527 // family is the first family explicitly specified by the user. If no families 528 // were explicitly specified, then the primary family is synthesized. 529 primaryFamily optFamily 530 531 // families are the inlined wrappers for the table's non-primary families, 532 // which are all the families specified by the user after the first. The 533 // primary family is kept separate since the common case is that there's just 534 // one family. 535 families []optFamily 536 537 outboundFKs []optForeignKeyConstraint 538 inboundFKs []optForeignKeyConstraint 539 540 // colMap is a mapping from unique ColumnID to column ordinal within the 541 // table. This is a common lookup that needs to be fast. 542 colMap map[sqlbase.ColumnID]int 543 } 544 545 var _ cat.Table = &optTable{} 546 547 func newOptTable( 548 desc *sqlbase.ImmutableTableDescriptor, 549 codec keys.SQLCodec, 550 stats []*stats.TableStatistic, 551 tblZone *zonepb.ZoneConfig, 552 ) (*optTable, error) { 553 ot := &optTable{ 554 desc: desc, 555 codec: codec, 556 rawStats: stats, 557 zone: tblZone, 558 } 559 560 // Create the table's column mapping from sqlbase.ColumnID to column ordinal. 561 ot.colMap = make(map[sqlbase.ColumnID]int, ot.DeletableColumnCount()) 562 for i, n := 0, ot.DeletableColumnCount(); i < n; i++ { 563 ot.colMap[sqlbase.ColumnID(ot.Column(i).ColID())] = i 564 } 565 566 // Build the indexes (add 1 to account for lack of primary index in 567 // DeletableIndexes slice). 568 ot.indexes = make([]optIndex, 1+len(ot.desc.DeletableIndexes())) 569 570 for i := range ot.indexes { 571 var idxDesc *sqlbase.IndexDescriptor 572 if i == 0 { 573 idxDesc = &desc.PrimaryIndex 574 } else { 575 idxDesc = &ot.desc.DeletableIndexes()[i-1] 576 } 577 578 // If there is a subzone that applies to the entire index, use that, 579 // else use the table zone. Skip subzones that apply to partitions, 580 // since they apply only to a subset of the index. 581 idxZone := tblZone 582 for j := range tblZone.Subzones { 583 subzone := &tblZone.Subzones[j] 584 if subzone.IndexID == uint32(idxDesc.ID) && subzone.PartitionName == "" { 585 copyZone := subzone.Config 586 copyZone.InheritFromParent(tblZone) 587 idxZone = ©Zone 588 } 589 } 590 ot.indexes[i].init(ot, i, idxDesc, idxZone) 591 } 592 593 for i := range ot.desc.OutboundFKs { 594 fk := &ot.desc.OutboundFKs[i] 595 ot.outboundFKs = append(ot.outboundFKs, optForeignKeyConstraint{ 596 name: fk.Name, 597 originTable: ot.ID(), 598 originColumns: fk.OriginColumnIDs, 599 referencedTable: cat.StableID(fk.ReferencedTableID), 600 referencedColumns: fk.ReferencedColumnIDs, 601 validity: fk.Validity, 602 match: fk.Match, 603 deleteAction: fk.OnDelete, 604 updateAction: fk.OnUpdate, 605 }) 606 } 607 for i := range ot.desc.InboundFKs { 608 fk := &ot.desc.InboundFKs[i] 609 ot.inboundFKs = append(ot.inboundFKs, optForeignKeyConstraint{ 610 name: fk.Name, 611 originTable: cat.StableID(fk.OriginTableID), 612 originColumns: fk.OriginColumnIDs, 613 referencedTable: ot.ID(), 614 referencedColumns: fk.ReferencedColumnIDs, 615 validity: fk.Validity, 616 match: fk.Match, 617 deleteAction: fk.OnDelete, 618 updateAction: fk.OnUpdate, 619 }) 620 } 621 622 ot.primaryFamily.init(ot, &desc.Families[0]) 623 ot.families = make([]optFamily, len(desc.Families)-1) 624 for i := range ot.families { 625 ot.families[i].init(ot, &desc.Families[i+1]) 626 } 627 628 // Add stats last, now that other metadata is initialized. 629 if stats != nil { 630 ot.stats = make([]optTableStat, len(stats)) 631 n := 0 632 for i := range stats { 633 // We skip any stats that have columns that don't exist in the table anymore. 634 if ok, err := ot.stats[n].init(ot, stats[i]); err != nil { 635 return nil, err 636 } else if ok { 637 n++ 638 } 639 } 640 ot.stats = ot.stats[:n] 641 } 642 643 return ot, nil 644 } 645 646 // ID is part of the cat.Object interface. 647 func (ot *optTable) ID() cat.StableID { 648 return cat.StableID(ot.desc.ID) 649 } 650 651 // PostgresDescriptorID is part of the cat.Object interface. 652 func (ot *optTable) PostgresDescriptorID() cat.StableID { 653 return cat.StableID(ot.desc.ID) 654 } 655 656 // isStale checks if the optTable object needs to be refreshed because the stats 657 // or zone config have changed. False positives are ok. 658 func (ot *optTable) isStale(tableStats []*stats.TableStatistic, zone *zonepb.ZoneConfig) bool { 659 // Fast check to verify that the statistics haven't changed: we check the 660 // length and the address of the underlying array. This is not a perfect 661 // check (in principle, the stats could have left the cache and then gotten 662 // regenerated), but it works in the common case. 663 if len(tableStats) != len(ot.rawStats) { 664 return true 665 } 666 if len(tableStats) > 0 && &tableStats[0] != &ot.rawStats[0] { 667 return true 668 } 669 if !zone.Equal(ot.zone) { 670 return true 671 } 672 return false 673 } 674 675 // Equals is part of the cat.Object interface. 676 func (ot *optTable) Equals(other cat.Object) bool { 677 otherTable, ok := other.(*optTable) 678 if !ok { 679 return false 680 } 681 if ot == otherTable { 682 // Fast path when it is the same object. 683 return true 684 } 685 if ot.desc.ID != otherTable.desc.ID || ot.desc.Version != otherTable.desc.Version { 686 return false 687 } 688 689 // Verify the stats are identical. 690 if len(ot.stats) != len(otherTable.stats) { 691 return false 692 } 693 for i := range ot.stats { 694 if !ot.stats[i].equals(&otherTable.stats[i]) { 695 return false 696 } 697 } 698 699 // Verify that indexes are in same zones. For performance, skip deep equality 700 // check if it's the same as the previous index (common case). 701 var prevLeftZone, prevRightZone *zonepb.ZoneConfig 702 for i := range ot.indexes { 703 leftZone := ot.indexes[i].zone 704 rightZone := otherTable.indexes[i].zone 705 if leftZone == prevLeftZone && rightZone == prevRightZone { 706 continue 707 } 708 if !leftZone.Equal(rightZone) { 709 return false 710 } 711 prevLeftZone = leftZone 712 prevRightZone = rightZone 713 } 714 715 return true 716 } 717 718 // Name is part of the cat.Table interface. 719 func (ot *optTable) Name() tree.Name { 720 return tree.Name(ot.desc.Name) 721 } 722 723 // IsVirtualTable is part of the cat.Table interface. 724 func (ot *optTable) IsVirtualTable() bool { 725 return false 726 } 727 728 // ColumnCount is part of the cat.Table interface. 729 func (ot *optTable) ColumnCount() int { 730 return len(ot.desc.Columns) 731 } 732 733 // WritableColumnCount is part of the cat.Table interface. 734 func (ot *optTable) WritableColumnCount() int { 735 return len(ot.desc.WritableColumns()) 736 } 737 738 // DeletableColumnCount is part of the cat.Table interface. 739 func (ot *optTable) DeletableColumnCount() int { 740 return len(ot.desc.DeletableColumns()) 741 } 742 743 // Column is part of the cat.Table interface. 744 func (ot *optTable) Column(i int) cat.Column { 745 return &ot.desc.DeletableColumns()[i] 746 } 747 748 // IndexCount is part of the cat.Table interface. 749 func (ot *optTable) IndexCount() int { 750 // Primary index is always present, so count is always >= 1. 751 return 1 + len(ot.desc.Indexes) 752 } 753 754 // WritableIndexCount is part of the cat.Table interface. 755 func (ot *optTable) WritableIndexCount() int { 756 // Primary index is always present, so count is always >= 1. 757 return 1 + len(ot.desc.WritableIndexes()) 758 } 759 760 // DeletableIndexCount is part of the cat.Table interface. 761 func (ot *optTable) DeletableIndexCount() int { 762 // Primary index is always present, so count is always >= 1. 763 return 1 + len(ot.desc.DeletableIndexes()) 764 } 765 766 // Index is part of the cat.Table interface. 767 func (ot *optTable) Index(i cat.IndexOrdinal) cat.Index { 768 return &ot.indexes[i] 769 } 770 771 // StatisticCount is part of the cat.Table interface. 772 func (ot *optTable) StatisticCount() int { 773 return len(ot.stats) 774 } 775 776 // Statistic is part of the cat.Table interface. 777 func (ot *optTable) Statistic(i int) cat.TableStatistic { 778 return &ot.stats[i] 779 } 780 781 // CheckCount is part of the cat.Table interface. 782 func (ot *optTable) CheckCount() int { 783 return len(ot.desc.ActiveChecks()) 784 } 785 786 // Check is part of the cat.Table interface. 787 func (ot *optTable) Check(i int) cat.CheckConstraint { 788 check := ot.desc.ActiveChecks()[i] 789 return cat.CheckConstraint{ 790 Constraint: check.Expr, 791 Validated: check.Validity == sqlbase.ConstraintValidity_Validated, 792 } 793 } 794 795 // FamilyCount is part of the cat.Table interface. 796 func (ot *optTable) FamilyCount() int { 797 return 1 + len(ot.families) 798 } 799 800 // Family is part of the cat.Table interface. 801 func (ot *optTable) Family(i int) cat.Family { 802 if i == 0 { 803 return &ot.primaryFamily 804 } 805 return &ot.families[i-1] 806 } 807 808 // OutboundForeignKeyCount is part of the cat.Table interface. 809 func (ot *optTable) OutboundForeignKeyCount() int { 810 return len(ot.outboundFKs) 811 } 812 813 // OutboundForeignKeyCount is part of the cat.Table interface. 814 func (ot *optTable) OutboundForeignKey(i int) cat.ForeignKeyConstraint { 815 return &ot.outboundFKs[i] 816 } 817 818 // InboundForeignKeyCount is part of the cat.Table interface. 819 func (ot *optTable) InboundForeignKeyCount() int { 820 return len(ot.inboundFKs) 821 } 822 823 // InboundForeignKey is part of the cat.Table interface. 824 func (ot *optTable) InboundForeignKey(i int) cat.ForeignKeyConstraint { 825 return &ot.inboundFKs[i] 826 } 827 828 // lookupColumnOrdinal returns the ordinal of the column with the given ID. A 829 // cache makes the lookup O(1). 830 func (ot *optTable) lookupColumnOrdinal(colID sqlbase.ColumnID) (int, error) { 831 col, ok := ot.colMap[colID] 832 if ok { 833 return col, nil 834 } 835 return col, pgerror.Newf(pgcode.UndefinedColumn, 836 "column [%d] does not exist", colID) 837 } 838 839 // optIndex is a wrapper around sqlbase.IndexDescriptor that caches some 840 // commonly accessed information and keeps a reference to the table wrapper. 841 type optIndex struct { 842 tab *optTable 843 desc *sqlbase.IndexDescriptor 844 zone *zonepb.ZoneConfig 845 846 // storedCols is the set of non-PK columns if this is the primary index, 847 // otherwise it is desc.StoreColumnIDs. 848 storedCols []sqlbase.ColumnID 849 850 indexOrdinal int 851 numCols int 852 numKeyCols int 853 numLaxKeyCols int 854 } 855 856 var _ cat.Index = &optIndex{} 857 858 // init can be used instead of newOptIndex when we have a pre-allocated instance 859 // (e.g. as part of a bigger struct). 860 func (oi *optIndex) init( 861 tab *optTable, indexOrdinal int, desc *sqlbase.IndexDescriptor, zone *zonepb.ZoneConfig, 862 ) { 863 oi.tab = tab 864 oi.desc = desc 865 oi.zone = zone 866 oi.indexOrdinal = indexOrdinal 867 if desc == &tab.desc.PrimaryIndex { 868 // Although the primary index contains all columns in the table, the index 869 // descriptor does not contain columns that are not explicitly part of the 870 // primary key. Retrieve those columns from the table descriptor. 871 oi.storedCols = make([]sqlbase.ColumnID, 0, tab.DeletableColumnCount()-len(desc.ColumnIDs)) 872 var pkCols util.FastIntSet 873 for i := range desc.ColumnIDs { 874 pkCols.Add(int(desc.ColumnIDs[i])) 875 } 876 for i, n := 0, tab.DeletableColumnCount(); i < n; i++ { 877 id := tab.Column(i).ColID() 878 if !pkCols.Contains(int(id)) { 879 oi.storedCols = append(oi.storedCols, sqlbase.ColumnID(id)) 880 } 881 } 882 oi.numCols = tab.DeletableColumnCount() 883 } else { 884 oi.storedCols = desc.StoreColumnIDs 885 oi.numCols = len(desc.ColumnIDs) + len(desc.ExtraColumnIDs) + len(desc.StoreColumnIDs) 886 } 887 888 if desc.Unique { 889 notNull := true 890 for _, id := range desc.ColumnIDs { 891 ord, _ := tab.lookupColumnOrdinal(id) 892 if tab.desc.DeletableColumns()[ord].Nullable { 893 notNull = false 894 break 895 } 896 } 897 898 if notNull { 899 // Unique index with no null columns: columns from index are sufficient 900 // to form a key without needing extra primary key columns. There is no 901 // separate lax key. 902 oi.numLaxKeyCols = len(desc.ColumnIDs) 903 oi.numKeyCols = oi.numLaxKeyCols 904 } else { 905 // Unique index with at least one nullable column: extra primary key 906 // columns will be added to the row key when one of the unique index 907 // columns has a NULL value. 908 oi.numLaxKeyCols = len(desc.ColumnIDs) 909 oi.numKeyCols = oi.numLaxKeyCols + len(desc.ExtraColumnIDs) 910 } 911 } else { 912 // Non-unique index: extra primary key columns are always added to the row 913 // key. There is no separate lax key. 914 oi.numLaxKeyCols = len(desc.ColumnIDs) + len(desc.ExtraColumnIDs) 915 oi.numKeyCols = oi.numLaxKeyCols 916 } 917 } 918 919 // ID is part of the cat.Index interface. 920 func (oi *optIndex) ID() cat.StableID { 921 return cat.StableID(oi.desc.ID) 922 } 923 924 // Name is part of the cat.Index interface. 925 func (oi *optIndex) Name() tree.Name { 926 return tree.Name(oi.desc.Name) 927 } 928 929 // IsUnique is part of the cat.Index interface. 930 func (oi *optIndex) IsUnique() bool { 931 return oi.desc.Unique 932 } 933 934 // IsInverted is part of the cat.Index interface. 935 func (oi *optIndex) IsInverted() bool { 936 return oi.desc.Type == sqlbase.IndexDescriptor_INVERTED 937 } 938 939 // ColumnCount is part of the cat.Index interface. 940 func (oi *optIndex) ColumnCount() int { 941 return oi.numCols 942 } 943 944 // Predicate is part of the cat.Index interface. It returns the predicate 945 // expression and true if the index is a partial index. If the index is not 946 // partial, the empty string and false is returned. 947 func (oi *optIndex) Predicate() (string, bool) { 948 return oi.desc.Predicate, oi.desc.Predicate != "" 949 } 950 951 // KeyColumnCount is part of the cat.Index interface. 952 func (oi *optIndex) KeyColumnCount() int { 953 return oi.numKeyCols 954 } 955 956 // LaxKeyColumnCount is part of the cat.Index interface. 957 func (oi *optIndex) LaxKeyColumnCount() int { 958 return oi.numLaxKeyCols 959 } 960 961 // Column is part of the cat.Index interface. 962 func (oi *optIndex) Column(i int) cat.IndexColumn { 963 length := len(oi.desc.ColumnIDs) 964 if i < length { 965 ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i]) 966 return cat.IndexColumn{ 967 Column: oi.tab.Column(ord), 968 Ordinal: ord, 969 Descending: oi.desc.ColumnDirections[i] == sqlbase.IndexDescriptor_DESC, 970 } 971 } 972 973 i -= length 974 length = len(oi.desc.ExtraColumnIDs) 975 if i < length { 976 ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ExtraColumnIDs[i]) 977 return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord} 978 } 979 980 i -= length 981 ord, _ := oi.tab.lookupColumnOrdinal(oi.storedCols[i]) 982 return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord} 983 } 984 985 // Zone is part of the cat.Index interface. 986 func (oi *optIndex) Zone() cat.Zone { 987 return oi.zone 988 } 989 990 // Span is part of the cat.Index interface. 991 func (oi *optIndex) Span() roachpb.Span { 992 desc := oi.tab.desc 993 // Tables up to MaxSystemConfigDescID are grouped in a single system config 994 // span. 995 if desc.ID <= keys.MaxSystemConfigDescID { 996 return keys.SystemConfigSpan 997 } 998 return desc.IndexSpan(oi.tab.codec, oi.desc.ID) 999 } 1000 1001 // Table is part of the cat.Index interface. 1002 func (oi *optIndex) Table() cat.Table { 1003 return oi.tab 1004 } 1005 1006 // Ordinal is part of the cat.Index interface. 1007 func (oi *optIndex) Ordinal() int { 1008 return oi.indexOrdinal 1009 } 1010 1011 // PartitionByListPrefixes is part of the cat.Index interface. 1012 func (oi *optIndex) PartitionByListPrefixes() []tree.Datums { 1013 list := oi.desc.Partitioning.List 1014 if len(list) == 0 { 1015 return nil 1016 } 1017 res := make([]tree.Datums, 0, len(list)) 1018 var a sqlbase.DatumAlloc 1019 for i := range list { 1020 for _, valueEncBuf := range list[i].Values { 1021 t, _, err := sqlbase.DecodePartitionTuple( 1022 &a, oi.tab.codec, &oi.tab.desc.TableDescriptor, oi.desc, &oi.desc.Partitioning, 1023 valueEncBuf, nil, /* prefixDatums */ 1024 ) 1025 if err != nil { 1026 panic(errors.NewAssertionErrorWithWrappedErrf(err, "while decoding partition tuple")) 1027 } 1028 // Ignore the DEFAULT case, where there is nothing to return. 1029 if len(t.Datums) > 0 { 1030 res = append(res, t.Datums) 1031 } 1032 // TODO(radu): split into multiple prefixes if Subpartition is also by list. 1033 // Note that this functionality should be kept in sync with the test catalog 1034 // implementation (test_catalog.go). 1035 } 1036 } 1037 return res 1038 } 1039 1040 // InterleaveAncestorCount is part of the cat.Index interface. 1041 func (oi *optIndex) InterleaveAncestorCount() int { 1042 return len(oi.desc.Interleave.Ancestors) 1043 } 1044 1045 // InterleaveAncestor is part of the cat.Index interface. 1046 func (oi *optIndex) InterleaveAncestor(i int) (table, index cat.StableID, numKeyCols int) { 1047 a := &oi.desc.Interleave.Ancestors[i] 1048 return cat.StableID(a.TableID), cat.StableID(a.IndexID), int(a.SharedPrefixLen) 1049 } 1050 1051 // InterleavedByCount is part of the cat.Index interface. 1052 func (oi *optIndex) InterleavedByCount() int { 1053 return len(oi.desc.InterleavedBy) 1054 } 1055 1056 // InterleavedBy is part of the cat.Index interface. 1057 func (oi *optIndex) InterleavedBy(i int) (table, index cat.StableID) { 1058 ref := &oi.desc.InterleavedBy[i] 1059 return cat.StableID(ref.Table), cat.StableID(ref.Index) 1060 } 1061 1062 type optTableStat struct { 1063 stat *stats.TableStatistic 1064 columnOrdinals []int 1065 } 1066 1067 var _ cat.TableStatistic = &optTableStat{} 1068 1069 func (os *optTableStat) init(tab *optTable, stat *stats.TableStatistic) (ok bool, _ error) { 1070 os.stat = stat 1071 os.columnOrdinals = make([]int, len(stat.ColumnIDs)) 1072 for i, c := range stat.ColumnIDs { 1073 var ok bool 1074 os.columnOrdinals[i], ok = tab.colMap[c] 1075 if !ok { 1076 // Column not in table (this is possible if the column was removed since 1077 // the statistic was calculated). 1078 return false, nil 1079 } 1080 } 1081 1082 return true, nil 1083 } 1084 1085 func (os *optTableStat) equals(other *optTableStat) bool { 1086 // Two table statistics are considered equal if they have been created at the 1087 // same time, on the same set of columns. 1088 if os.CreatedAt() != other.CreatedAt() || len(os.columnOrdinals) != len(other.columnOrdinals) { 1089 return false 1090 } 1091 for i, c := range os.columnOrdinals { 1092 if c != other.columnOrdinals[i] { 1093 return false 1094 } 1095 } 1096 return true 1097 } 1098 1099 // CreatedAt is part of the cat.TableStatistic interface. 1100 func (os *optTableStat) CreatedAt() time.Time { 1101 return os.stat.CreatedAt 1102 } 1103 1104 // ColumnCount is part of the cat.TableStatistic interface. 1105 func (os *optTableStat) ColumnCount() int { 1106 return len(os.columnOrdinals) 1107 } 1108 1109 // ColumnOrdinal is part of the cat.TableStatistic interface. 1110 func (os *optTableStat) ColumnOrdinal(i int) int { 1111 return os.columnOrdinals[i] 1112 } 1113 1114 // RowCount is part of the cat.TableStatistic interface. 1115 func (os *optTableStat) RowCount() uint64 { 1116 return os.stat.RowCount 1117 } 1118 1119 // DistinctCount is part of the cat.TableStatistic interface. 1120 func (os *optTableStat) DistinctCount() uint64 { 1121 return os.stat.DistinctCount 1122 } 1123 1124 // NullCount is part of the cat.TableStatistic interface. 1125 func (os *optTableStat) NullCount() uint64 { 1126 return os.stat.NullCount 1127 } 1128 1129 // Histogram is part of the cat.TableStatistic interface. 1130 func (os *optTableStat) Histogram() []cat.HistogramBucket { 1131 return os.stat.Histogram 1132 } 1133 1134 // optFamily is a wrapper around sqlbase.ColumnFamilyDescriptor that keeps a 1135 // reference to the table wrapper. 1136 type optFamily struct { 1137 tab *optTable 1138 desc *sqlbase.ColumnFamilyDescriptor 1139 } 1140 1141 var _ cat.Family = &optFamily{} 1142 1143 // init can be used instead of newOptFamily when we have a pre-allocated 1144 // instance (e.g. as part of a bigger struct). 1145 func (oi *optFamily) init(tab *optTable, desc *sqlbase.ColumnFamilyDescriptor) { 1146 oi.tab = tab 1147 oi.desc = desc 1148 } 1149 1150 // ID is part of the cat.Family interface. 1151 func (oi *optFamily) ID() cat.StableID { 1152 return cat.StableID(oi.desc.ID) 1153 } 1154 1155 // Name is part of the cat.Family interface. 1156 func (oi *optFamily) Name() tree.Name { 1157 return tree.Name(oi.desc.Name) 1158 } 1159 1160 // ColumnCount is part of the cat.Family interface. 1161 func (oi *optFamily) ColumnCount() int { 1162 return len(oi.desc.ColumnIDs) 1163 } 1164 1165 // Column is part of the cat.Family interface. 1166 func (oi *optFamily) Column(i int) cat.FamilyColumn { 1167 ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i]) 1168 return cat.FamilyColumn{Column: oi.tab.Column(ord), Ordinal: ord} 1169 } 1170 1171 // Table is part of the cat.Family interface. 1172 func (oi *optFamily) Table() cat.Table { 1173 return oi.tab 1174 } 1175 1176 // optForeignKeyConstraint implements cat.ForeignKeyConstraint and represents a 1177 // foreign key relationship. Both the origin and the referenced table store the 1178 // same optForeignKeyConstraint (as an outbound and inbound reference, 1179 // respectively). 1180 type optForeignKeyConstraint struct { 1181 name string 1182 1183 originTable cat.StableID 1184 originColumns []sqlbase.ColumnID 1185 1186 referencedTable cat.StableID 1187 referencedColumns []sqlbase.ColumnID 1188 1189 validity sqlbase.ConstraintValidity 1190 match sqlbase.ForeignKeyReference_Match 1191 deleteAction sqlbase.ForeignKeyReference_Action 1192 updateAction sqlbase.ForeignKeyReference_Action 1193 } 1194 1195 var _ cat.ForeignKeyConstraint = &optForeignKeyConstraint{} 1196 1197 // Name is part of the cat.ForeignKeyConstraint interface. 1198 func (fk *optForeignKeyConstraint) Name() string { 1199 return fk.name 1200 } 1201 1202 // OriginTableID is part of the cat.ForeignKeyConstraint interface. 1203 func (fk *optForeignKeyConstraint) OriginTableID() cat.StableID { 1204 return fk.originTable 1205 } 1206 1207 // ReferencedTableID is part of the cat.ForeignKeyConstraint interface. 1208 func (fk *optForeignKeyConstraint) ReferencedTableID() cat.StableID { 1209 return fk.referencedTable 1210 } 1211 1212 // ColumnCount is part of the cat.ForeignKeyConstraint interface. 1213 func (fk *optForeignKeyConstraint) ColumnCount() int { 1214 return len(fk.originColumns) 1215 } 1216 1217 // OriginColumnOrdinal is part of the cat.ForeignKeyConstraint interface. 1218 func (fk *optForeignKeyConstraint) OriginColumnOrdinal(originTable cat.Table, i int) int { 1219 if originTable.ID() != fk.originTable { 1220 panic(errors.AssertionFailedf( 1221 "invalid table %d passed to OriginColumnOrdinal (expected %d)", 1222 originTable.ID(), fk.originTable, 1223 )) 1224 } 1225 1226 tab := originTable.(*optTable) 1227 ord, _ := tab.lookupColumnOrdinal(fk.originColumns[i]) 1228 return ord 1229 } 1230 1231 // ReferencedColumnOrdinal is part of the cat.ForeignKeyConstraint interface. 1232 func (fk *optForeignKeyConstraint) ReferencedColumnOrdinal(referencedTable cat.Table, i int) int { 1233 if referencedTable.ID() != fk.referencedTable { 1234 panic(errors.AssertionFailedf( 1235 "invalid table %d passed to ReferencedColumnOrdinal (expected %d)", 1236 referencedTable.ID(), fk.referencedTable, 1237 )) 1238 } 1239 tab := referencedTable.(*optTable) 1240 ord, _ := tab.lookupColumnOrdinal(fk.referencedColumns[i]) 1241 return ord 1242 } 1243 1244 // Validated is part of the cat.ForeignKeyConstraint interface. 1245 func (fk *optForeignKeyConstraint) Validated() bool { 1246 return fk.validity == sqlbase.ConstraintValidity_Validated 1247 } 1248 1249 // MatchMethod is part of the cat.ForeignKeyConstraint interface. 1250 func (fk *optForeignKeyConstraint) MatchMethod() tree.CompositeKeyMatchMethod { 1251 return sqlbase.ForeignKeyReferenceMatchValue[fk.match] 1252 } 1253 1254 // DeleteReferenceAction is part of the cat.ForeignKeyConstraint interface. 1255 func (fk *optForeignKeyConstraint) DeleteReferenceAction() tree.ReferenceAction { 1256 return sqlbase.ForeignKeyReferenceActionType[fk.deleteAction] 1257 } 1258 1259 // UpdateReferenceAction is part of the cat.ForeignKeyConstraint interface. 1260 func (fk *optForeignKeyConstraint) UpdateReferenceAction() tree.ReferenceAction { 1261 return sqlbase.ForeignKeyReferenceActionType[fk.updateAction] 1262 } 1263 1264 // optVirtualTable is similar to optTable but is used with virtual tables. 1265 type optVirtualTable struct { 1266 desc *sqlbase.ImmutableTableDescriptor 1267 1268 // A virtual table can effectively have multiple instances, with different 1269 // contents. For example `db1.pg_catalog.pg_sequence` contains info about 1270 // sequences in db1, whereas `db2.pg_catalog.pg_sequence` contains info about 1271 // sequences in db2. 1272 // 1273 // These instances should have different stable IDs. To achieve this, the 1274 // stable ID is the database ID concatenated with the descriptor ID. 1275 // 1276 // Note that some virtual tables have a special instance with empty catalog, 1277 // for example "".information_schema.tables contains info about tables in 1278 // all databases. We treat the empty catalog as having database ID 0. 1279 id cat.StableID 1280 1281 // name is the fully qualified, fully resolved, fully normalized name of the 1282 // virtual table. 1283 name cat.DataSourceName 1284 1285 // indexes contains "virtual indexes", which are used to produce virtual table 1286 // data given constraints using generator functions. The 0th index is a 1287 // synthesized primary index. 1288 indexes []optVirtualIndex 1289 1290 // family is a synthesized primary family. 1291 family optVirtualFamily 1292 1293 // colMap is a mapping from unique ColumnID to column ordinal within the 1294 // table. This is a common lookup that needs to be fast. 1295 colMap map[sqlbase.ColumnID]int 1296 } 1297 1298 var _ cat.Table = &optVirtualTable{} 1299 1300 func newOptVirtualTable( 1301 ctx context.Context, 1302 oc *optCatalog, 1303 desc *sqlbase.ImmutableTableDescriptor, 1304 name *cat.DataSourceName, 1305 ) (*optVirtualTable, error) { 1306 // Calculate the stable ID (see the comment for optVirtualTable.id). 1307 id := cat.StableID(desc.ID) 1308 if name.Catalog() != "" { 1309 // TODO(radu): it's unfortunate that we have to lookup the schema again. 1310 _, dbDesc, err := oc.planner.LookupSchema(ctx, name.Catalog(), name.Schema()) 1311 if err != nil { 1312 return nil, err 1313 } 1314 if dbDesc == nil { 1315 // The database was not found. This can happen e.g. when 1316 // accessing a virtual schema over a non-existent 1317 // database. This is a common scenario when the current db 1318 // in the session points to a database that was not created 1319 // yet. 1320 // 1321 // In that case we use an invalid database ID. We 1322 // distinguish this from the empty database case because the 1323 // virtual tables do not "contain" the same information in 1324 // both cases. 1325 id |= cat.StableID(math.MaxUint32) << 32 1326 } else { 1327 id |= cat.StableID(dbDesc.(*DatabaseDescriptor).ID) << 32 1328 } 1329 } 1330 1331 ot := &optVirtualTable{ 1332 desc: desc, 1333 id: id, 1334 name: *name, 1335 } 1336 1337 // Create the table's column mapping from sqlbase.ColumnID to column ordinal. 1338 ot.colMap = make(map[sqlbase.ColumnID]int, ot.DeletableColumnCount()) 1339 for i, n := 0, ot.DeletableColumnCount(); i < n; i++ { 1340 ot.colMap[sqlbase.ColumnID(ot.Column(i).ColID())] = i 1341 } 1342 1343 ot.name.ExplicitSchema = true 1344 ot.name.ExplicitCatalog = true 1345 1346 ot.family.init(ot) 1347 1348 // Build the indexes (add 1 to account for lack of primary index in 1349 // indexes slice). 1350 ot.indexes = make([]optVirtualIndex, 1+len(ot.desc.Indexes)) 1351 // Set up the primary index. 1352 ot.indexes[0] = optVirtualIndex{ 1353 tab: ot, 1354 indexOrdinal: 0, 1355 numCols: ot.ColumnCount(), 1356 isPrimary: true, 1357 desc: &sqlbase.IndexDescriptor{ 1358 ID: 0, 1359 Name: "primary", 1360 }, 1361 } 1362 1363 for i := range ot.desc.Indexes { 1364 idxDesc := &ot.desc.Indexes[i] 1365 if len(idxDesc.ColumnIDs) > 1 { 1366 panic("virtual indexes with more than 1 col not supported") 1367 } 1368 1369 // Add 1, since the 0th index will the the primary that we added above. 1370 ot.indexes[i+1] = optVirtualIndex{ 1371 tab: ot, 1372 desc: idxDesc, 1373 indexOrdinal: i + 1, 1374 // The virtual indexes don't return the bogus PK key? 1375 numCols: ot.ColumnCount(), 1376 } 1377 } 1378 1379 return ot, nil 1380 } 1381 1382 // ID is part of the cat.Object interface. 1383 func (ot *optVirtualTable) ID() cat.StableID { 1384 return ot.id 1385 } 1386 1387 // PostgresDescriptorID is part of the cat.Object interface. 1388 func (ot *optVirtualTable) PostgresDescriptorID() cat.StableID { 1389 return cat.StableID(ot.desc.ID) 1390 } 1391 1392 // Equals is part of the cat.Object interface. 1393 func (ot *optVirtualTable) Equals(other cat.Object) bool { 1394 otherTable, ok := other.(*optVirtualTable) 1395 if !ok { 1396 return false 1397 } 1398 if ot == otherTable { 1399 // Fast path when it is the same object. 1400 return true 1401 } 1402 if ot.id != otherTable.id || ot.desc.Version != otherTable.desc.Version { 1403 return false 1404 } 1405 1406 return true 1407 } 1408 1409 // Name is part of the cat.Table interface. 1410 func (ot *optVirtualTable) Name() tree.Name { 1411 return ot.name.ObjectName 1412 } 1413 1414 // IsVirtualTable is part of the cat.Table interface. 1415 func (ot *optVirtualTable) IsVirtualTable() bool { 1416 return true 1417 } 1418 1419 // ColumnCount is part of the cat.Table interface. 1420 func (ot *optVirtualTable) ColumnCount() int { 1421 // Virtual tables expose an extra (bogus) PK column. 1422 return len(ot.desc.Columns) + 1 1423 } 1424 1425 // WritableColumnCount is part of the cat.Table interface. 1426 func (ot *optVirtualTable) WritableColumnCount() int { 1427 return len(ot.desc.WritableColumns()) + 1 1428 } 1429 1430 // DeletableColumnCount is part of the cat.Table interface. 1431 func (ot *optVirtualTable) DeletableColumnCount() int { 1432 return len(ot.desc.DeletableColumns()) + 1 1433 } 1434 1435 // Column is part of the cat.Table interface. 1436 func (ot *optVirtualTable) Column(i int) cat.Column { 1437 if i == 0 { 1438 // Column 0 is a dummy PK column. 1439 return optDummyVirtualPKColumn{} 1440 } 1441 return &ot.desc.DeletableColumns()[i-1] 1442 } 1443 1444 // IndexCount is part of the cat.Table interface. 1445 func (ot *optVirtualTable) IndexCount() int { 1446 // Primary index is always present, so count is always >= 1. 1447 return 1 + len(ot.desc.Indexes) 1448 } 1449 1450 // WritableIndexCount is part of the cat.Table interface. 1451 func (ot *optVirtualTable) WritableIndexCount() int { 1452 // Primary index is always present, so count is always >= 1. 1453 return 1 + len(ot.desc.WritableIndexes()) 1454 } 1455 1456 // DeletableIndexCount is part of the cat.Table interface. 1457 func (ot *optVirtualTable) DeletableIndexCount() int { 1458 // Primary index is always present, so count is always >= 1. 1459 return 1 + len(ot.desc.DeletableIndexes()) 1460 } 1461 1462 // Index is part of the cat.Table interface. 1463 func (ot *optVirtualTable) Index(i cat.IndexOrdinal) cat.Index { 1464 return &ot.indexes[i] 1465 } 1466 1467 // StatisticCount is part of the cat.Table interface. 1468 func (ot *optVirtualTable) StatisticCount() int { 1469 return 0 1470 } 1471 1472 // Statistic is part of the cat.Table interface. 1473 func (ot *optVirtualTable) Statistic(i int) cat.TableStatistic { 1474 panic("no stats") 1475 } 1476 1477 // CheckCount is part of the cat.Table interface. 1478 func (ot *optVirtualTable) CheckCount() int { 1479 return len(ot.desc.ActiveChecks()) 1480 } 1481 1482 // Check is part of the cat.Table interface. 1483 func (ot *optVirtualTable) Check(i int) cat.CheckConstraint { 1484 check := ot.desc.ActiveChecks()[i] 1485 return cat.CheckConstraint{ 1486 Constraint: check.Expr, 1487 Validated: check.Validity == sqlbase.ConstraintValidity_Validated, 1488 } 1489 } 1490 1491 // FamilyCount is part of the cat.Table interface. 1492 func (ot *optVirtualTable) FamilyCount() int { 1493 return 1 1494 } 1495 1496 // Family is part of the cat.Table interface. 1497 func (ot *optVirtualTable) Family(i int) cat.Family { 1498 return &ot.family 1499 } 1500 1501 // OutboundForeignKeyCount is part of the cat.Table interface. 1502 func (ot *optVirtualTable) OutboundForeignKeyCount() int { 1503 return 0 1504 } 1505 1506 // OutboundForeignKeyCount is part of the cat.Table interface. 1507 func (ot *optVirtualTable) OutboundForeignKey(i int) cat.ForeignKeyConstraint { 1508 panic("no FKs") 1509 } 1510 1511 // InboundForeignKeyCount is part of the cat.Table interface. 1512 func (ot *optVirtualTable) InboundForeignKeyCount() int { 1513 return 0 1514 } 1515 1516 // InboundForeignKey is part of the cat.Table interface. 1517 func (ot *optVirtualTable) InboundForeignKey(i int) cat.ForeignKeyConstraint { 1518 panic("no FKs") 1519 } 1520 1521 type optDummyVirtualPKColumn struct{} 1522 1523 var _ cat.Column = optDummyVirtualPKColumn{} 1524 1525 // ColID is part of the cat.Column interface. 1526 func (optDummyVirtualPKColumn) ColID() cat.StableID { 1527 return math.MaxInt64 1528 } 1529 1530 // ColName is part of the cat.Column interface. 1531 func (optDummyVirtualPKColumn) ColName() tree.Name { 1532 return "crdb_internal_vtable_pk" 1533 } 1534 1535 // DatumType is part of the cat.Column interface. 1536 func (optDummyVirtualPKColumn) DatumType() *types.T { 1537 return types.Int 1538 } 1539 1540 // ColTypePrecision is part of the cat.Column interface. 1541 func (optDummyVirtualPKColumn) ColTypePrecision() int { 1542 return int(types.Int.Precision()) 1543 } 1544 1545 // ColTypeWidth is part of the cat.Column interface. 1546 func (optDummyVirtualPKColumn) ColTypeWidth() int { 1547 return int(types.Int.Width()) 1548 } 1549 1550 // ColTypeStr is part of the cat.Column interface. 1551 func (optDummyVirtualPKColumn) ColTypeStr() string { 1552 return types.Int.SQLString() 1553 } 1554 1555 // IsNullable is part of the cat.Column interface. 1556 func (optDummyVirtualPKColumn) IsNullable() bool { 1557 return false 1558 } 1559 1560 // IsHidden is part of the cat.Column interface. 1561 func (optDummyVirtualPKColumn) IsHidden() bool { 1562 return true 1563 } 1564 1565 // HasDefault is part of the cat.Column interface. 1566 func (optDummyVirtualPKColumn) HasDefault() bool { 1567 return false 1568 } 1569 1570 // DefaultExprStr is part of the cat.Column interface. 1571 func (optDummyVirtualPKColumn) DefaultExprStr() string { 1572 return "" 1573 } 1574 1575 // IsComputed is part of the cat.Column interface. 1576 func (optDummyVirtualPKColumn) IsComputed() bool { 1577 return false 1578 } 1579 1580 // ComputedExprStr is part of the cat.Column interface. 1581 func (optDummyVirtualPKColumn) ComputedExprStr() string { 1582 return "" 1583 } 1584 1585 // optVirtualIndex is a dummy implementation of cat.Index for the indexes 1586 // reported by a virtual table. The index assumes that table column 0 is a dummy 1587 // PK column. 1588 type optVirtualIndex struct { 1589 tab *optVirtualTable 1590 1591 // isPrimary is set to true if this is the dummy PK index for virtual tables. 1592 isPrimary bool 1593 1594 desc *sqlbase.IndexDescriptor 1595 1596 numCols int 1597 1598 indexOrdinal int 1599 } 1600 1601 // ID is part of the cat.Index interface. 1602 func (oi *optVirtualIndex) ID() cat.StableID { 1603 return cat.StableID(oi.desc.ID) 1604 } 1605 1606 // Name is part of the cat.Index interface. 1607 func (oi *optVirtualIndex) Name() tree.Name { 1608 return tree.Name(oi.desc.Name) 1609 } 1610 1611 // IsUnique is part of the cat.Index interface. 1612 func (oi *optVirtualIndex) IsUnique() bool { 1613 return oi.desc.Unique 1614 } 1615 1616 // IsInverted is part of the cat.Index interface. 1617 func (oi *optVirtualIndex) IsInverted() bool { 1618 return false 1619 } 1620 1621 // ColumnCount is part of the cat.Index interface. 1622 func (oi *optVirtualIndex) ColumnCount() int { 1623 return oi.numCols 1624 } 1625 1626 // Predicate is part of the cat.Index interface. 1627 func (oi *optVirtualIndex) Predicate() (string, bool) { 1628 return "", false 1629 } 1630 1631 // KeyColumnCount is part of the cat.Index interface. 1632 func (oi *optVirtualIndex) KeyColumnCount() int { 1633 return 1 1634 } 1635 1636 // LaxKeyColumnCount is part of the cat.Index interface. 1637 func (oi *optVirtualIndex) LaxKeyColumnCount() int { 1638 return 1 1639 } 1640 1641 // lookupColumnOrdinal returns the ordinal of the column with the given ID. A 1642 // cache makes the lookup O(1). 1643 func (ot *optVirtualTable) lookupColumnOrdinal(colID sqlbase.ColumnID) (int, error) { 1644 col, ok := ot.colMap[colID] 1645 if ok { 1646 return col, nil 1647 } 1648 return col, pgerror.Newf(pgcode.UndefinedColumn, 1649 "column [%d] does not exist", colID) 1650 } 1651 1652 // Column is part of the cat.Index interface. 1653 func (oi *optVirtualIndex) Column(i int) cat.IndexColumn { 1654 if oi.isPrimary { 1655 return cat.IndexColumn{Column: oi.tab.Column(i), Ordinal: i} 1656 } 1657 if i == oi.ColumnCount()-1 { 1658 // The special bogus PK column goes at the end. It has ID 0. 1659 return cat.IndexColumn{Column: oi.tab.Column(0), Ordinal: 0} 1660 } 1661 length := len(oi.desc.ColumnIDs) 1662 if i < length { 1663 ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.ColumnIDs[i]) 1664 return cat.IndexColumn{ 1665 Column: oi.tab.Column(ord), 1666 Ordinal: ord, 1667 } 1668 } 1669 1670 i -= length 1671 ord, _ := oi.tab.lookupColumnOrdinal(oi.desc.StoreColumnIDs[i]) 1672 return cat.IndexColumn{Column: oi.tab.Column(ord), Ordinal: ord} 1673 } 1674 1675 // Zone is part of the cat.Index interface. 1676 func (oi *optVirtualIndex) Zone() cat.Zone { 1677 panic("no zone") 1678 } 1679 1680 // Span is part of the cat.Index interface. 1681 func (oi *optVirtualIndex) Span() roachpb.Span { 1682 panic("no span") 1683 } 1684 1685 // Table is part of the cat.Index interface. 1686 func (oi *optVirtualIndex) Table() cat.Table { 1687 return oi.tab 1688 } 1689 1690 // Ordinal is part of the cat.Index interface. 1691 func (oi *optVirtualIndex) Ordinal() int { 1692 return oi.indexOrdinal 1693 } 1694 1695 // PartitionByListPrefixes is part of the cat.Index interface. 1696 func (oi *optVirtualIndex) PartitionByListPrefixes() []tree.Datums { 1697 panic("no partition") 1698 } 1699 1700 // InterleaveAncestorCount is part of the cat.Index interface. 1701 func (oi *optVirtualIndex) InterleaveAncestorCount() int { 1702 return 0 1703 } 1704 1705 // InterleaveAncestor is part of the cat.Index interface. 1706 func (oi *optVirtualIndex) InterleaveAncestor(i int) (table, index cat.StableID, numKeyCols int) { 1707 panic("no interleavings") 1708 } 1709 1710 // InterleavedByCount is part of the cat.Index interface. 1711 func (oi *optVirtualIndex) InterleavedByCount() int { 1712 return 0 1713 } 1714 1715 // InterleavedBy is part of the cat.Index interface. 1716 func (oi *optVirtualIndex) InterleavedBy(i int) (table, index cat.StableID) { 1717 panic("no interleavings") 1718 } 1719 1720 // optVirtualFamily is a dummy implementation of cat.Family for the only family 1721 // reported by a virtual table. 1722 type optVirtualFamily struct { 1723 tab *optVirtualTable 1724 } 1725 1726 var _ cat.Family = &optVirtualFamily{} 1727 1728 func (oi *optVirtualFamily) init(tab *optVirtualTable) { 1729 oi.tab = tab 1730 } 1731 1732 // ID is part of the cat.Family interface. 1733 func (oi *optVirtualFamily) ID() cat.StableID { 1734 return 0 1735 } 1736 1737 // Name is part of the cat.Family interface. 1738 func (oi *optVirtualFamily) Name() tree.Name { 1739 return "primary" 1740 } 1741 1742 // ColumnCount is part of the cat.Family interface. 1743 func (oi *optVirtualFamily) ColumnCount() int { 1744 return oi.tab.ColumnCount() 1745 } 1746 1747 // Column is part of the cat.Family interface. 1748 func (oi *optVirtualFamily) Column(i int) cat.FamilyColumn { 1749 return cat.FamilyColumn{Column: oi.tab.Column(i), Ordinal: i} 1750 } 1751 1752 // Table is part of the cat.Family interface. 1753 func (oi *optVirtualFamily) Table() cat.Table { 1754 return oi.tab 1755 }