diff --git a/docs/generated/http/BUILD.bazel b/docs/generated/http/BUILD.bazel index 34c75f1ef1aa..8f7c570c246d 100644 --- a/docs/generated/http/BUILD.bazel +++ b/docs/generated/http/BUILD.bazel @@ -26,6 +26,7 @@ genrule( "//pkg/sql/pgwire/pgerror:pgerror_proto", "//pkg/sql/schemachanger/scpb:scpb_proto", "//pkg/sql/sessiondatapb:sessiondatapb_proto", + "//pkg/sql/sqlstats/insights:insights_proto", "//pkg/sql/types:types_proto", "//pkg/storage/enginepb:enginepb_proto", "//pkg/ts/catalog:catalog_proto", diff --git a/docs/generated/http/full.md b/docs/generated/http/full.md index 4c380bbdda61..845874fe3681 100644 --- a/docs/generated/http/full.md +++ b/docs/generated/http/full.md @@ -4877,6 +4877,52 @@ Support status: [reserved](#support-status) +## ListExecutionInsights + + + +ListExecutionInsights returns potentially problematic statements cluster-wide, +along with actions we suggest the application developer might take to remedy them. + +Support status: [reserved](#support-status) + +#### Request Parameters + + + + + + + +| Field | Type | Label | Description | Support status | +| ----- | ---- | ----- | ----------- | -------------- | +| node_id | [string](#cockroach.server.serverpb.ListExecutionInsightsRequest-string) | | node_id is a string so that "local" can be used to specify that no forwarding is necessary. | [reserved](#support-status) | + + + + + + + +#### Response Parameters + + + + + + + +| Field | Type | Label | Description | Support status | +| ----- | ---- | ----- | ----------- | -------------- | +| insights | [cockroach.sql.insights.Insight](#cockroach.server.serverpb.ListExecutionInsightsResponse-cockroach.sql.insights.Insight) | repeated | insights lists any potentially problematic statements and actions we suggest the application developer might take to remedy them. | [reserved](#support-status) | +| errors | [cockroach.errorspb.EncodedError](#cockroach.server.serverpb.ListExecutionInsightsResponse-cockroach.errorspb.EncodedError) | repeated | errors holds any errors that occurred during fan-out calls to other nodes. | [reserved](#support-status) | + + + + + + + ## RequestCA `GET /_join/v1/ca` diff --git a/pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant b/pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant index 07ea6185c0f9..4108928e244e 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant +++ b/pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant @@ -44,6 +44,7 @@ crdb_internal cluster_contended_tables view admin NULL NULL crdb_internal cluster_contention_events table admin NULL NULL crdb_internal cluster_database_privileges table admin NULL NULL crdb_internal cluster_distsql_flows table admin NULL NULL +crdb_internal cluster_execution_insights table admin NULL NULL crdb_internal cluster_inflight_traces table admin NULL NULL crdb_internal cluster_locks table admin NULL NULL crdb_internal cluster_queries table admin NULL NULL diff --git a/pkg/cli/testdata/zip/partial1 b/pkg/cli/testdata/zip/partial1 index 25b3daea2f51..9c3e7528ef4b 100644 --- a/pkg/cli/testdata/zip/partial1 +++ b/pkg/cli/testdata/zip/partial1 @@ -14,6 +14,7 @@ debug zip --concurrency=1 --cpu-profile-duration=0s /dev/null [cluster] retrieving SQL data for crdb_internal.cluster_contention_events... writing output: debug/crdb_internal.cluster_contention_events.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... writing output: debug/crdb_internal.cluster_distsql_flows.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_database_privileges... writing output: debug/crdb_internal.cluster_database_privileges.txt... done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... writing output: debug/crdb_internal.cluster_execution_insights.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_locks... writing output: debug/crdb_internal.cluster_locks.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_queries... writing output: debug/crdb_internal.cluster_queries.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_sessions... writing output: debug/crdb_internal.cluster_sessions.txt... done diff --git a/pkg/cli/testdata/zip/partial1_excluded b/pkg/cli/testdata/zip/partial1_excluded index b94b6d7f76ba..4ded927c3c50 100644 --- a/pkg/cli/testdata/zip/partial1_excluded +++ b/pkg/cli/testdata/zip/partial1_excluded @@ -14,6 +14,7 @@ debug zip /dev/null --concurrency=1 --exclude-nodes=2 --cpu-profile-duration=0 [cluster] retrieving SQL data for crdb_internal.cluster_contention_events... writing output: debug/crdb_internal.cluster_contention_events.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... writing output: debug/crdb_internal.cluster_distsql_flows.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_database_privileges... writing output: debug/crdb_internal.cluster_database_privileges.txt... done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... writing output: debug/crdb_internal.cluster_execution_insights.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_locks... writing output: debug/crdb_internal.cluster_locks.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_queries... writing output: debug/crdb_internal.cluster_queries.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_sessions... writing output: debug/crdb_internal.cluster_sessions.txt... done diff --git a/pkg/cli/testdata/zip/partial2 b/pkg/cli/testdata/zip/partial2 index fd8a0d36d5f3..2084458f8216 100644 --- a/pkg/cli/testdata/zip/partial2 +++ b/pkg/cli/testdata/zip/partial2 @@ -14,6 +14,7 @@ debug zip --concurrency=1 --cpu-profile-duration=0 /dev/null [cluster] retrieving SQL data for crdb_internal.cluster_contention_events... writing output: debug/crdb_internal.cluster_contention_events.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... writing output: debug/crdb_internal.cluster_distsql_flows.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_database_privileges... writing output: debug/crdb_internal.cluster_database_privileges.txt... done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... writing output: debug/crdb_internal.cluster_execution_insights.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_locks... writing output: debug/crdb_internal.cluster_locks.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_queries... writing output: debug/crdb_internal.cluster_queries.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_sessions... writing output: debug/crdb_internal.cluster_sessions.txt... done diff --git a/pkg/cli/testdata/zip/testzip b/pkg/cli/testdata/zip/testzip index 5da5334e4762..1303de6514af 100644 --- a/pkg/cli/testdata/zip/testzip +++ b/pkg/cli/testdata/zip/testzip @@ -14,6 +14,7 @@ debug zip --concurrency=1 --cpu-profile-duration=1s /dev/null [cluster] retrieving SQL data for crdb_internal.cluster_contention_events... writing output: debug/crdb_internal.cluster_contention_events.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... writing output: debug/crdb_internal.cluster_distsql_flows.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_database_privileges... writing output: debug/crdb_internal.cluster_database_privileges.txt... done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... writing output: debug/crdb_internal.cluster_execution_insights.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_locks... writing output: debug/crdb_internal.cluster_locks.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_queries... writing output: debug/crdb_internal.cluster_queries.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_sessions... writing output: debug/crdb_internal.cluster_sessions.txt... done diff --git a/pkg/cli/testdata/zip/testzip_concurrent b/pkg/cli/testdata/zip/testzip_concurrent index 3ae03e4a985b..f47dfc2bc278 100644 --- a/pkg/cli/testdata/zip/testzip_concurrent +++ b/pkg/cli/testdata/zip/testzip_concurrent @@ -67,6 +67,9 @@ zip [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows: done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows: writing output: debug/crdb_internal.cluster_distsql_flows.txt... +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights: done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights: writing output: debug/crdb_internal.cluster_execution_insights.txt... [cluster] retrieving SQL data for crdb_internal.cluster_locks... [cluster] retrieving SQL data for crdb_internal.cluster_locks: done [cluster] retrieving SQL data for crdb_internal.cluster_locks: writing output: debug/crdb_internal.cluster_locks.txt... diff --git a/pkg/cli/testdata/zip/testzip_tenant b/pkg/cli/testdata/zip/testzip_tenant index 66975cc521b2..522a300be7d9 100644 --- a/pkg/cli/testdata/zip/testzip_tenant +++ b/pkg/cli/testdata/zip/testzip_tenant @@ -22,6 +22,7 @@ debug zip --concurrency=1 --cpu-profile-duration=1s /dev/null [cluster] retrieving SQL data for crdb_internal.cluster_contention_events... writing output: debug/crdb_internal.cluster_contention_events.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_distsql_flows... writing output: debug/crdb_internal.cluster_distsql_flows.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_database_privileges... writing output: debug/crdb_internal.cluster_database_privileges.txt... done +[cluster] retrieving SQL data for crdb_internal.cluster_execution_insights... writing output: debug/crdb_internal.cluster_execution_insights.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_locks... writing output: debug/crdb_internal.cluster_locks.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_queries... writing output: debug/crdb_internal.cluster_queries.txt... done [cluster] retrieving SQL data for crdb_internal.cluster_sessions... writing output: debug/crdb_internal.cluster_sessions.txt... done diff --git a/pkg/cli/zip_cluster_wide.go b/pkg/cli/zip_cluster_wide.go index e9ce7581a1c8..36634d7dd95f 100644 --- a/pkg/cli/zip_cluster_wide.go +++ b/pkg/cli/zip_cluster_wide.go @@ -78,6 +78,7 @@ var debugZipTablesPerCluster = []string{ "crdb_internal.cluster_contention_events", "crdb_internal.cluster_distsql_flows", "crdb_internal.cluster_database_privileges", + "crdb_internal.cluster_execution_insights", "crdb_internal.cluster_locks", "crdb_internal.cluster_queries", "crdb_internal.cluster_sessions", diff --git a/pkg/kv/kvserver/gc/BUILD.bazel b/pkg/kv/kvserver/gc/BUILD.bazel index 04eb2d0207df..ea194595d61b 100644 --- a/pkg/kv/kvserver/gc/BUILD.bazel +++ b/pkg/kv/kvserver/gc/BUILD.bazel @@ -19,6 +19,7 @@ go_library( "//pkg/storage", "//pkg/storage/enginepb", "//pkg/util", + "//pkg/util/admission/admissionpb", "//pkg/util/bufalloc", "//pkg/util/contextutil", "//pkg/util/hlc", diff --git a/pkg/kv/kvserver/gc/gc.go b/pkg/kv/kvserver/gc/gc.go index ea4f84593c67..8a575f20da10 100644 --- a/pkg/kv/kvserver/gc/gc.go +++ b/pkg/kv/kvserver/gc/gc.go @@ -30,6 +30,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/storage" "github.com/cockroachdb/cockroach/pkg/storage/enginepb" "github.com/cockroachdb/cockroach/pkg/util" + "github.com/cockroachdb/cockroach/pkg/util/admission/admissionpb" "github.com/cockroachdb/cockroach/pkg/util/bufalloc" "github.com/cockroachdb/cockroach/pkg/util/contextutil" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -115,6 +116,20 @@ var MaxIntentKeyBytesPerCleanupBatch = settings.RegisterIntSetting( settings.NonNegativeInt, ) +// AdmissionPriority determines the admission priority level to use for MVCC GC +// work. +var AdmissionPriority = settings.RegisterEnumSetting( + settings.SystemOnly, + "kv.gc.admission_priority", + "the admission priority to use for mvcc gc work", + "bulk_normal_pri", + map[int64]string{ + int64(admissionpb.BulkNormalPri): "bulk_normal_pri", + int64(admissionpb.NormalPri): "normal_pri", + int64(admissionpb.UserHighPri): "user_high_pri", + }, +) + // CalculateThreshold calculates the GC threshold given the policy and the // current view of time. func CalculateThreshold(now hlc.Timestamp, gcttl time.Duration) (threshold hlc.Timestamp) { diff --git a/pkg/kv/kvserver/mvcc_gc_queue.go b/pkg/kv/kvserver/mvcc_gc_queue.go index 9f41d3d6aa30..6ae63c1fae5c 100644 --- a/pkg/kv/kvserver/mvcc_gc_queue.go +++ b/pkg/kv/kvserver/mvcc_gc_queue.go @@ -22,6 +22,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/kv/kvserver/gc" "github.com/cockroachdb/cockroach/pkg/kv/kvserver/intentresolver" "github.com/cockroachdb/cockroach/pkg/roachpb" + "github.com/cockroachdb/cockroach/pkg/settings" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/spanconfig" "github.com/cockroachdb/cockroach/pkg/storage/enginepb" @@ -35,9 +36,9 @@ import ( ) const ( - // mvccGCQueueTimerDuration is the duration between MVCC GCs of queued - // replicas. - mvccGCQueueTimerDuration = 1 * time.Second + // mvccGCQueueDefaultTimerDuration is the default duration between MVCC GCs + // of queued replicas. + mvccGCQueueDefaultTimerDuration = 1 * time.Second // mvccGCQueueTimeout is the timeout for a single MVCC GC run. mvccGCQueueTimeout = 10 * time.Minute // mvccGCQueueIntentBatchTimeout is the timeout for resolving a single batch @@ -64,6 +65,16 @@ const ( largeAbortSpanBytesThreshold = 16 * (1 << 20) // 16mb ) +// mvccGCQueueInterval is a setting that controls how long the mvcc GC queue +// waits between processing replicas. +var mvccGCQueueInterval = settings.RegisterDurationSetting( + settings.SystemOnly, + "kv.mvcc_gc.queue_interval", + "how long the mvcc gc queue waits between processing replicas", + mvccGCQueueDefaultTimerDuration, + settings.NonNegativeDuration, +) + func largeAbortSpan(ms enginepb.MVCCStats) bool { // Checks if the size of the abort span exceeds the given threshold. // The abort span is not supposed to become that large, but it does @@ -445,17 +456,32 @@ func (r *replicaGCer) send(ctx context.Context, req roachpb.GCRequest) error { // admission control here, as we are bypassing server.Node. var admissionHandle interface{} if r.admissionController != nil { + pri := admissionpb.WorkPriority(gc.AdmissionPriority.Get(&r.repl.ClusterSettings().SV)) ba.AdmissionHeader = roachpb.AdmissionHeader{ - // GC is currently assigned NormalPri. + // TODO(irfansharif): GC could be expected to be BulkNormalPri, so + // that it does not impact user-facing traffic when resources (e.g. + // CPU, write capacity of the store) are scarce. However long delays + // in GC can slow down user-facing traffic due to more versions in + // the store, and can increase write amplification of the store + // since there is more live data. Ideally, we should adjust this + // priority based on how far behind we are with respect to GC-ing + // data in this range. Keeping it static at NormalPri proved + // disruptive when a large volume of MVCC GC work is suddenly + // accrued (if an old protected timestamp record was just released + // for ex. following a long paused backup job being + // completed/canceled, or just an old, long running backup job + // finishing). For now, use a cluster setting that defaults to + // BulkNormalPri. // - // TODO(kv): GC could be expected to be LowPri, so that it does not - // impact user-facing traffic when resources (e.g. CPU, write capacity - // of the store) are scarce. However long delays in GC can slow down - // user-facing traffic due to more versions in the store, and can - // increase write amplification of the store since there is more live - // data. Ideally, we should adjust this priority based on how far behind - // we are wrt GCing in this range. - Priority: int32(admissionpb.NormalPri), + // After we implement dynamic priority adjustment, it's not clear + // whether we need additional pacing mechanisms to provide better + // latency isolation similar to ongoing work for backups (since MVCC + // GC work is CPU intensive): #82955. It's also worth noting that we + // might be able to do most MVCC GC work as part of regular + // compactions (#42514) -- the CPU use by the MVCC GC queue during + // keyspace might still be worth explicitly accounting/limiting, but + // it'll be lessened overall. + Priority: int32(pri), CreateTime: timeutil.Now().UnixNano(), Source: roachpb.AdmissionHeader_ROOT_KV, NoMemoryReservedAtSource: true, @@ -673,8 +699,8 @@ func updateStoreMetricsWithGCInfo(metrics *StoreMetrics, info gc.Info) { // timer returns a constant duration to space out GC processing // for successive queued replicas. -func (*mvccGCQueue) timer(_ time.Duration) time.Duration { - return mvccGCQueueTimerDuration +func (mgcq *mvccGCQueue) timer(_ time.Duration) time.Duration { + return mvccGCQueueInterval.Get(&mgcq.store.ClusterSettings().SV) } // purgatoryChan returns nil. diff --git a/pkg/server/BUILD.bazel b/pkg/server/BUILD.bazel index 4b5e1ad370cc..dc765f99c9f2 100644 --- a/pkg/server/BUILD.bazel +++ b/pkg/server/BUILD.bazel @@ -204,6 +204,7 @@ go_library( "//pkg/sql/sqlliveness", "//pkg/sql/sqlliveness/slprovider", "//pkg/sql/sqlstats", + "//pkg/sql/sqlstats/insights", "//pkg/sql/sqlstats/persistedsqlstats", "//pkg/sql/sqlstats/persistedsqlstats/sqlstatsutil", "//pkg/sql/sqlutil", diff --git a/pkg/server/serverpb/BUILD.bazel b/pkg/server/serverpb/BUILD.bazel index 21d820aec110..31f11471ebcd 100644 --- a/pkg/server/serverpb/BUILD.bazel +++ b/pkg/server/serverpb/BUILD.bazel @@ -29,12 +29,14 @@ proto_library( "//pkg/server/diagnostics/diagnosticspb:diagnosticspb_proto", "//pkg/server/status/statuspb:statuspb_proto", "//pkg/sql/contentionpb:contentionpb_proto", + "//pkg/sql/sqlstats/insights:insights_proto", "//pkg/storage/enginepb:enginepb_proto", "//pkg/ts/catalog:catalog_proto", "//pkg/util:util_proto", "//pkg/util/log/logpb:logpb_proto", "//pkg/util/metric:metric_proto", "//pkg/util/tracing/tracingpb:tracingpb_proto", + "@com_github_cockroachdb_errors//errorspb:errorspb_proto", "@com_github_gogo_protobuf//gogoproto:gogo_proto", "@com_google_protobuf//:duration_proto", "@com_google_protobuf//:timestamp_proto", @@ -68,6 +70,7 @@ go_proto_library( "//pkg/sql/contentionpb", "//pkg/sql/execinfrapb", # keep "//pkg/sql/pgwire/pgwirecancel", # keep + "//pkg/sql/sqlstats/insights", "//pkg/storage/enginepb", "//pkg/ts/catalog", "//pkg/util", @@ -75,6 +78,7 @@ go_proto_library( "//pkg/util/metric", "//pkg/util/tracing/tracingpb", "//pkg/util/uuid", # keep + "@com_github_cockroachdb_errors//errorspb", "@com_github_gogo_protobuf//gogoproto", # NB: The grpc-gateway compiler injects a dependency on the descriptor # package that Gazelle isn't prepared to deal with. diff --git a/pkg/server/serverpb/status.go b/pkg/server/serverpb/status.go index 0072ed4523ae..7be06399d29e 100644 --- a/pkg/server/serverpb/status.go +++ b/pkg/server/serverpb/status.go @@ -40,6 +40,7 @@ type SQLStatusServer interface { TxnIDResolution(context.Context, *TxnIDResolutionRequest) (*TxnIDResolutionResponse, error) TransactionContentionEvents(context.Context, *TransactionContentionEventsRequest) (*TransactionContentionEventsResponse, error) NodesList(context.Context, *NodesListRequest) (*NodesListResponse, error) + ListExecutionInsights(context.Context, *ListExecutionInsightsRequest) (*ListExecutionInsightsResponse, error) } // OptionalNodesStatusServer is a StatusServer that is only optionally present diff --git a/pkg/server/serverpb/status.proto b/pkg/server/serverpb/status.proto index e982fbc55801..9562d4ce8862 100644 --- a/pkg/server/serverpb/status.proto +++ b/pkg/server/serverpb/status.proto @@ -13,6 +13,7 @@ package cockroach.server.serverpb; option go_package = "serverpb"; import "build/info.proto"; +import "errorspb/errors.proto"; import "gossip/gossip.proto"; import "jobs/jobspb/jobs.proto"; import "roachpb/app_stats.proto"; @@ -23,6 +24,7 @@ import "server/diagnostics/diagnosticspb/diagnostics.proto"; import "server/serverpb/index_recommendations.proto"; import "server/status/statuspb/status.proto"; import "sql/contentionpb/contention.proto"; +import "sql/sqlstats/insights/insights.proto"; import "storage/enginepb/engine.proto"; import "storage/enginepb/mvcc.proto"; import "storage/enginepb/rocksdb.proto"; @@ -1824,6 +1826,27 @@ message TransactionContentionEventsResponse { ]; } +message ListExecutionInsightsRequest { + // node_id is a string so that "local" can be used to specify that no + // forwarding is necessary. + string node_id = 1 [ + (gogoproto.customname) = "NodeID" + ]; +} + +message ListExecutionInsightsResponse { + // insights lists any potentially problematic statements and actions we + // suggest the application developer might take to remedy them. + repeated cockroach.sql.insights.Insight insights = 1 [ + (gogoproto.nullable) = false + ]; + + // errors holds any errors that occurred during fan-out calls to other nodes. + repeated errorspb.EncodedError errors = 2 [ + (gogoproto.nullable) = false + ]; +} + service Status { // Certificates retrieves a copy of the TLS certificates. rpc Certificates(CertificatesRequest) returns (CertificatesResponse) { @@ -2260,4 +2283,8 @@ service Status { get: "/_status/transactioncontentionevents" }; } + + // ListExecutionInsights returns potentially problematic statements cluster-wide, + // along with actions we suggest the application developer might take to remedy them. + rpc ListExecutionInsights(ListExecutionInsightsRequest) returns (ListExecutionInsightsResponse) {} } diff --git a/pkg/server/status.go b/pkg/server/status.go index 026bea2bdafc..eb4f910333a4 100644 --- a/pkg/server/status.go +++ b/pkg/server/status.go @@ -63,6 +63,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/roleoption" "github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants" + "github.com/cockroachdb/cockroach/pkg/sql/sqlstats/insights" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/contextutil" "github.com/cockroachdb/cockroach/pkg/util/grpcutil" @@ -418,6 +419,19 @@ func (b *baseStatusServer) ListLocalDistSQLFlows( return response, nil } +func (b *baseStatusServer) localExecutionInsights( + ctx context.Context, +) (*serverpb.ListExecutionInsightsResponse, error) { + var response serverpb.ListExecutionInsightsResponse + + reader := b.sqlServer.pgServer.SQLServer.GetSQLStatsProvider() + reader.IterateInsights(ctx, func(ctx context.Context, insight *insights.Insight) { + response.Insights = append(response.Insights, *insight) + }) + + return &response, nil +} + func (b *baseStatusServer) localTxnIDResolution( req *serverpb.TxnIDResolutionRequest, ) *serverpb.TxnIDResolutionResponse { @@ -3105,6 +3119,66 @@ func mergeDistSQLRemoteFlows(a, b []serverpb.DistSQLRemoteFlows) []serverpb.Dist return result } +func (s *statusServer) ListExecutionInsights( + ctx context.Context, req *serverpb.ListExecutionInsightsRequest, +) (*serverpb.ListExecutionInsightsResponse, error) { + ctx = propagateGatewayMetadata(ctx) + ctx = s.AnnotateCtx(ctx) + + // Check permissions early to avoid fan-out to all nodes. + if err := s.privilegeChecker.requireViewActivityOrViewActivityRedactedPermission(ctx); err != nil { + // NB: not using serverError() here since the priv checker + // already returns a proper gRPC error status. + return nil, err + } + + localRequest := serverpb.ListExecutionInsightsRequest{NodeID: "local"} + + if len(req.NodeID) > 0 { + requestedNodeID, local, err := s.parseNodeID(req.NodeID) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, err.Error()) + } + if local { + return s.localExecutionInsights(ctx) + } + statusClient, err := s.dialNode(ctx, requestedNodeID) + if err != nil { + return nil, serverError(ctx, err) + } + return statusClient.ListExecutionInsights(ctx, &localRequest) + } + + var response serverpb.ListExecutionInsightsResponse + + dialFn := func(ctx context.Context, nodeID roachpb.NodeID) (interface{}, error) { + return s.dialNode(ctx, nodeID) + } + nodeFn := func(ctx context.Context, client interface{}, nodeID roachpb.NodeID) (interface{}, error) { + statusClient := client.(serverpb.StatusClient) + resp, err := statusClient.ListExecutionInsights(ctx, &localRequest) + if err != nil { + return nil, err + } + return resp, nil + } + responseFn := func(nodeID roachpb.NodeID, nodeResponse interface{}) { + if nodeResponse == nil { + return + } + insightsResponse := nodeResponse.(*serverpb.ListExecutionInsightsResponse) + response.Insights = append(response.Insights, insightsResponse.Insights...) + } + errorFn := func(nodeID roachpb.NodeID, err error) { + response.Errors = append(response.Errors, errors.EncodeError(ctx, err)) + } + + if err := s.iterateNodes(ctx, "execution insights list", dialFn, nodeFn, responseFn, errorFn); err != nil { + return nil, serverError(ctx, err) + } + return &response, nil +} + // SpanStats requests the total statistics stored on a node for a given key // span, which may include multiple ranges. func (s *statusServer) SpanStats( diff --git a/pkg/server/tenant_status.go b/pkg/server/tenant_status.go index 775664cf573d..d007eeabf8fe 100644 --- a/pkg/server/tenant_status.go +++ b/pkg/server/tenant_status.go @@ -401,6 +401,71 @@ func (t *tenantStatusServer) ListLocalContentionEvents( return t.baseStatusServer.ListLocalContentionEvents(ctx, req) } +func (t *tenantStatusServer) ListExecutionInsights( + ctx context.Context, req *serverpb.ListExecutionInsightsRequest, +) (*serverpb.ListExecutionInsightsResponse, error) { + ctx = propagateGatewayMetadata(ctx) + ctx = t.AnnotateCtx(ctx) + + // Check permissions early to avoid fan-out to all nodes. + if err := t.privilegeChecker.requireViewActivityOrViewActivityRedactedPermission(ctx); err != nil { + // NB: not using serverError() here since the priv checker + // already returns a proper gRPC error status. + return nil, err + } + + if t.sqlServer.SQLInstanceID() == 0 { + return nil, status.Errorf(codes.Unavailable, "instanceID not set") + } + + localRequest := serverpb.ListExecutionInsightsRequest{NodeID: "local"} + + if len(req.NodeID) > 0 { + requestedInstanceID, local, err := t.parseInstanceID(req.NodeID) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, err.Error()) + } + if local { + return t.baseStatusServer.localExecutionInsights(ctx) + } + instance, err := t.sqlServer.sqlInstanceProvider.GetInstance(ctx, requestedInstanceID) + if err != nil { + return nil, err + } + statusClient, err := t.dialPod(ctx, requestedInstanceID, instance.InstanceAddr) + if err != nil { + return nil, err + } + return statusClient.ListExecutionInsights(ctx, &localRequest) + } + + var response serverpb.ListExecutionInsightsResponse + + podFn := func(ctx context.Context, client interface{}, _ base.SQLInstanceID) (interface{}, error) { + statusClient := client.(serverpb.StatusClient) + resp, err := statusClient.ListExecutionInsights(ctx, &localRequest) + if err != nil { + return nil, err + } + return resp, nil + } + responseFn := func(_ base.SQLInstanceID, nodeResp interface{}) { + if nodeResp == nil { + return + } + insightsResponse := nodeResp.(*serverpb.ListExecutionInsightsResponse) + response.Insights = append(response.Insights, insightsResponse.Insights...) + } + errorFn := func(instanceID base.SQLInstanceID, err error) { + response.Errors = append(response.Errors, errors.EncodeError(ctx, err)) + } + + if err := t.iteratePods(ctx, "execution insights list", t.dialCallback, podFn, responseFn, errorFn); err != nil { + return nil, err + } + return &response, nil +} + func (t *tenantStatusServer) ResetSQLStats( ctx context.Context, req *serverpb.ResetSQLStatsRequest, ) (*serverpb.ResetSQLStatsResponse, error) { diff --git a/pkg/sql/BUILD.bazel b/pkg/sql/BUILD.bazel index b8cbea24f274..26a94b9db3d2 100644 --- a/pkg/sql/BUILD.bazel +++ b/pkg/sql/BUILD.bazel @@ -546,6 +546,7 @@ go_test( "distsql_plan_bulk_test.go", "distsql_plan_set_op_test.go", "distsql_running_test.go", + "drop_function_test.go", "drop_helpers_test.go", "drop_test.go", "err_count_test.go", diff --git a/pkg/sql/alter_column_type.go b/pkg/sql/alter_column_type.go index 4b3da2d909d3..1aaf709b6c4a 100644 --- a/pkg/sql/alter_column_type.go +++ b/pkg/sql/alter_column_type.go @@ -66,9 +66,6 @@ func AlterColumnType( tn *tree.TableName, ) error { for _, tableRef := range tableDesc.DependedOnBy { - if err := params.p.maybeFailOnDroppingFunction(ctx, tableRef.ID); err != nil { - return err - } found := false for _, colID := range tableRef.ColumnIDs { if colID == col.GetID() { @@ -76,7 +73,7 @@ func AlterColumnType( } } if found { - return params.p.dependentViewError( + return params.p.dependentError( ctx, "column", col.GetName(), tableDesc.ParentID, tableRef.ID, "alter type of", ) } diff --git a/pkg/sql/alter_table.go b/pkg/sql/alter_table.go index dc3db15d0862..e1be7f6e2b4c 100644 --- a/pkg/sql/alter_table.go +++ b/pkg/sql/alter_table.go @@ -26,6 +26,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog/catpb" "github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver" "github.com/cockroachdb/cockroach/pkg/sql/catalog/schemaexpr" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" @@ -836,7 +837,7 @@ func (n *alterTableNode) startExec(params runParams) error { } depViewRenameError := func(objType string, refTableID descpb.ID) error { - return params.p.dependentViewError(params.ctx, + return params.p.dependentError(params.ctx, objType, tree.ErrString(&t.NewName), n.tableDesc.ParentID, refTableID, "rename", ) } @@ -1589,9 +1590,6 @@ func dropColumnImpl( // You can't drop a column depended on by a view unless CASCADE was // specified. for _, ref := range tableDesc.DependedOnBy { - if err := params.p.maybeFailOnDroppingFunction(params.ctx, ref.ID); err != nil { - return nil, err - } found := false for _, colID := range ref.ColumnIDs { if colID == colToDrop.GetID() { @@ -1602,31 +1600,38 @@ func dropColumnImpl( if !found { continue } - err := params.p.canRemoveDependentViewGeneric( + err := params.p.canRemoveDependent( params.ctx, "column", string(t.Column), tableDesc.ParentID, ref, t.DropBehavior, ) if err != nil { return nil, err } - viewDesc, err := params.p.getViewDescForCascade( + depDesc, err := params.p.getDescForCascade( params.ctx, "column", string(t.Column), tableDesc.ParentID, ref.ID, t.DropBehavior, ) if err != nil { return nil, err } - jobDesc := fmt.Sprintf("removing view %q dependent on column %q which is being dropped", - viewDesc.Name, colToDrop.ColName()) - cascadedViews, err := params.p.removeDependentView(params.ctx, tableDesc, viewDesc, jobDesc) - if err != nil { - return nil, err - } - qualifiedView, err := params.p.getQualifiedTableName(params.ctx, viewDesc) - if err != nil { - return nil, err - } + switch t := depDesc.(type) { + case *tabledesc.Mutable: + jobDesc := fmt.Sprintf("removing view %q dependent on column %q which is being dropped", + t.Name, colToDrop.ColName()) + cascadedViews, err := params.p.removeDependentView(params.ctx, tableDesc, t, jobDesc) + if err != nil { + return nil, err + } + qualifiedView, err := params.p.getQualifiedTableName(params.ctx, t) + if err != nil { + return nil, err + } - droppedViews = append(droppedViews, cascadedViews...) - droppedViews = append(droppedViews, qualifiedView.FQString()) + droppedViews = append(droppedViews, cascadedViews...) + droppedViews = append(droppedViews, qualifiedView.FQString()) + case *funcdesc.Mutable: + if err := params.p.removeDependentFunction(params.ctx, tableDesc, t); err != nil { + return nil, err + } + } } // We cannot remove this column if there are computed columns that use it. diff --git a/pkg/sql/alter_table_set_schema.go b/pkg/sql/alter_table_set_schema.go index 835bc3c4b49e..a705b4c1a84a 100644 --- a/pkg/sql/alter_table_set_schema.go +++ b/pkg/sql/alter_table_set_schema.go @@ -80,11 +80,8 @@ func (p *planner) AlterTableSetSchema( // Check if any objects depend on this table/view/sequence via its name. // If so, then we disallow renaming, otherwise we allow it. for _, dependent := range tableDesc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, dependent.ID); err != nil { - return nil, err - } if !dependent.ByID { - return nil, p.dependentViewError( + return nil, p.dependentError( ctx, string(tableDesc.DescriptorType()), tableDesc.Name, tableDesc.ParentID, dependent.ID, "set schema on", ) diff --git a/pkg/sql/catalog/descs/function.go b/pkg/sql/catalog/descs/function.go index 43b94cdd2b95..d87e3c5c6136 100644 --- a/pkg/sql/catalog/descs/function.go +++ b/pkg/sql/catalog/descs/function.go @@ -12,13 +12,12 @@ package descs import ( "context" - "strconv" "github.com/cockroachdb/cockroach/pkg/kv" "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/sql/sqlerrors" "github.com/cockroachdb/errors" ) @@ -34,20 +33,32 @@ func (tc *Collection) GetImmutableFunctionByID( return desc, nil } +// GetMutableFunctionByID returns a mutable function descriptor. +func (tc *Collection) GetMutableFunctionByID( + ctx context.Context, txn *kv.Txn, fnID descpb.ID, flags tree.ObjectLookupFlags, +) (*funcdesc.Mutable, error) { + flags.RequireMutable = true + desc, err := tc.getFunctionByID(ctx, txn, fnID, flags) + if err != nil { + return nil, err + } + return desc.(*funcdesc.Mutable), nil +} + func (tc *Collection) getFunctionByID( ctx context.Context, txn *kv.Txn, fnID descpb.ID, flags tree.ObjectLookupFlags, ) (catalog.FunctionDescriptor, error) { descs, err := tc.getDescriptorsByID(ctx, txn, flags.CommonLookupFlags, fnID) if err != nil { if errors.Is(err, catalog.ErrDescriptorNotFound) { - return nil, sqlerrors.NewUndefinedFunctionError(strconv.Itoa(int(fnID))) + return nil, errors.Wrapf(tree.ErrFunctionUndefined, "function %d does not exist", fnID) } return nil, err } fn, ok := descs[0].(catalog.FunctionDescriptor) if !ok { - return nil, sqlerrors.NewUndefinedFunctionError(strconv.Itoa(int(fnID))) + return nil, errors.Wrapf(tree.ErrFunctionUndefined, "function %d does not exist", fnID) } hydrated, err := tc.hydrateTypesInDescWithOptions(ctx, txn, fn, flags.IncludeOffline, flags.AvoidLeased) diff --git a/pkg/sql/catalog/descs/schema.go b/pkg/sql/catalog/descs/schema.go index 0e55a8a19f04..9a408f2e809b 100644 --- a/pkg/sql/catalog/descs/schema.go +++ b/pkg/sql/catalog/descs/schema.go @@ -120,6 +120,19 @@ func (tc *Collection) GetImmutableSchemaByID( return tc.getSchemaByID(ctx, txn, schemaID, flags) } +// GetMutableSchemaByID returns a mutable schema descriptor with the given +// schema ID. +func (tc *Collection) GetMutableSchemaByID( + ctx context.Context, txn *kv.Txn, schemaID descpb.ID, flags tree.SchemaLookupFlags, +) (*schemadesc.Mutable, error) { + flags.RequireMutable = true + desc, err := tc.getSchemaByID(ctx, txn, schemaID, flags) + if err != nil { + return nil, err + } + return desc.(*schemadesc.Mutable), nil +} + // GetImmutableSchemaByName returns a ResolvedSchema wrapping an immutable // descriptor, if applicable. RequireMutable is ignored. // Required is ignored, and an error is always returned if no descriptor with diff --git a/pkg/sql/catalog/resolver/resolver.go b/pkg/sql/catalog/resolver/resolver.go index 0b9a183c6402..c89479fb81be 100644 --- a/pkg/sql/catalog/resolver/resolver.go +++ b/pkg/sql/catalog/resolver/resolver.go @@ -43,6 +43,7 @@ type SchemaResolver interface { ObjectNameTargetResolver tree.QualifiedNameResolver tree.TypeReferenceResolver + tree.FunctionReferenceResolver // Accessor is a crufty name and interface that wraps the *descs.Collection. Accessor() catalog.Accessor diff --git a/pkg/sql/catalog/schemadesc/schema_desc.go b/pkg/sql/catalog/schemadesc/schema_desc.go index 41731906406a..1244cf16c535 100644 --- a/pkg/sql/catalog/schemadesc/schema_desc.go +++ b/pkg/sql/catalog/schemadesc/schema_desc.go @@ -403,6 +403,22 @@ func (desc *Mutable) AddFunction(name string, f descpb.SchemaDescriptor_Function } } +// RemoveFunction removes a UDF overload signature from the schema descriptor. +func (desc *Mutable) RemoveFunction(name string, id descpb.ID) { + if fn, ok := desc.Functions[name]; ok { + updated := fn.Overloads[:0] + for _, ol := range fn.Overloads { + if ol.ID != id { + updated = append(updated, ol) + } + } + desc.Functions[name] = descpb.SchemaDescriptor_Function{ + Name: name, + Overloads: updated, + } + } +} + // GetObjectType implements the PrivilegeObject interface. func (desc *immutable) GetObjectType() privilege.ObjectType { return privilege.Schema diff --git a/pkg/sql/catalog/schemaexpr/expr.go b/pkg/sql/catalog/schemaexpr/expr.go index e9443e5aa1f0..b91bb9f572f0 100644 --- a/pkg/sql/catalog/schemaexpr/expr.go +++ b/pkg/sql/catalog/schemaexpr/expr.go @@ -26,6 +26,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/volatility" "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" "github.com/cockroachdb/errors" ) @@ -113,6 +114,10 @@ func DequalifyAndValidateExpr( return "", nil, colIDs, err } + if err := tree.MaybeFailOnUDFUsage(typedExpr); err != nil { + return "", nil, colIDs, unimplemented.NewWithIssue(83234, "usage of user-defined function from relations not supported") + } + return tree.Serialize(typedExpr), typedExpr.ResolvedType(), colIDs, nil } diff --git a/pkg/sql/catalog/tabledesc/table.go b/pkg/sql/catalog/tabledesc/table.go index a69e518be278..bb50524cd0e3 100644 --- a/pkg/sql/catalog/tabledesc/table.go +++ b/pkg/sql/catalog/tabledesc/table.go @@ -166,6 +166,9 @@ func MakeColumnDefDescs( if err != nil { return nil, err } + if err := tree.MaybeFailOnUDFUsage(ret.DefaultExpr); err != nil { + return nil, err + } // Keep the type checked expression so that the type annotation gets // properly stored, only if the default expression is not NULL. @@ -186,6 +189,9 @@ func MakeColumnDefDescs( if err != nil { return nil, err } + if err := tree.MaybeFailOnUDFUsage(ret.OnUpdateExpr); err != nil { + return nil, err + } d.OnUpdateExpr.Expr = ret.OnUpdateExpr s := tree.Serialize(d.OnUpdateExpr.Expr) diff --git a/pkg/sql/colexec/colexecbase/BUILD.bazel b/pkg/sql/colexec/colexecbase/BUILD.bazel index 500344630793..6df7ced15b72 100644 --- a/pkg/sql/colexec/colexecbase/BUILD.bazel +++ b/pkg/sql/colexec/colexecbase/BUILD.bazel @@ -74,14 +74,12 @@ go_test( "//pkg/sql/randgen", "//pkg/sql/sem/cast", "//pkg/sql/sem/eval", - "//pkg/sql/sem/tree", "//pkg/sql/types", "//pkg/testutils/skip", "//pkg/util/leaktest", "//pkg/util/log", "//pkg/util/mon", "//pkg/util/randutil", - "@com_github_lib_pq//oid", "@com_github_stretchr_testify//require", ], ) diff --git a/pkg/sql/colexec/colexecbase/cast.eg.go b/pkg/sql/colexec/colexecbase/cast.eg.go index 0b8c12dbee21..450b140b0977 100644 --- a/pkg/sql/colexec/colexecbase/cast.eg.go +++ b/pkg/sql/colexec/colexecbase/cast.eg.go @@ -94,7 +94,15 @@ func GetCastOperator( return &castOpNullAny{castOpBase: base}, nil } if isIdentityCast(fromType, toType) { - return &castIdentityOp{castOpBase: base}, nil + // bpchars require special handling. + if toType.Oid() == oid.T_bpchar { + return &castBPCharIdentityOp{castOpBase: base}, nil + } + // If we don't have an array of bpchars, then we use the identity, + // otherwise we'll fallback to datum-datum cast below. + if toType.Oid() != oid.T__bpchar { + return &castIdentityOp{castOpBase: base}, nil + } } isFromDatum := typeconv.TypeFamilyToCanonicalTypeFamily(fromType.Family()) == typeconv.DatumVecCanonicalTypeFamily isToDatum := typeconv.TypeFamilyToCanonicalTypeFamily(toType.Family()) == typeconv.DatumVecCanonicalTypeFamily @@ -1214,6 +1222,50 @@ func (c *castIdentityOp) Next() coldata.Batch { return batch } +// castBPCharIdentityOp is a specialization of castIdentityOp which handles +// casts to the bpchar type (which trims trailing whitespaces). +type castBPCharIdentityOp struct { + castOpBase +} + +var _ colexecop.ClosableOperator = &castBPCharIdentityOp{} + +func (c *castBPCharIdentityOp) Next() coldata.Batch { + batch := c.Input.Next() + n := batch.Length() + if n == 0 { + return coldata.ZeroBatch + } + inputVec := batch.ColVec(c.colIdx) + inputCol := inputVec.Bytes() + inputNulls := inputVec.Nulls() + outputVec := batch.ColVec(c.outputIdx) + outputCol := outputVec.Bytes() + outputNulls := outputVec.Nulls() + // Note that the loops below are not as optimized as in other cast operators + // since this operator should only be planned in tests. + c.allocator.PerformOperation([]coldata.Vec{outputVec}, func() { + if sel := batch.Selection(); sel != nil { + for _, i := range sel[:n] { + if inputNulls.NullAt(i) { + outputNulls.SetNull(i) + } else { + outputCol.Set(i, bytes.TrimRight(inputCol.Get(i), " ")) + } + } + } else { + for i := 0; i < n; i++ { + if inputNulls.NullAt(i) { + outputNulls.SetNull(i) + } else { + outputCol.Set(i, bytes.TrimRight(inputCol.Get(i), " ")) + } + } + } + }) + return batch +} + type castNativeToDatumOp struct { castOpBase diff --git a/pkg/sql/colexec/colexecbase/cast_test.go b/pkg/sql/colexec/colexecbase/cast_test.go index 412f9dbbe655..fcab275f8ccb 100644 --- a/pkg/sql/colexec/colexecbase/cast_test.go +++ b/pkg/sql/colexec/colexecbase/cast_test.go @@ -26,12 +26,10 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/randgen" "github.com/cockroachdb/cockroach/pkg/sql/sem/cast" "github.com/cockroachdb/cockroach/pkg/sql/sem/eval" - "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/randutil" - "github.com/lib/pq/oid" "github.com/stretchr/testify/require" ) @@ -48,12 +46,6 @@ func TestRandomizedCast(t *testing.T) { getValidSupportedCast := func() (from, to *types.T) { for { from, to = randgen.RandType(rng), randgen.RandType(rng) - if from.Oid() == oid.T_void && to.Oid() == oid.T_bpchar { - // Skip the cast from void to char because such setup would get - // stuck forever in the datum generation (due to the TODO - // below). - continue - } if _, ok := cast.LookupCastVolatility(from, to); ok { if colexecbase.IsCastSupported(from, to) { return from, to @@ -73,27 +65,10 @@ func TestRandomizedCast(t *testing.T) { toConverter := colconv.GetDatumToPhysicalFn(to) errorExpected := false for i := 0; i < numRows; i++ { - var ( - fromDatum, toDatum tree.Datum - err error - ) - // Datum generation. The loop exists only because of the TODO below. - for { - // We don't allow any NULL datums to be generated, so disable - // this ability in the RandDatum function. - fromDatum = randgen.RandDatum(rng, from, false) - toDatum, err = eval.PerformCast(&evalCtx, fromDatum, to) - if to.Oid() == oid.T_bpchar && string(*toDatum.(*tree.DString)) == "" { - // There is currently a problem when converting an empty - // string datum to a physical representation, so we skip - // such a datum and retry generation. - // TODO(yuzefovich): figure it out. When removing this - // check, remove the special casing for 'void -> char' cast - // above. - continue - } - break - } + // We don't allow any NULL datums to be generated, so disable this + // ability in the RandDatum function. + fromDatum := randgen.RandDatum(rng, from, false) + toDatum, err := eval.PerformCast(&evalCtx, fromDatum, to) var toPhys interface{} if err != nil { errorExpected = true diff --git a/pkg/sql/colexec/colexecbase/cast_tmpl.go b/pkg/sql/colexec/colexecbase/cast_tmpl.go index 97083c78d7d2..8e75a440571d 100644 --- a/pkg/sql/colexec/colexecbase/cast_tmpl.go +++ b/pkg/sql/colexec/colexecbase/cast_tmpl.go @@ -126,7 +126,15 @@ func GetCastOperator( return &castOpNullAny{castOpBase: base}, nil } if isIdentityCast(fromType, toType) { - return &castIdentityOp{castOpBase: base}, nil + // bpchars require special handling. + if toType.Oid() == oid.T_bpchar { + return &castBPCharIdentityOp{castOpBase: base}, nil + } + // If we don't have an array of bpchars, then we use the identity, + // otherwise we'll fallback to datum-datum cast below. + if toType.Oid() != oid.T__bpchar { + return &castIdentityOp{castOpBase: base}, nil + } } isFromDatum := typeconv.TypeFamilyToCanonicalTypeFamily(fromType.Family()) == typeconv.DatumVecCanonicalTypeFamily isToDatum := typeconv.TypeFamilyToCanonicalTypeFamily(toType.Family()) == typeconv.DatumVecCanonicalTypeFamily @@ -322,6 +330,50 @@ func (c *castIdentityOp) Next() coldata.Batch { return batch } +// castBPCharIdentityOp is a specialization of castIdentityOp which handles +// casts to the bpchar type (which trims trailing whitespaces). +type castBPCharIdentityOp struct { + castOpBase +} + +var _ colexecop.ClosableOperator = &castBPCharIdentityOp{} + +func (c *castBPCharIdentityOp) Next() coldata.Batch { + batch := c.Input.Next() + n := batch.Length() + if n == 0 { + return coldata.ZeroBatch + } + inputVec := batch.ColVec(c.colIdx) + inputCol := inputVec.Bytes() + inputNulls := inputVec.Nulls() + outputVec := batch.ColVec(c.outputIdx) + outputCol := outputVec.Bytes() + outputNulls := outputVec.Nulls() + // Note that the loops below are not as optimized as in other cast operators + // since this operator should only be planned in tests. + c.allocator.PerformOperation([]coldata.Vec{outputVec}, func() { + if sel := batch.Selection(); sel != nil { + for _, i := range sel[:n] { + if inputNulls.NullAt(i) { + outputNulls.SetNull(i) + } else { + outputCol.Set(i, bytes.TrimRight(inputCol.Get(i), " ")) + } + } + } else { + for i := 0; i < n; i++ { + if inputNulls.NullAt(i) { + outputNulls.SetNull(i) + } else { + outputCol.Set(i, bytes.TrimRight(inputCol.Get(i), " ")) + } + } + } + }) + return batch +} + type castNativeToDatumOp struct { castOpBase diff --git a/pkg/sql/crdb_internal.go b/pkg/sql/crdb_internal.go index 1e98e6d1adcc..7ce259f6c7e6 100644 --- a/pkg/sql/crdb_internal.go +++ b/pkg/sql/crdb_internal.go @@ -65,7 +65,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/sqlliveness" "github.com/cockroachdb/cockroach/pkg/sql/sqlstats" - "github.com/cockroachdb/cockroach/pkg/sql/sqlstats/insights" "github.com/cockroachdb/cockroach/pkg/sql/sqlstats/persistedsqlstats" "github.com/cockroachdb/cockroach/pkg/sql/sqlstats/persistedsqlstats/sqlstatsutil" "github.com/cockroachdb/cockroach/pkg/sql/sqlstats/sslocal" @@ -110,6 +109,7 @@ var crdbInternal = virtualSchema{ catconstants.CrdbInternalClusterContendedTablesViewID: crdbInternalClusterContendedTablesView, catconstants.CrdbInternalClusterContentionEventsTableID: crdbInternalClusterContentionEventsTable, catconstants.CrdbInternalClusterDistSQLFlowsTableID: crdbInternalClusterDistSQLFlowsTable, + catconstants.CrdbInternalClusterExecutionInsightsTableID: crdbInternalClusterExecutionInsightsTable, catconstants.CrdbInternalClusterLocksTableID: crdbInternalClusterLocksTable, catconstants.CrdbInternalClusterQueriesTableID: crdbInternalClusterQueriesTable, catconstants.CrdbInternalClusterTransactionsTableID: crdbInternalClusterTxnsTable, @@ -6291,9 +6291,9 @@ func populateClusterLocksWithFilter( return matched, err } -var crdbInternalNodeExecutionInsightsTable = virtualSchemaTable{ - schema: ` -CREATE TABLE crdb_internal.node_execution_insights ( +// This is the table structure for both cluster_execution_insights and node_execution_insights. +const executionInsightsSchemaPattern = ` +CREATE TABLE crdb_internal.%s ( session_id STRING NOT NULL, txn_id UUID NOT NULL, txn_fingerprint_id BYTES NOT NULL, @@ -6314,59 +6314,94 @@ CREATE TABLE crdb_internal.node_execution_insights ( retries INT8 NOT NULL, last_retry_reason STRING, exec_node_ids INT[] NOT NULL -);`, +)` + +var crdbInternalClusterExecutionInsightsTable = virtualSchemaTable{ + schema: fmt.Sprintf(executionInsightsSchemaPattern, "cluster_execution_insights"), populate: func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) (err error) { - p.extendedEvalCtx.statsProvider.IterateInsights(ctx, func( - ctx context.Context, insight *insights.Insight, - ) { - startTimestamp, errTimestamp := tree.MakeDTimestamp(insight.Statement.StartTime, time.Nanosecond) - if errTimestamp != nil { - err = errors.CombineErrors(err, errTimestamp) - return - } + return populateExecutionInsights(ctx, p, addRow, &serverpb.ListExecutionInsightsRequest{}) + }, +} - endTimestamp, errTimestamp := tree.MakeDTimestamp(insight.Statement.EndTime, time.Nanosecond) - if errTimestamp != nil { - err = errors.CombineErrors(err, errTimestamp) - return - } +var crdbInternalNodeExecutionInsightsTable = virtualSchemaTable{ + schema: fmt.Sprintf(executionInsightsSchemaPattern, "node_execution_insights"), + populate: func(ctx context.Context, p *planner, db catalog.DatabaseDescriptor, addRow func(...tree.Datum) error) (err error) { + return populateExecutionInsights(ctx, p, addRow, &serverpb.ListExecutionInsightsRequest{NodeID: "local"}) + }, +} - execNodeIDs := tree.NewDArray(types.Int) - for _, nodeID := range insight.Statement.Nodes { - if errNodeID := execNodeIDs.Append(tree.NewDInt(tree.DInt(nodeID))); errNodeID != nil { - err = errors.CombineErrors(err, errNodeID) - return - } +func populateExecutionInsights( + ctx context.Context, + p *planner, + addRow func(...tree.Datum) error, + request *serverpb.ListExecutionInsightsRequest, +) (err error) { + hasRoleOption, err := p.HasViewActivityOrViewActivityRedactedRole(ctx) + if err != nil { + return err + } + if !hasRoleOption { + return pgerror.Newf( + pgcode.InsufficientPrivilege, + "user %s does not have %s or %s privilege", + p.User(), + roleoption.VIEWACTIVITY, + roleoption.VIEWACTIVITYREDACTED, + ) + } + + response, err := p.extendedEvalCtx.SQLStatusServer.ListExecutionInsights(ctx, request) + if err != nil { + return + } + for _, insight := range response.Insights { + startTimestamp, errTimestamp := tree.MakeDTimestamp(insight.Statement.StartTime, time.Nanosecond) + if errTimestamp != nil { + err = errors.CombineErrors(err, errTimestamp) + return + } + + endTimestamp, errTimestamp := tree.MakeDTimestamp(insight.Statement.EndTime, time.Nanosecond) + if errTimestamp != nil { + err = errors.CombineErrors(err, errTimestamp) + return + } + + execNodeIDs := tree.NewDArray(types.Int) + for _, nodeID := range insight.Statement.Nodes { + if errNodeID := execNodeIDs.Append(tree.NewDInt(tree.DInt(nodeID))); errNodeID != nil { + err = errors.CombineErrors(err, errNodeID) + return } + } - autoRetryReason := tree.DNull - if insight.Statement.AutoRetryReason != "" { - autoRetryReason = tree.NewDString(insight.Statement.AutoRetryReason) - } - - err = errors.CombineErrors(err, addRow( - tree.NewDString(hex.EncodeToString(insight.Session.ID.GetBytes())), - tree.NewDUuid(tree.DUuid{UUID: insight.Transaction.ID}), - tree.NewDBytes(tree.DBytes(sqlstatsutil.EncodeUint64ToBytes(uint64(insight.Transaction.FingerprintID)))), - tree.NewDString(hex.EncodeToString(insight.Statement.ID.GetBytes())), - tree.NewDBytes(tree.DBytes(sqlstatsutil.EncodeUint64ToBytes(uint64(insight.Statement.FingerprintID)))), - tree.NewDString(insight.Statement.Query), - tree.NewDString(insight.Statement.Status), - startTimestamp, - endTimestamp, - tree.MakeDBool(tree.DBool(insight.Statement.FullScan)), - tree.NewDString(insight.Statement.User), - tree.NewDString(insight.Statement.ApplicationName), - tree.NewDString(insight.Statement.Database), - tree.NewDString(insight.Statement.PlanGist), - tree.NewDInt(tree.DInt(insight.Statement.RowsRead)), - tree.NewDInt(tree.DInt(insight.Statement.RowsWritten)), - tree.NewDFloat(tree.DFloat(insight.Transaction.UserPriority)), - tree.NewDInt(tree.DInt(insight.Statement.Retries)), - autoRetryReason, - execNodeIDs, - )) - }) - return err - }, + autoRetryReason := tree.DNull + if insight.Statement.AutoRetryReason != "" { + autoRetryReason = tree.NewDString(insight.Statement.AutoRetryReason) + } + + err = errors.CombineErrors(err, addRow( + tree.NewDString(hex.EncodeToString(insight.Session.ID.GetBytes())), + tree.NewDUuid(tree.DUuid{UUID: insight.Transaction.ID}), + tree.NewDBytes(tree.DBytes(sqlstatsutil.EncodeUint64ToBytes(uint64(insight.Transaction.FingerprintID)))), + tree.NewDString(hex.EncodeToString(insight.Statement.ID.GetBytes())), + tree.NewDBytes(tree.DBytes(sqlstatsutil.EncodeUint64ToBytes(uint64(insight.Statement.FingerprintID)))), + tree.NewDString(insight.Statement.Query), + tree.NewDString(insight.Statement.Status), + startTimestamp, + endTimestamp, + tree.MakeDBool(tree.DBool(insight.Statement.FullScan)), + tree.NewDString(insight.Statement.User), + tree.NewDString(insight.Statement.ApplicationName), + tree.NewDString(insight.Statement.Database), + tree.NewDString(insight.Statement.PlanGist), + tree.NewDInt(tree.DInt(insight.Statement.RowsRead)), + tree.NewDInt(tree.DInt(insight.Statement.RowsWritten)), + tree.NewDFloat(tree.DFloat(insight.Transaction.UserPriority)), + tree.NewDInt(tree.DInt(insight.Statement.Retries)), + autoRetryReason, + execNodeIDs, + )) + } + return } diff --git a/pkg/sql/crdb_internal_test.go b/pkg/sql/crdb_internal_test.go index 6318a09354b3..6b184003a87f 100644 --- a/pkg/sql/crdb_internal_test.go +++ b/pkg/sql/crdb_internal_test.go @@ -12,7 +12,9 @@ package sql_test import ( "context" + gosql "database/sql" "fmt" + "net/url" "strings" "sync/atomic" "testing" @@ -932,3 +934,71 @@ func TestIsAtLeastVersion(t *testing.T) { } } } + +// This test doesn't care about the contents of these virtual tables; +// other places (the insights integration tests) do that for us. +// What we look at here is the role-option-checking we need to make sure +// the current sql user has permission to read these tables at all. +// VIEWACTIVITY or VIEWACTIVITYREDACTED should be sufficient. +func TestExecutionInsights(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + // Start the cluster. + ctx := context.Background() + settings := cluster.MakeTestingClusterSettings() + args := base.TestClusterArgs{ServerArgs: base.TestServerArgs{Settings: settings}} + tc := testcluster.StartTestCluster(t, 1, args) + defer tc.Stopper().Stop(ctx) + sqlDB := sqlutils.MakeSQLRunner(tc.ServerConn(0)) + + // We'll check both the cluster-wide table and the node-local one. + virtualTables := []interface{}{ + "cluster_execution_insights", + "node_execution_insights", + } + testutils.RunValues(t, "table", virtualTables, func(t *testing.T, table interface{}) { + testCases := []struct { + option string + granted bool + }{ + {option: "VIEWACTIVITY", granted: true}, + {option: "VIEWACTIVITYREDACTED", granted: true}, + {option: "NOVIEWACTIVITY"}, + {option: "NOVIEWACTIVITYREDACTED"}, + } + for _, testCase := range testCases { + t.Run(fmt.Sprintf("option=%s", testCase.option), func(t *testing.T) { + // Create a test user with the role option we're testing. + sqlDB.Exec(t, fmt.Sprintf("CREATE USER testuser WITH %s", testCase.option)) + defer func() { + sqlDB.Exec(t, "DROP USER testuser") + }() + + // Connect to the cluster as the test user. + pgUrl, cleanup := sqlutils.PGUrl(t, tc.Server(0).ServingSQLAddr(), + fmt.Sprintf("TestExecutionInsights-%s-%s", table, testCase.option), + url.User("testuser"), + ) + defer cleanup() + db, err := gosql.Open("postgres", pgUrl.String()) + require.NoError(t, err) + defer func() { _ = db.Close() }() + + // Try to read the virtual table, and see that we can or cannot as expected. + rows, err := db.Query(fmt.Sprintf("SELECT count(*) FROM crdb_internal.%s", table)) + defer func() { + if rows != nil { + _ = rows.Close() + } + }() + if testCase.granted { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } + + }) +} diff --git a/pkg/sql/create_function_test.go b/pkg/sql/create_function_test.go index 8bdf2b576e65..9565eeaafaa6 100644 --- a/pkg/sql/create_function_test.go +++ b/pkg/sql/create_function_test.go @@ -115,7 +115,7 @@ SELECT nextval(105:::REGCLASS);`, seq.GetDependedOnBy(), ) - // Make sure sequence has correct back references. + // Make sure view has correct back references. vn := tree.MakeTableNameWithSchema("defaultdb", "public", "v") _, view, err := col.GetImmutableTableByName(ctx, txn, &vn, tree.ObjectLookupFlagsWithRequired()) require.NoError(t, err) @@ -127,6 +127,7 @@ SELECT nextval(105:::REGCLASS);`, view.GetDependedOnBy(), ) + // Make sure type has correct back references. typn := tree.MakeQualifiedTypeName("defaultdb", "public", "notmyworkday") _, typ, err := col.GetImmutableTypeByName(ctx, txn, &typn, tree.ObjectLookupFlagsWithRequired()) require.NoError(t, err) @@ -139,85 +140,6 @@ SELECT nextval(105:::REGCLASS);`, return nil }) require.NoError(t, err) - - // Test drop/rename behavior in legacy schema changer. - tDB.Exec(t, "SET use_declarative_schema_changer = off") - - testCases := []struct { - stmt string - expectedErr string - }{ - { - stmt: "DROP SEQUENCE sq1", - expectedErr: "pq: cannot drop sequence sq1 because other objects depend on it", - }, - { - stmt: "DROP SEQUENCE sq1 CASCADE", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER SEQUENCE sq1 RENAME TO sq1_new", - expectedErr: "", - }, - { - stmt: "DROP TABLE t", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "DROP TABLE t CASCADE", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t RENAME TO t_new", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t SET SCHEMA test_sc", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t DROP COLUMN b", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t DROP COLUMN b CASCADE", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t RENAME COLUMN b TO bb", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER TABLE t ALTER COLUMN b TYPE STRING", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "DROP INDEX t@t_idx_b", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "DROP INDEX t@t_idx_b CASCADE", - expectedErr: "pq: unimplemented: drop function not supported", - }, - { - stmt: "ALTER INDEX t@t_idx_b RENAME TO t_idx_b_new", - expectedErr: "pq: unimplemented: drop function not supported", - }, - } - - for _, tc := range testCases { - _, err = sqlDB.Exec(tc.stmt) - if tc.expectedErr == "" { - require.NoError(t, err) - continue - } - require.Equal(t, tc.expectedErr, err.Error()) - } - - // Test drop/rename behavior in declarative schema changer. - tDB.Exec(t, "SET use_declarative_schema_changer = on") - _, err = sqlDB.Exec("DROP TABLE t CASCADE ") - require.Equal(t, "pq: unimplemented: function descriptor not supported in declarative schema changer", err.Error()) } func TestCreateFunctionWithTableImplicitType(t *testing.T) { diff --git a/pkg/sql/drop_cascade.go b/pkg/sql/drop_cascade.go index 3de050e5e2f8..7e65c4d42bdf 100644 --- a/pkg/sql/drop_cascade.go +++ b/pkg/sql/drop_cascade.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/dbdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/resolver" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc" @@ -36,6 +37,7 @@ type dropCascadeState struct { toDeleteByID map[descpb.ID]*toDelete allTableObjectsToDelete []*tabledesc.Mutable typesToDelete []*typedesc.Mutable + functionsToDelete []*funcdesc.Mutable droppedNames []string } @@ -67,15 +69,32 @@ func (d *dropCascadeState) collectObjectsInSchema( d.objectNamesToDelete = append(d.objectNamesToDelete, &names[i]) } d.schemasToDelete = append(d.schemasToDelete, schemaWithDbDesc{schema: schema, dbDesc: db}) + + // Collect functions to delete. Function is a bit special because it doesn't + // have namespace records. So function names are not included in + // objectNamesToDelete. Instead, we need to go through each schema descriptor + // to collect function descriptors by function ids. + err = schema.ForEachFunctionOverload(func(overload descpb.SchemaDescriptor_FunctionOverload) error { + fnDesc, err := p.Descriptors().GetMutableFunctionByID( + ctx, p.txn, overload.ID, tree.ObjectLookupFlagsWithRequired(), + ) + if err != nil { + return err + } + d.functionsToDelete = append(d.functionsToDelete, fnDesc) + return nil + }) + if err != nil { + return err + } + return nil } // This resolves objects for DROP SCHEMA and DROP DATABASE ops. // db is used to generate a useful error message in the case // of DROP DATABASE; otherwise, db is nil. -func (d *dropCascadeState) resolveCollectedObjects( - ctx context.Context, p *planner, db *dbdesc.Mutable, -) error { +func (d *dropCascadeState) resolveCollectedObjects(ctx context.Context, p *planner) error { d.td = make([]toDelete, 0, len(d.objectNamesToDelete)) // Resolve each of the collected names. for i := range d.objectNamesToDelete { @@ -131,10 +150,7 @@ func (d *dropCascadeState) resolveCollectedObjects( // Recursively check permissions on all dependent views, since some may // be in different databases. for _, ref := range tbDesc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, ref.ID); err != nil { - return err - } - if err := p.canRemoveDependentView(ctx, tbDesc, ref, tree.DropCascade); err != nil { + if err := p.canRemoveDependentFromTable(ctx, tbDesc, ref, tree.DropCascade); err != nil { return err } } @@ -198,6 +214,20 @@ func (d *dropCascadeState) resolveCollectedObjects( } func (d *dropCascadeState) dropAllCollectedObjects(ctx context.Context, p *planner) error { + // Delete all of the function first since we don't allow function references + // from other objects yet. + // TODO(chengxiong): rework dropCascadeState logic to add function into the + // table/view dependency graph. This is needed when we start allowing using + // functions from other objects. + for _, fn := range d.functionsToDelete { + if err := p.canDropFunction(ctx, fn); err != nil { + return err + } + if err := p.dropFunctionImpl(ctx, fn); err != nil { + return err + } + } + // Delete all of the collected tables. for _, toDel := range d.td { desc := toDel.desc diff --git a/pkg/sql/drop_database.go b/pkg/sql/drop_database.go index 772a25b5006b..912d5de6141a 100644 --- a/pkg/sql/drop_database.go +++ b/pkg/sql/drop_database.go @@ -95,7 +95,7 @@ func (p *planner) DropDatabase(ctx context.Context, n *tree.DropDatabase) (planN } } - if len(d.objectNamesToDelete) > 0 { + if len(d.objectNamesToDelete) > 0 || len(d.functionsToDelete) > 0 { switch n.DropBehavior { case tree.DropRestrict: return nil, pgerror.Newf(pgcode.DependentObjectsStillExist, @@ -111,7 +111,7 @@ func (p *planner) DropDatabase(ctx context.Context, n *tree.DropDatabase) (planN } } - if err := d.resolveCollectedObjects(ctx, p, dbDesc); err != nil { + if err := d.resolveCollectedObjects(ctx, p); err != nil { return nil, err } @@ -292,13 +292,16 @@ func (p *planner) accumulateCascadingViews( ctx context.Context, dependentObjects map[descpb.ID]*tabledesc.Mutable, desc *tabledesc.Mutable, ) error { for _, ref := range desc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, ref.ID); err != nil { - return err - } - dependentDesc, err := p.Descriptors().GetMutableTableVersionByID(ctx, ref.ID, p.txn) + desc, err := p.Descriptors().GetMutableDescriptorByID(ctx, p.txn, ref.ID) if err != nil { return err } + + dependentDesc, ok := desc.(*tabledesc.Mutable) + if !ok { + continue + } + if !dependentDesc.IsView() { continue } diff --git a/pkg/sql/drop_function.go b/pkg/sql/drop_function.go index cdd5f54091e4..8a12851bcce8 100644 --- a/pkg/sql/drop_function.go +++ b/pkg/sql/drop_function.go @@ -12,24 +12,238 @@ package sql import ( "context" + "fmt" + "github.com/cockroachdb/cockroach/pkg/sql/catalog" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" + "github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scerrors" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" + "github.com/cockroachdb/errors" ) type dropFunctionNode struct { - n *tree.DropFunction + toDrop []*funcdesc.Mutable + dropBehavior tree.DropBehavior } // DropFunction drops a function. -func (p *planner) DropFunction(ctx context.Context, n *tree.DropFunction) (planNode, error) { - return &dropFunctionNode{n: n}, nil +func (p *planner) DropFunction( + ctx context.Context, n *tree.DropFunction, +) (ret planNode, err error) { + if n.DropBehavior == tree.DropCascade { + // TODO(chengxiong): remove this check when drop function cascade is supported. + return nil, unimplemented.Newf("DROP FUNCTION...CASCADE", "drop function cascade not supported") + } + dropNode := &dropFunctionNode{ + toDrop: make([]*funcdesc.Mutable, 0, len(n.Functions)), + dropBehavior: n.DropBehavior, + } + fnResolved := util.MakeFastIntSet() + for _, fn := range n.Functions { + ol, err := p.matchUDF(ctx, &fn, !n.IfExists) + if err != nil { + return nil, err + } + if ol == nil { + continue + } + fnID, err := funcdesc.UserDefinedFunctionOIDToID(ol.Oid) + if err != nil { + return nil, err + } + if fnResolved.Contains(int(fnID)) { + continue + } + fnResolved.Add(int(fnID)) + mut, err := p.checkPrivilegesForDropFunction(ctx, fnID) + if err != nil { + return nil, err + } + dropNode.toDrop = append(dropNode.toDrop, mut) + } + + if len(dropNode.toDrop) == 0 { + return newZeroNode(nil), nil + } + // TODO(chengxiong): check if there is any backreference which requires + // CASCADE drop behavior. This is needed when we start allowing UDF + // references from other objects. + return dropNode, nil } func (n *dropFunctionNode) startExec(params runParams) error { - return unimplemented.NewWithIssue(83235, "drop function not supported") + for _, fnMutable := range n.toDrop { + if err := params.p.dropFunctionImpl(params.ctx, fnMutable); err != nil { + return err + } + } + return nil } func (n *dropFunctionNode) Next(params runParams) (bool, error) { return false, nil } func (n *dropFunctionNode) Values() tree.Datums { return tree.Datums{} } func (n *dropFunctionNode) Close(ctx context.Context) {} + +// matchUDF tries to resolve a user-defined function with the given signature +// from the current search path, only overloads with exactly the same argument +// types are considered a match. If required is true, an error is returned if +// the function is not found. An error is also returning if a builtin function +// is matched. +func (p *planner) matchUDF( + ctx context.Context, fn *tree.FuncObj, required bool, +) (*tree.QualifiedOverload, error) { + path := p.CurrentSearchPath() + fnDef, err := p.ResolveFunction(ctx, fn.FuncName.ToUnresolvedObjectName().ToUnresolvedName(), &path) + if err != nil { + if !required && errors.Is(err, tree.ErrFunctionUndefined) { + return nil, nil + } + return nil, err + } + + argTypes, err := fn.InputArgTypes(ctx, p) + if err != nil { + return nil, err + } + ol, err := fnDef.MatchOverload(argTypes, fn.FuncName.Schema(), &path) + if err != nil { + if !required && errors.Is(err, tree.ErrFunctionUndefined) { + return nil, nil + } + return nil, err + } + if !ol.IsUDF { + return nil, errors.Errorf( + "cannot drop function %s because it is required by the database system", + ol.Signature(true /*Simplify*/), + ) + } + return &ol, nil +} + +func (p *planner) checkPrivilegesForDropFunction( + ctx context.Context, fnID descpb.ID, +) (*funcdesc.Mutable, error) { + mutable, err := p.Descriptors().GetMutableFunctionByID(ctx, p.Txn(), fnID, tree.ObjectLookupFlagsWithRequired()) + if err != nil { + return nil, err + } + if err := p.canDropFunction(ctx, mutable); err != nil { + return nil, err + } + return mutable, nil +} + +func (p *planner) canDropFunction(ctx context.Context, fnDesc catalog.FunctionDescriptor) error { + hasOwernship, err := p.HasOwnershipOnSchema(ctx, fnDesc.GetParentSchemaID(), fnDesc.GetParentID()) + if err != nil { + return err + } + if hasOwernship { + return nil + } + hasOwernship, err = p.HasOwnership(ctx, fnDesc) + if err != nil { + return err + } + if !hasOwernship { + return errors.Errorf("must be owner of function %s", fnDesc.GetName()) + } + return nil +} + +func (p *planner) dropFunctionImpl(ctx context.Context, fnMutable *funcdesc.Mutable) error { + if fnMutable.Dropped() { + return errors.Errorf("function %q is already being dropped", fnMutable.Name) + } + + // Exit early with an error if the function is undergoing a declarative schema + // change, before we try to get job IDs and update job statuses later. See + // createOrUpdateSchemaChangeJob. + if fnMutable.GetDeclarativeSchemaChangerState() != nil { + return scerrors.ConcurrentSchemaChangeError(fnMutable) + } + + // Remove backreference from tables/views/sequences referenced by this UDF. + for _, id := range fnMutable.DependsOn { + // TODO(chengxiong): remove backreference from UDFs that this UDF has + // reference to. This is needed when we allow UDFs being referenced by + // UDFs. + refMutable, err := p.Descriptors().GetMutableTableByID( + ctx, p.txn, id, tree.ObjectLookupFlagsWithRequired(), + ) + if err != nil { + return err + } + refMutable.DependedOnBy = removeMatchingReferences( + refMutable.DependedOnBy, + fnMutable.GetID(), + ) + if err := p.writeSchemaChange( + ctx, refMutable, descpb.InvalidMutationID, + fmt.Sprintf("updating backreference of function %s(%d) in table %s(%d)", + fnMutable.Name, fnMutable.ID, refMutable.Name, refMutable.ID, + ), + ); err != nil { + return err + } + } + + // Remove backreference from types referenced by this UDF. + jobDesc := fmt.Sprintf( + "updating type backreference %v for function %s(%d)", + fnMutable.DependsOnTypes, fnMutable.Name, fnMutable.ID, + ) + if err := p.removeTypeBackReferences( + ctx, fnMutable.DependsOnTypes, fnMutable.ID, jobDesc, + ); err != nil { + return err + } + + // Remove function signature from schema. + scDesc, err := p.Descriptors().GetMutableSchemaByID( + ctx, p.Txn(), fnMutable.ParentSchemaID, tree.ObjectLookupFlagsWithRequired().CommonLookupFlags, + ) + if err != nil { + return err + } + scDesc.RemoveFunction(fnMutable.Name, fnMutable.ID) + if err := p.writeSchemaDescChange( + ctx, scDesc, + fmt.Sprintf("removing function %s(%d) from schema %s(%d)", fnMutable.Name, fnMutable.ID, scDesc.Name, scDesc.ID), + ); err != nil { + return err + } + + // Mark the UDF as dropped. + fnMutable.SetDropped() + return p.writeFuncSchemaChange(ctx, fnMutable) +} + +func (p *planner) writeFuncDesc(ctx context.Context, funcDesc *funcdesc.Mutable) error { + b := p.txn.NewBatch() + if err := p.Descriptors().WriteDescToBatch( + ctx, p.extendedEvalCtx.Tracing.KVTracingEnabled(), funcDesc, b, + ); err != nil { + return err + } + return p.txn.Run(ctx, b) +} + +func (p *planner) writeFuncSchemaChange(ctx context.Context, funcDesc *funcdesc.Mutable) error { + return p.writeFuncDesc(ctx, funcDesc) +} + +func (p *planner) removeDependentFunction( + ctx context.Context, tbl *tabledesc.Mutable, fn *funcdesc.Mutable, +) error { + // In the table whose index is being removed, filter out all back-references + // that refer to the view that's being removed. + tbl.DependedOnBy = removeMatchingReferences(tbl.DependedOnBy, fn.ID) + // Then proceed to actually drop the view and log an event for it. + return p.dropFunctionImpl(ctx, fn) +} diff --git a/pkg/sql/drop_function_test.go b/pkg/sql/drop_function_test.go new file mode 100644 index 000000000000..bad18e74ad6c --- /dev/null +++ b/pkg/sql/drop_function_test.go @@ -0,0 +1,404 @@ +// Copyright 2022 The Cockroach Authors. +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package sql_test + +import ( + "context" + "sort" + "strconv" + "testing" + + "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/kv" + "github.com/cockroachdb/cockroach/pkg/sql" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/descs" + "github.com/cockroachdb/cockroach/pkg/sql/sem/catid" + "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" + "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" + "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/stretchr/testify/require" +) + +func TestDropFunction(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + ctx := context.Background() + s, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{}) + defer s.Stopper().Stop(ctx) + tDB := sqlutils.MakeSQLRunner(sqlDB) + + tDB.Exec(t, ` +CREATE TABLE t( + a INT PRIMARY KEY, + b INT, + C INT, + INDEX t_idx_b(b), + INDEX t_idx_c(c) +); +CREATE SEQUENCE sq1; +CREATE VIEW v AS SELECT a FROM t; +CREATE TYPE notmyworkday AS ENUM ('Monday', 'Tuesday'); +CREATE FUNCTION f(a notmyworkday) RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ + SELECT a FROM t; + SELECT b FROM t@t_idx_b; + SELECT c FROM t@t_idx_c; + SELECT a FROM v; + SELECT nextval('sq1'); +$$; +CREATE SCHEMA test_sc; +`, + ) + + err := sql.TestingDescsTxn(ctx, s, func(ctx context.Context, txn *kv.Txn, col *descs.Collection) error { + funcDesc, err := col.GetImmutableFunctionByID(ctx, txn, 109, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, funcDesc.GetName(), "f") + + require.Equal(t, + `SELECT a FROM defaultdb.public.t; +SELECT b FROM defaultdb.public.t@t_idx_b; +SELECT c FROM defaultdb.public.t@t_idx_c; +SELECT a FROM defaultdb.public.v; +SELECT nextval(105:::REGCLASS);`, + funcDesc.GetFunctionBody()) + + sort.Slice(funcDesc.GetDependsOn(), func(i, j int) bool { + return funcDesc.GetDependsOn()[i] < funcDesc.GetDependsOn()[j] + }) + require.Equal(t, + []descpb.ID{104, 105, 106}, + funcDesc.GetDependsOn(), + ) + sort.Slice(funcDesc.GetDependsOnTypes(), func(i, j int) bool { + return funcDesc.GetDependsOnTypes()[i] < funcDesc.GetDependsOnTypes()[j] + }) + require.Equal(t, + []descpb.ID{107, 108}, + funcDesc.GetDependsOnTypes(), + ) + + // Make sure columns and indexes has correct back references. + tn := tree.MakeTableNameWithSchema("defaultdb", "public", "t") + _, tbl, err := col.GetImmutableTableByName(ctx, txn, &tn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, "t", tbl.GetName()) + require.Equal(t, + []descpb.TableDescriptor_Reference{ + {ID: 106, ColumnIDs: []catid.ColumnID{1}}, + {ID: 109, ColumnIDs: []catid.ColumnID{1}}, + {ID: 109, IndexID: 2, ColumnIDs: []catid.ColumnID{2}}, + {ID: 109, IndexID: 3, ColumnIDs: []catid.ColumnID{3}}, + }, + tbl.GetDependedOnBy(), + ) + + // Make sure sequence has correct back references. + sqn := tree.MakeTableNameWithSchema("defaultdb", "public", "sq1") + _, seq, err := col.GetImmutableTableByName(ctx, txn, &sqn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, "sq1", seq.GetName()) + require.Equal(t, + []descpb.TableDescriptor_Reference{ + {ID: 109, ByID: true}, + }, + seq.GetDependedOnBy(), + ) + + // Make sure view has correct back references. + vn := tree.MakeTableNameWithSchema("defaultdb", "public", "v") + _, view, err := col.GetImmutableTableByName(ctx, txn, &vn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, "v", view.GetName()) + require.Equal(t, + []descpb.TableDescriptor_Reference{ + {ID: 109, ColumnIDs: []catid.ColumnID{1}}, + }, + view.GetDependedOnBy(), + ) + + // Make sure type has correct back references. + typn := tree.MakeQualifiedTypeName("defaultdb", "public", "notmyworkday") + _, typ, err := col.GetImmutableTypeByName(ctx, txn, &typn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, "notmyworkday", typ.GetName()) + require.Equal(t, + []descpb.ID{109}, + typ.GetReferencingDescriptorIDs(), + ) + + return nil + }) + require.NoError(t, err) + + // DROP the function and make sure dependencies are cleared. + tDB.Exec(t, "DROP FUNCTION f") + err = sql.TestingDescsTxn(ctx, s, func(ctx context.Context, txn *kv.Txn, col *descs.Collection) error { + _, err := col.GetImmutableFunctionByID(ctx, txn, 109, tree.ObjectLookupFlagsWithRequired()) + require.Error(t, err) + require.Regexp(t, "descriptor is being dropped", err.Error()) + + // Make sure columns and indexes has correct back references. + tn := tree.MakeTableNameWithSchema("defaultdb", "public", "t") + _, tbl, err := col.GetImmutableTableByName(ctx, txn, &tn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, + []descpb.TableDescriptor_Reference{ + {ID: 106, ColumnIDs: []catid.ColumnID{1}}, + }, + tbl.GetDependedOnBy(), + ) + + // Make sure sequence has correct back references. + sqn := tree.MakeTableNameWithSchema("defaultdb", "public", "sq1") + _, seq, err := col.GetImmutableTableByName(ctx, txn, &sqn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Nil(t, seq.GetDependedOnBy()) + + // Make sure view has correct back references. + vn := tree.MakeTableNameWithSchema("defaultdb", "public", "v") + _, view, err := col.GetImmutableTableByName(ctx, txn, &vn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Nil(t, view.GetDependedOnBy()) + + // Make sure type has correct back references. + typn := tree.MakeQualifiedTypeName("defaultdb", "public", "notmyworkday") + _, typ, err := col.GetImmutableTypeByName(ctx, txn, &typn, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Nil(t, typ.GetReferencingDescriptorIDs()) + + return nil + }) + require.NoError(t, err) +} + +func TestDropFailOnDependentFunction(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + ctx := context.Background() + s, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{}) + defer s.Stopper().Stop(ctx) + tDB := sqlutils.MakeSQLRunner(sqlDB) + + tDB.Exec(t, ` +CREATE TABLE t( + a INT PRIMARY KEY, + b INT, + C INT, + INDEX t_idx_b(b), + INDEX t_idx_c(c) +); +CREATE SEQUENCE sq1; +CREATE TABLE t2(a INT PRIMARY KEY); +CREATE VIEW v AS SELECT a FROM t2; +CREATE TYPE notmyworkday AS ENUM ('Monday', 'Tuesday'); +CREATE SCHEMA test_sc; +CREATE FUNCTION test_sc.f(a notmyworkday) RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ + SELECT a FROM t; + SELECT b FROM t@t_idx_b; + SELECT c FROM t@t_idx_c; + SELECT a FROM v; + SELECT nextval('sq1'); +$$; +CREATE DATABASE test_udf_db; +USE test_udf_db; +CREATE FUNCTION test_udf_db.public.f() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ + SELECT 1; +$$; +USE defaultdb; +`, + ) + + // Test drop/rename behavior in legacy schema changer. + tDB.Exec(t, "SET use_declarative_schema_changer = off;") + + testCases := []struct { + stmt string + expectedErr string + }{ + { + stmt: "DROP SEQUENCE sq1", + expectedErr: "pq: cannot drop sequence sq1 because other objects depend on it", + }, + { + stmt: "DROP TABLE t", + expectedErr: `pq: cannot drop relation "t" because function "f" depends on it`, + }, + { + stmt: "DROP VIEW v", + expectedErr: `pq: cannot drop relation "v" because function "f" depends on it`, + }, + { + stmt: "ALTER TABLE t RENAME TO t_new", + expectedErr: `pq: cannot rename relation "t" because function "f" depends on it`, + }, + { + stmt: "ALTER TABLE t SET SCHEMA test_sc", + expectedErr: `pq: cannot set schema on relation "t" because function "f" depends on it`, + }, + { + stmt: "ALTER TABLE t DROP COLUMN b", + expectedErr: `pq: cannot drop column "b" because function "f" depends on it`, + }, + { + stmt: "ALTER TABLE t RENAME COLUMN b TO bb", + expectedErr: `pq: cannot rename column "b" because function "f" depends on it`, + }, + { + stmt: "ALTER TABLE t ALTER COLUMN b TYPE STRING", + expectedErr: `pq: cannot alter type of column "b" because function "f" depends on it`, + }, + { + stmt: "DROP INDEX t@t_idx_b", + expectedErr: `pq: cannot drop index "t_idx_b" because function "f" depends on it`, + }, + { + stmt: "ALTER INDEX t@t_idx_b RENAME TO t_idx_b_new", + expectedErr: `pq: cannot rename index "t_idx_b" because function "f" depends on it`, + }, + { + stmt: "DROP SCHEMA test_sc", + expectedErr: `pq: schema "test_sc" is not empty and CASCADE was not specified`, + }, + { + stmt: "DROP DATABASE test_udf_db RESTRICT", + expectedErr: `pq: database "test_udf_db" is not empty and RESTRICT was specified`, + }, + } + + for i, tc := range testCases { + t.Run(strconv.Itoa(i), func(t *testing.T) { + _, err := sqlDB.Exec(tc.stmt) + require.Equal(t, tc.expectedErr, err.Error()) + }) + } + + // Test drop behavior in declarative schema changer. + tDB.Exec(t, "SET use_declarative_schema_changer = on") + + dropStmts := []string{ + "DROP TABLE t", + "DROP TABLE t CASCADE", + "DROP SEQUENCE sq1", + "DROP SEQUENCE sq1 CASCADE", + "DROP TABLE t2 CASCADE", + "DROP VIEW v", + "DROP VIEW v CASCADE", + "DROP TYPE notmyworkday", + "DROP SCHEMA test_sc CASCADE", + "DROP SCHEMA test_sc CASCADE", + "DROP DATABASE test_udf_db CASCADE", + "DROP DATABASE test_udf_db CASCADE", + "ALTER TABLE t DROP COLUMN b", + "ALTER TABLE t DROP COLUMN b CASCADE", + } + + for _, stmt := range dropStmts { + t.Run(stmt, func(t *testing.T) { + _, err := sqlDB.Exec(stmt) + require.Equal(t, "pq: unimplemented: function descriptor not supported in declarative schema changer", err.Error()) + }) + } +} + +func TestDropCascadeRemoveFunction(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + setupQuery := ` +CREATE DATABASE test_db; +USE test_db; +CREATE TABLE t( + a INT PRIMARY KEY, + b INT, + C INT, + INDEX t_idx_b(b), + INDEX t_idx_c(c) +); +CREATE SEQUENCE sq1; +CREATE TABLE t2(a INT PRIMARY KEY); +CREATE VIEW v AS SELECT a FROM t2; +CREATE TYPE notmyworkday AS ENUM ('Monday', 'Tuesday'); +CREATE SCHEMA test_sc; +CREATE FUNCTION test_sc.f(a notmyworkday) RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ + SELECT a FROM t; + SELECT b FROM t@t_idx_b; + SELECT c FROM t@t_idx_c; + SELECT a FROM v; + SELECT nextval('sq1'); +$$; +` + + testCases := []struct { + testName string + stmt string + }{ + { + testName: "drop sequence", + stmt: "DROP SEQUENCE sq1 CASCADE", + }, + { + testName: "drop table", + stmt: "DROP TABLE t CASCADE", + }, + { + testName: "drop view", + stmt: "DROP VIEW v CASCADE", + }, + { + testName: "drop column", + stmt: "ALTER TABLE t DROP COLUMN b CASCADE", + }, + { + testName: "drop index", + stmt: "DROP INDEX t@t_idx_b CASCADE", + }, + { + testName: "drop database", + stmt: "DROP DATABASE test_db CASCADE", + }, + } + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + ctx := context.Background() + s, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{}) + defer s.Stopper().Stop(ctx) + tDB := sqlutils.MakeSQLRunner(sqlDB) + tDB.Exec(t, setupQuery) + // Test drop/rename behavior in legacy schema changer. + tDB.Exec(t, "SET use_declarative_schema_changer = off;") + + err := sql.TestingDescsTxn(ctx, s, func(ctx context.Context, txn *kv.Txn, col *descs.Collection) error { + fnDesc, err := col.GetImmutableFunctionByID(ctx, txn, 113, tree.ObjectLookupFlagsWithRequired()) + require.NoError(t, err) + require.Equal(t, "f", fnDesc.GetName()) + require.True(t, fnDesc.Public()) + return nil + }) + require.NoError(t, err) + + tDB.Exec(t, tc.stmt) + + err = sql.TestingDescsTxn(ctx, s, func(ctx context.Context, txn *kv.Txn, col *descs.Collection) error { + _, err := col.GetImmutableFunctionByID(ctx, txn, 113, tree.ObjectLookupFlagsWithRequired()) + require.Error(t, err) + require.Regexp(t, "descriptor is being dropped", err.Error()) + return nil + }) + require.NoError(t, err) + }) + } +} diff --git a/pkg/sql/drop_index.go b/pkg/sql/drop_index.go index 0e374f17891e..4669d0f4568f 100644 --- a/pkg/sql/drop_index.go +++ b/pkg/sql/drop_index.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/descmetadata" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" @@ -444,35 +445,39 @@ func (p *planner) dropIndexByName( var droppedViews []string for _, tableRef := range tableDesc.DependedOnBy { if tableRef.IndexID == idx.GetID() { - if err := p.maybeFailOnDroppingFunction(ctx, tableRef.ID); err != nil { - return err - } // Ensure that we have DROP privilege on all dependent views - err := p.canRemoveDependentViewGeneric( + err := p.canRemoveDependent( ctx, "index", idx.GetName(), tableDesc.ParentID, tableRef, behavior) if err != nil { return err } - viewDesc, err := p.getViewDescForCascade( + depDesc, err := p.getDescForCascade( ctx, "index", idx.GetName(), tableDesc.ParentID, tableRef.ID, behavior, ) if err != nil { return err } - viewJobDesc := fmt.Sprintf("removing view %q dependent on index %q which is being dropped", - viewDesc.Name, idx.GetName()) - cascadedViews, err := p.removeDependentView(ctx, tableDesc, viewDesc, viewJobDesc) - if err != nil { - return err - } + switch t := depDesc.(type) { + case *tabledesc.Mutable: + viewJobDesc := fmt.Sprintf("removing view %q dependent on index %q which is being dropped", + t.Name, idx.GetName()) + cascadedViews, err := p.removeDependentView(ctx, tableDesc, t, viewJobDesc) + if err != nil { + return err + } - qualifiedView, err := p.getQualifiedTableName(ctx, viewDesc) - if err != nil { - return err - } + qualifiedView, err := p.getQualifiedTableName(ctx, t) + if err != nil { + return err + } - droppedViews = append(droppedViews, qualifiedView.FQString()) - droppedViews = append(droppedViews, cascadedViews...) + droppedViews = append(droppedViews, qualifiedView.FQString()) + droppedViews = append(droppedViews, cascadedViews...) + case *funcdesc.Mutable: + if err := p.removeDependentFunction(ctx, tableDesc, t); err != nil { + return err + } + } } } diff --git a/pkg/sql/drop_schema.go b/pkg/sql/drop_schema.go index 500928885daa..48bad898e4c5 100644 --- a/pkg/sql/drop_schema.go +++ b/pkg/sql/drop_schema.go @@ -104,12 +104,15 @@ func (p *planner) DropSchema(ctx context.Context, n *tree.DropSchema) (planNode, "must be owner of schema %s", tree.Name(sc.GetName())) } namesBefore := len(d.objectNamesToDelete) + fnsBefore := len(d.functionsToDelete) if err := d.collectObjectsInSchema(ctx, p, db, sc); err != nil { return nil, err } // We added some new objects to delete. Ensure that we have the correct // drop behavior to be doing this. - if namesBefore != len(d.objectNamesToDelete) && n.DropBehavior != tree.DropCascade { + if (namesBefore != len(d.objectNamesToDelete) || fnsBefore != len(d.functionsToDelete)) && + n.DropBehavior != tree.DropCascade { + return nil, pgerror.Newf(pgcode.DependentObjectsStillExist, "schema %q is not empty and CASCADE was not specified", scName) } @@ -120,12 +123,7 @@ func (p *planner) DropSchema(ctx context.Context, n *tree.DropSchema) (planNode, } - // The database descriptor is used to generate specific error messages when - // a database cannot be collected for dropping. The database descriptor is nil here - // because dropping a schema will never result in a database being collected and dropped. - // Also, schemas can belong to different databases, so it does not make sense to pass a single - // database descriptor. - if err := d.resolveCollectedObjects(ctx, p, nil /* db */); err != nil { + if err := d.resolveCollectedObjects(ctx, p); err != nil { return nil, err } diff --git a/pkg/sql/drop_sequence.go b/pkg/sql/drop_sequence.go index bea3491a323b..a5c6a5184abf 100644 --- a/pkg/sql/drop_sequence.go +++ b/pkg/sql/drop_sequence.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" @@ -228,62 +229,83 @@ func (p *planner) canRemoveOwnedSequencesImpl( // This is called when the DropBehavior is DropCascade. func dropDependentOnSequence(ctx context.Context, p *planner, seqDesc *tabledesc.Mutable) error { for _, dependent := range seqDesc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, dependent.ID); err != nil { + desc, err := p.Descriptors().GetMutableDescriptorByID(ctx, p.txn, dependent.ID) + if err != nil { return err } + switch t := desc.(type) { + case *tabledesc.Mutable: + return dropDepTableOnSequence(ctx, p, t, seqDesc.Name, dependent.ColumnIDs) + case *funcdesc.Mutable: + return p.dropFunctionImpl(ctx, t) + default: + return errors.AssertionFailedf( + "unexpected dependent %s %s on sequence %s", + desc.DescriptorType(), desc.GetName(), seqDesc.Name, + ) + } + } + return nil +} - tblDesc, err := p.Descriptors().GetMutableTableByID(ctx, p.txn, dependent.ID, - tree.ObjectLookupFlags{ - CommonLookupFlags: tree.CommonLookupFlags{ - IncludeOffline: true, - IncludeDropped: true, - }, - }) +func dropDepTableOnSequence( + ctx context.Context, + p *planner, + tblDesc *tabledesc.Mutable, + seqName string, + depColIDs []descpb.ColumnID, +) error { + tblDesc, err := p.Descriptors().GetMutableTableByID(ctx, p.txn, tblDesc.ID, + tree.ObjectLookupFlags{ + CommonLookupFlags: tree.CommonLookupFlags{ + IncludeOffline: true, + IncludeDropped: true, + }, + }) + if err != nil { + return err + } + + // If the table that uses the sequence has been dropped already, + // no need to update, so skip. + if tblDesc.Dropped() { + return nil + } + + // If the dependent object is a view, drop the view. + if tblDesc.IsView() { + _, err = p.dropViewImpl(ctx, tblDesc, false /* queueJob */, "", tree.DropCascade) if err != nil { return err } + return nil + } - // If the table that uses the sequence has been dropped already, - // no need to update, so skip. - if tblDesc.Dropped() { - continue - } + // Set of column IDs which will have their default values dropped. + colsToDropDefault := make(map[descpb.ColumnID]struct{}) + for _, colID := range depColIDs { + colsToDropDefault[colID] = struct{}{} + } - // If the dependent object is a view, drop the view. - if tblDesc.IsView() { - _, err = p.dropViewImpl(ctx, tblDesc, false /* queueJob */, "", tree.DropCascade) - if err != nil { + // Iterate over all columns in the table, drop affected columns' default values + // and update back references. + for _, column := range tblDesc.PublicColumns() { + if _, ok := colsToDropDefault[column.GetID()]; ok { + column.ColumnDesc().DefaultExpr = nil + if err := p.removeSequenceDependencies(ctx, tblDesc, column); err != nil { return err } - continue - } - - // Set of column IDs which will have their default values dropped. - colsToDropDefault := make(map[descpb.ColumnID]struct{}) - for _, colID := range dependent.ColumnIDs { - colsToDropDefault[colID] = struct{}{} - } - - // Iterate over all columns in the table, drop affected columns' default values - // and update back references. - for _, column := range tblDesc.PublicColumns() { - if _, ok := colsToDropDefault[column.GetID()]; ok { - column.ColumnDesc().DefaultExpr = nil - if err := p.removeSequenceDependencies(ctx, tblDesc, column); err != nil { - return err - } - } } + } - jobDesc := fmt.Sprintf( - "removing default expressions using sequence %q since it is being dropped", - seqDesc.Name, - ) - if err := p.writeSchemaChange( - ctx, tblDesc, descpb.InvalidMutationID, jobDesc, - ); err != nil { - return err - } + jobDesc := fmt.Sprintf( + "removing default expressions using sequence %q since it is being dropped", + seqName, + ) + if err := p.writeSchemaChange( + ctx, tblDesc, descpb.InvalidMutationID, jobDesc, + ); err != nil { + return err } return nil } diff --git a/pkg/sql/drop_table.go b/pkg/sql/drop_table.go index 0f2ba2e75cea..84963e923f3f 100644 --- a/pkg/sql/drop_table.go +++ b/pkg/sql/drop_table.go @@ -19,6 +19,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/descmetadata" "github.com/cockroachdb/cockroach/pkg/sql/privilege" @@ -26,7 +27,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlerrors" "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" - "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/log/eventpb" "github.com/cockroachdb/cockroach/pkg/util/timeutil" @@ -84,10 +84,7 @@ func (p *planner) DropTable(ctx context.Context, n *tree.DropTable) (planNode, e } for _, ref := range droppedDesc.DependedOnBy { if _, ok := td[ref.ID]; !ok { - if err := p.maybeFailOnDroppingFunction(ctx, ref.ID); err != nil { - return nil, err - } - if err := p.canRemoveDependentView(ctx, droppedDesc, ref, n.DropBehavior); err != nil { + if err := p.canRemoveDependentFromTable(ctx, droppedDesc, ref, n.DropBehavior); err != nil { return nil, err } } @@ -275,28 +272,36 @@ func (p *planner) dropTableImpl( // Copy out the set of dependencies as it may be overwritten in the loop. dependedOnBy := append([]descpb.TableDescriptor_Reference(nil), tableDesc.DependedOnBy...) for _, ref := range dependedOnBy { - viewDesc, err := p.getViewDescForCascade( + depDesc, err := p.getDescForCascade( ctx, string(tableDesc.DescriptorType()), tableDesc.Name, tableDesc.ParentID, ref.ID, tree.DropCascade, ) if err != nil { return droppedViews, err } // This view is already getting dropped. Don't do it twice. - if viewDesc.Dropped() { + if depDesc.Dropped() { continue } - cascadedViews, err := p.dropViewImpl(ctx, viewDesc, !droppingParent, "dropping dependent view", tree.DropCascade) - if err != nil { - return droppedViews, err - } - qualifiedView, err := p.getQualifiedTableName(ctx, viewDesc) - if err != nil { - return droppedViews, err - } + switch t := depDesc.(type) { + case *tabledesc.Mutable: + cascadedViews, err := p.dropViewImpl(ctx, t, !droppingParent, "dropping dependent view", tree.DropCascade) + if err != nil { + return droppedViews, err + } + + qualifiedView, err := p.getQualifiedTableName(ctx, t) + if err != nil { + return droppedViews, err + } - droppedViews = append(droppedViews, cascadedViews...) - droppedViews = append(droppedViews, qualifiedView.FQString()) + droppedViews = append(droppedViews, cascadedViews...) + droppedViews = append(droppedViews, qualifiedView.FQString()) + case *funcdesc.Mutable: + if err := p.dropFunctionImpl(ctx, t); err != nil { + return droppedViews, err + } + } } err := p.removeTableComments(ctx, tableDesc) @@ -588,19 +593,3 @@ func (p *planner) removeTableComments(ctx context.Context, tableDesc *tabledesc. p.SessionData(), ).DeleteAllCommentsForTables(catalog.MakeDescriptorIDSet(tableDesc.GetID())) } - -// This is a guard to prevent cascade dropping an object if it's referenced by a function. -// This is because we don't support drop function at the moment. However, we'll -// add the support pretty soon. -func (p *planner) maybeFailOnDroppingFunction(ctx context.Context, id descpb.ID) error { - desc, err := p.Descriptors().GetMutableDescriptorByID(ctx, p.txn, id) - if err != nil { - return err - } - // TODO (Chengxiong): support dropping function. - if desc.DescriptorType() == catalog.Function { - return unimplemented.NewWithIssue(83235, "drop function not supported") - } - - return nil -} diff --git a/pkg/sql/drop_view.go b/pkg/sql/drop_view.go index 76a59baeec31..63bf0cddd4a5 100644 --- a/pkg/sql/drop_view.go +++ b/pkg/sql/drop_view.go @@ -15,11 +15,12 @@ import ( "fmt" "github.com/cockroachdb/cockroach/pkg/server/telemetry" + "github.com/cockroachdb/cockroach/pkg/sql/catalog" "github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb" + "github.com/cockroachdb/cockroach/pkg/sql/catalog/funcdesc" "github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc" "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/sql/sqlerrors" "github.com/cockroachdb/cockroach/pkg/sql/sqltelemetry" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/log/eventpb" @@ -68,15 +69,12 @@ func (p *planner) DropView(ctx context.Context, n *tree.DropView) (planNode, err for _, toDel := range td { droppedDesc := toDel.desc for _, ref := range droppedDesc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, ref.ID); err != nil { - return nil, err - } // Don't verify that we can remove a dependent view if that dependent // view was explicitly specified in the DROP VIEW command. if descInSlice(ref.ID, td) { continue } - if err := p.canRemoveDependentView(ctx, droppedDesc, ref, n.DropBehavior); err != nil { + if err := p.canRemoveDependentFromTable(ctx, droppedDesc, ref, n.DropBehavior); err != nil { return nil, err } } @@ -138,13 +136,39 @@ func descInSlice(descID descpb.ID, td []toDelete) bool { return false } -func (p *planner) canRemoveDependentView( +func (p *planner) canRemoveDependent( + ctx context.Context, + typeName string, + objName string, + parentID descpb.ID, + ref descpb.TableDescriptor_Reference, + behavior tree.DropBehavior, +) error { + desc, err := p.Descriptors().GetMutableDescriptorByID(ctx, p.txn, ref.ID) + if err != nil { + return err + } + + switch t := desc.(type) { + case *tabledesc.Mutable: + return p.canRemoveDependentViewGeneric(ctx, typeName, objName, parentID, t, behavior) + case *funcdesc.Mutable: + return p.canRemoveDependentFunctionGeneric(ctx, typeName, objName, t, behavior) + default: + return errors.AssertionFailedf( + "unexpected dependent %s %s on %s %s", + desc.DescriptorType(), desc.GetName(), typeName, objName, + ) + } +} + +func (p *planner) canRemoveDependentFromTable( ctx context.Context, from *tabledesc.Mutable, ref descpb.TableDescriptor_Reference, behavior tree.DropBehavior, ) error { - return p.canRemoveDependentViewGeneric(ctx, string(from.DescriptorType()), from.Name, from.ParentID, ref, behavior) + return p.canRemoveDependent(ctx, string(from.DescriptorType()), from.Name, from.ParentID, ref, behavior) } func (p *planner) canRemoveDependentViewGeneric( @@ -152,25 +176,40 @@ func (p *planner) canRemoveDependentViewGeneric( typeName string, objName string, parentID descpb.ID, - ref descpb.TableDescriptor_Reference, + viewDesc *tabledesc.Mutable, behavior tree.DropBehavior, ) error { - viewDesc, err := p.getViewDescForCascade(ctx, typeName, objName, parentID, ref.ID, behavior) - if err != nil { - return err + if behavior != tree.DropCascade { + return p.dependentViewError(ctx, typeName, objName, parentID, viewDesc, "drop") } + if err := p.CheckPrivilege(ctx, viewDesc, privilege.DROP); err != nil { return err } // If this view is depended on by other views, we have to check them as well. for _, ref := range viewDesc.DependedOnBy { - if err := p.canRemoveDependentView(ctx, viewDesc, ref, behavior); err != nil { + if err := p.canRemoveDependentFromTable(ctx, viewDesc, ref, behavior); err != nil { return err } } return nil } +func (p *planner) canRemoveDependentFunctionGeneric( + ctx context.Context, + typeName string, + objName string, + fnDesc *funcdesc.Mutable, + behavior tree.DropBehavior, +) error { + if behavior != tree.DropCascade { + return p.dependentFunctionError(typeName, objName, fnDesc, "drop") + } + // TODO(chengxiong): check backreference dependents for drop cascade. This is + // needed when we start allowing references on UDFs. + return p.canDropFunction(ctx, fnDesc) +} + // Drops the view and any additional views that depend on it. // Returns the names of any additional views that were also dropped // due to `cascade` behavior. @@ -231,26 +270,35 @@ func (p *planner) dropViewImpl( if behavior == tree.DropCascade { dependedOnBy := append([]descpb.TableDescriptor_Reference(nil), viewDesc.DependedOnBy...) for _, ref := range dependedOnBy { - dependentDesc, err := p.getViewDescForCascade( + depDesc, err := p.getDescForCascade( ctx, string(viewDesc.DescriptorType()), viewDesc.Name, viewDesc.ParentID, ref.ID, behavior, ) if err != nil { return cascadeDroppedViews, err } - qualifiedView, err := p.getQualifiedTableName(ctx, dependentDesc) - if err != nil { - return cascadeDroppedViews, err + if depDesc.Dropped() { + continue } - // Check if the dependency was already marked as dropped, - // while dealing with any earlier dependent views. - if !dependentDesc.Dropped() { - cascadedViews, err := p.dropViewImpl(ctx, dependentDesc, queueJob, "dropping dependent view", behavior) + + switch t := depDesc.(type) { + case *tabledesc.Mutable: + qualifiedView, err := p.getQualifiedTableName(ctx, t) + if err != nil { + return cascadeDroppedViews, err + } + // Check if the dependency was already marked as dropped, + // while dealing with any earlier dependent views. + cascadedViews, err := p.dropViewImpl(ctx, t, queueJob, "dropping dependent view", behavior) if err != nil { return cascadeDroppedViews, err } cascadeDroppedViews = append(cascadeDroppedViews, cascadedViews...) cascadeDroppedViews = append(cascadeDroppedViews, qualifiedView.FQString()) + case *funcdesc.Mutable: + if err := p.dropFunctionImpl(ctx, t); err != nil { + return cascadeDroppedViews, err + } } } } @@ -267,34 +315,20 @@ func (p *planner) dropViewImpl( return cascadeDroppedViews, nil } -func (p *planner) getViewDescForCascade( +func (p *planner) getDescForCascade( ctx context.Context, typeName string, objName string, - parentID, viewID descpb.ID, + parentID, descID descpb.ID, behavior tree.DropBehavior, -) (*tabledesc.Mutable, error) { - viewDesc, err := p.Descriptors().GetMutableTableVersionByID(ctx, viewID, p.txn) +) (catalog.MutableDescriptor, error) { + desc, err := p.Descriptors().GetMutableDescriptorByID(ctx, p.txn, descID) if err != nil { - log.Warningf(ctx, "unable to retrieve descriptor for view %d: %v", viewID, err) - return nil, errors.Wrapf(err, "error resolving dependent view ID %d", viewID) + log.Warningf(ctx, "unable to retrieve descriptor for %d: %v", descID, err) + return nil, errors.Wrapf(err, "error resolving dependent ID %d", descID) } if behavior != tree.DropCascade { - viewName := viewDesc.Name - if viewDesc.ParentID != parentID { - var err error - viewFQName, err := p.getQualifiedTableName(ctx, viewDesc) - if err != nil { - log.Warningf(ctx, "unable to retrieve qualified name of view %d: %v", viewID, err) - return nil, sqlerrors.NewDependentObjectErrorf( - "cannot drop %s %q because a view depends on it", typeName, objName) - } - viewName = viewFQName.FQString() - } - return nil, errors.WithHintf( - sqlerrors.NewDependentObjectErrorf("cannot drop %s %q because view %q depends on it", - typeName, objName, viewName), - "you can drop %s instead.", viewName) + return nil, p.dependentError(ctx, typeName, objName, parentID, descID, "drop") } - return viewDesc, nil + return desc, nil } diff --git a/pkg/sql/function_resolver_test.go b/pkg/sql/function_resolver_test.go index 4a7d1ffd206a..773c218d0d20 100644 --- a/pkg/sql/function_resolver_test.go +++ b/pkg/sql/function_resolver_test.go @@ -219,7 +219,7 @@ CREATE FUNCTION sc1.lower() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ SELECT 3 $$ testName: "unsupported builtin function", funName: tree.UnresolvedName{NumParts: 1, Parts: tree.NameParts{"querytree", "", "", ""}}, searchPath: []string{"sc1", "sc2"}, - expectedErr: "querytree(): unimplemented: this function is not yet supported", + expectedErr: `querytree\(\): unimplemented: this function is not yet supported`, }, // TODO(Chengxiong): add test case for builtin function names when builtin // OIDs are changed to fixed IDs. @@ -248,7 +248,7 @@ CREATE FUNCTION sc1.lower() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ SELECT 3 $$ path := sessiondata.MakeSearchPath(tc.searchPath) funcDef, err := funcResolver.ResolveFunction(ctx, &tc.funName, &path) if tc.expectedErr != "" { - require.Equal(t, tc.expectedErr, err.Error()) + require.Regexp(t, tc.expectedErr, err.Error()) continue } require.NoError(t, err) @@ -391,7 +391,7 @@ CREATE FUNCTION sc1.lower(a STRING) RETURNS STRING IMMUTABLE LANGUAGE SQL AS $$ } typeChecked, err := tree.TypeCheck(ctx, expr, &semaCtx, desired) if tc.expectedErr != "" { - require.Equal(t, tc.expectedErr, err.Error()) + require.Regexp(t, tc.expectedErr, err.Error()) return } require.NoError(t, err) diff --git a/pkg/sql/importer/import_table_creation.go b/pkg/sql/importer/import_table_creation.go index 1d9b7c1141f7..9846bab3f5b8 100644 --- a/pkg/sql/importer/import_table_creation.go +++ b/pkg/sql/importer/import_table_creation.go @@ -447,3 +447,17 @@ func (r fkResolver) GetQualifiedTableNameByID( ) (*tree.TableName, error) { return nil, errSchemaResolver } + +// ResolveFunction implements the resolver.SchemaResolver interface. +func (r fkResolver) ResolveFunction( + ctx context.Context, name *tree.UnresolvedName, path tree.SearchPath, +) (*tree.ResolvedFunctionDefinition, error) { + return nil, errSchemaResolver +} + +// ResolveFunctionByOID implements the resolver.SchemaResolver interface. +func (r fkResolver) ResolveFunctionByOID( + ctx context.Context, oid oid.Oid, +) (string, *tree.Overload, error) { + return "", nil, errSchemaResolver +} diff --git a/pkg/sql/logictest/testdata/logic_test/crdb_internal b/pkg/sql/logictest/testdata/logic_test/crdb_internal index 57a4de5d088c..3e790d4f2350 100644 --- a/pkg/sql/logictest/testdata/logic_test/crdb_internal +++ b/pkg/sql/logictest/testdata/logic_test/crdb_internal @@ -23,6 +23,7 @@ crdb_internal cluster_contended_tables view admin NULL NULL crdb_internal cluster_contention_events table admin NULL NULL crdb_internal cluster_database_privileges table admin NULL NULL crdb_internal cluster_distsql_flows table admin NULL NULL +crdb_internal cluster_execution_insights table admin NULL NULL crdb_internal cluster_inflight_traces table admin NULL NULL crdb_internal cluster_locks table admin NULL NULL crdb_internal cluster_queries table admin NULL NULL diff --git a/pkg/sql/logictest/testdata/logic_test/create_statements b/pkg/sql/logictest/testdata/logic_test/create_statements index b6526a2ed2d6..543ad9394a3e 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_statements +++ b/pkg/sql/logictest/testdata/logic_test/create_statements @@ -243,6 +243,49 @@ CREATE TABLE crdb_internal.cluster_distsql_flows ( since TIMESTAMPTZ NOT NULL, status STRING NOT NULL ) {} {} +CREATE TABLE crdb_internal.cluster_execution_insights ( + session_id STRING NOT NULL, + txn_id UUID NOT NULL, + txn_fingerprint_id BYTES NOT NULL, + stmt_id STRING NOT NULL, + stmt_fingerprint_id BYTES NOT NULL, + query STRING NOT NULL, + status STRING NOT NULL, + start_time TIMESTAMP NOT NULL, + end_time TIMESTAMP NOT NULL, + full_scan BOOL NOT NULL, + user_name STRING NOT NULL, + app_name STRING NOT NULL, + database_name STRING NOT NULL, + plan_gist STRING NOT NULL, + rows_read INT8 NOT NULL, + rows_written INT8 NOT NULL, + priority FLOAT8 NOT NULL, + retries INT8 NOT NULL, + last_retry_reason STRING NULL, + exec_node_ids INT8[] NOT NULL +) CREATE TABLE crdb_internal.cluster_execution_insights ( + session_id STRING NOT NULL, + txn_id UUID NOT NULL, + txn_fingerprint_id BYTES NOT NULL, + stmt_id STRING NOT NULL, + stmt_fingerprint_id BYTES NOT NULL, + query STRING NOT NULL, + status STRING NOT NULL, + start_time TIMESTAMP NOT NULL, + end_time TIMESTAMP NOT NULL, + full_scan BOOL NOT NULL, + user_name STRING NOT NULL, + app_name STRING NOT NULL, + database_name STRING NOT NULL, + plan_gist STRING NOT NULL, + rows_read INT8 NOT NULL, + rows_written INT8 NOT NULL, + priority FLOAT8 NOT NULL, + retries INT8 NOT NULL, + last_retry_reason STRING NULL, + exec_node_ids INT8[] NOT NULL +) {} {} CREATE TABLE crdb_internal.cluster_inflight_traces ( trace_id INT8 NOT NULL, node_id INT8 NOT NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/grant_table b/pkg/sql/logictest/testdata/logic_test/grant_table index 8b57fbe584b7..f3f1e8429a26 100644 --- a/pkg/sql/logictest/testdata/logic_test/grant_table +++ b/pkg/sql/logictest/testdata/logic_test/grant_table @@ -36,6 +36,7 @@ test crdb_internal cluster_contended_tables public test crdb_internal cluster_contention_events public SELECT false test crdb_internal cluster_database_privileges public SELECT false test crdb_internal cluster_distsql_flows public SELECT false +test crdb_internal cluster_execution_insights public SELECT false test crdb_internal cluster_inflight_traces public SELECT false test crdb_internal cluster_locks public SELECT false test crdb_internal cluster_queries public SELECT false diff --git a/pkg/sql/logictest/testdata/logic_test/information_schema b/pkg/sql/logictest/testdata/logic_test/information_schema index 00270a1ff308..7b10b9414ec6 100644 --- a/pkg/sql/logictest/testdata/logic_test/information_schema +++ b/pkg/sql/logictest/testdata/logic_test/information_schema @@ -401,6 +401,7 @@ crdb_internal cluster_contended_tables crdb_internal cluster_contention_events crdb_internal cluster_database_privileges crdb_internal cluster_distsql_flows +crdb_internal cluster_execution_insights crdb_internal cluster_inflight_traces crdb_internal cluster_locks crdb_internal cluster_queries @@ -726,6 +727,7 @@ cluster_contended_tables cluster_contention_events cluster_database_privileges cluster_distsql_flows +cluster_execution_insights cluster_inflight_traces cluster_locks cluster_queries @@ -1090,6 +1092,7 @@ system crdb_internal cluster_contended_tables SYSTEM system crdb_internal cluster_contention_events SYSTEM VIEW NO 1 system crdb_internal cluster_database_privileges SYSTEM VIEW NO 1 system crdb_internal cluster_distsql_flows SYSTEM VIEW NO 1 +system crdb_internal cluster_execution_insights SYSTEM VIEW NO 1 system crdb_internal cluster_inflight_traces SYSTEM VIEW NO 1 system crdb_internal cluster_locks SYSTEM VIEW NO 1 system crdb_internal cluster_queries SYSTEM VIEW NO 1 @@ -2744,6 +2747,7 @@ NULL public system crdb_internal cluster_contended_tables NULL public system crdb_internal cluster_contention_events SELECT NO YES NULL public system crdb_internal cluster_database_privileges SELECT NO YES NULL public system crdb_internal cluster_distsql_flows SELECT NO YES +NULL public system crdb_internal cluster_execution_insights SELECT NO YES NULL public system crdb_internal cluster_inflight_traces SELECT NO YES NULL public system crdb_internal cluster_locks SELECT NO YES NULL public system crdb_internal cluster_queries SELECT NO YES @@ -3315,6 +3319,7 @@ NULL public system crdb_internal cluster_contended_tables NULL public system crdb_internal cluster_contention_events SELECT NO YES NULL public system crdb_internal cluster_database_privileges SELECT NO YES NULL public system crdb_internal cluster_distsql_flows SELECT NO YES +NULL public system crdb_internal cluster_execution_insights SELECT NO YES NULL public system crdb_internal cluster_inflight_traces SELECT NO YES NULL public system crdb_internal cluster_locks SELECT NO YES NULL public system crdb_internal cluster_queries SELECT NO YES diff --git a/pkg/sql/logictest/testdata/logic_test/lookup_join b/pkg/sql/logictest/testdata/logic_test/lookup_join index d3ff2a6735d1..c00860d23b3a 100644 --- a/pkg/sql/logictest/testdata/logic_test/lookup_join +++ b/pkg/sql/logictest/testdata/logic_test/lookup_join @@ -14,6 +14,25 @@ statement ok CREATE TABLE def_e_decimal (d INT, e DECIMAL, f INT, PRIMARY KEY (f, e)); INSERT INTO def_e_decimal VALUES (1, 1, 2), (2, 1, 1), (NULL, 2, 1) +statement ok +CREATE TABLE float_xy (x FLOAT, y INT, INDEX asc_idx (x, y), INDEX desc_idx (x DESC, y)); +INSERT INTO float_xy VALUES (1, 1), (2, 1), (NULL, 2), ('NaN'::FLOAT, 3), ('+Inf'::FLOAT, 4), ('-Inf'::FLOAT, 5); + +statement ok +CREATE TABLE string_xy (x TEXT, y INT, INDEX asc_idx (x, y), INDEX desc_idx (x DESC, y)); +INSERT INTO string_xy VALUES ('abc', 1), ('abcd', 2), ('bcd', 3), ('xyz', 4), ('', 5), (NULL, 6); + +statement ok +CREATE TABLE time_xy (x TIME, y TIMESTAMP, INDEX x_idx (x), INDEX y_idx (y)); +INSERT INTO time_xy +VALUES +('00:00:00'::TIME, '2016-06-22 19:10:25'::TIMESTAMP), +('24:00:00'::TIME, '2042-01-01 00:00:00'::TIMESTAMP), +('infinity'::TIME, '1970-01-01 00:00:00'::TIMESTAMP), +('00:52:12.19515'::TIME, NULL), +(NULL, 'infinity'::TIMESTAMP), +('-infinity'::TIME, '-infinity'::TIMESTAMP); + statement ok CREATE TABLE gh (g INT, h INT, INDEX g_idx (g)); INSERT INTO gh VALUES (NULL, 1) @@ -916,3 +935,534 @@ x y z u v w 2 1 5 2 1 5 2 1 6 2 1 4 2 1 6 2 1 5 + +# Test inequality lookup joins. +# Case with idxCol <= inputCol. +query IIIIII +SELECT a, b, c, d, e, f FROM abc INNER LOOKUP JOIN def ON f <= a ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 +1 1 2 2 1 1 +2 NULL 2 NULL 2 1 +2 NULL 2 1 1 2 +2 NULL 2 2 1 1 +2 1 1 NULL 2 1 +2 1 1 1 1 2 +2 1 1 2 1 1 + +# Case with idxCol >= inputCol (same output as last test). +query IIIIII +SELECT a, b, c, d, e, f FROM def INNER LOOKUP JOIN abc ON a >= f ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 +1 1 2 2 1 1 +2 NULL 2 NULL 2 1 +2 NULL 2 1 1 2 +2 NULL 2 2 1 1 +2 1 1 NULL 2 1 +2 1 1 1 1 2 +2 1 1 2 1 1 + +# Case with idxCol < inputCol. +query IIIIII +SELECT a, b, c, d, e, f FROM abc INNER LOOKUP JOIN def ON f < a ORDER BY a, b, c, d, e, f +---- +2 NULL 2 NULL 2 1 +2 NULL 2 2 1 1 +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case with idxCol > inputCol (same output as last test). +query IIIIII +SELECT a, b, c, d, e, f FROM def INNER LOOKUP JOIN abc ON a > f ORDER BY a, b, c, d, e, f +---- +2 NULL 2 NULL 2 1 +2 NULL 2 2 1 1 +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case where input column used as bound has null. +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a >= d +---- +1 1 2 1 1 2 +1 1 2 2 1 1 +1 1 2 2 NULL 2 +2 1 1 2 1 1 +2 1 1 2 NULL 2 + +# Case where input column used as bound has null (idxCol > inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a > d +---- +1 1 2 2 1 1 +1 1 2 2 NULL 2 + +# Case where input column used as bound has null (idxCol >= inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a >= d +---- +1 1 2 1 1 2 +1 1 2 2 1 1 +1 1 2 2 NULL 2 +2 1 1 2 1 1 +2 1 1 2 NULL 2 + +# Case where input column used as bound has null (idxCol < inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a < d +---- +2 1 1 1 1 2 + +# Case where input column used as bound has null (idxCol <= inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a <= d +---- +2 1 1 1 1 2 +2 1 1 2 1 1 +2 1 1 2 NULL 2 +1 1 2 1 1 2 + +# Case with two inequalities. +query IIIIII +SELECT a, b, c, d, e, f FROM abc INNER LOOKUP JOIN def ON f < a AND f >= b ORDER BY a, b, c, d, e, f +---- +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case with two inequalities (same output as last test). +query IIIIII +SELECT a, b, c, d, e, f FROM def INNER LOOKUP JOIN abc ON f < a AND f >= b ORDER BY a, b, c, d, e, f +---- +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case with two inequalities, one is a constant. +query IIIIII rowsort +SELECT * FROM abc INNER LOOKUP JOIN def ON f < 2 AND f >= b +---- +1 1 2 2 1 1 +2 1 1 2 1 1 +1 1 2 NULL 2 1 +2 1 1 NULL 2 1 + +# Case with two inequalities, one is a constant. +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN abc ON a < 2 AND a >= d +---- +1 1 2 1 1 2 + +# Case with equality prefix. +query IIIIII rowsort +SELECT * FROM abc INNER LOOKUP JOIN def ON f = c AND e >= b +---- +2 1 1 2 1 1 +2 1 1 NULL 2 1 +1 1 2 1 1 2 + +# Case with equality prefix. +query IIIIII +SELECT a, b, c, d, e, f FROM abc INNER LOOKUP JOIN def ON f = a AND e >= c ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 +2 1 1 1 1 2 + +# Case with equality prefix (same output as last test). +query IIIIII +SELECT a, b, c, d, e, f FROM def INNER LOOKUP JOIN abc ON f = a AND e >= c ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 +2 1 1 1 1 2 + +# Case with descending index column (idxCol < inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN def_e_desc AS def2 ON def.f = def2.f AND def2.e < def.d +---- +2 1 1 2 1 1 + +# Case with descending index column (idxCol <= inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN def_e_desc AS def2 +ON def.f = def2.f AND def2.e <= def.d ORDER BY def.d, def.e, def.f, def2.d, def2.e, def2.f +---- +1 1 2 1 1 2 +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case with descending index column (idxCol > inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN def_e_desc AS def2 ON def.f = def2.f AND def2.e > def.d +---- + +# Case with descending index column (idxCol >= inputCol). +query IIIIII rowsort +SELECT * FROM def INNER LOOKUP JOIN def_e_desc AS def2 ON def.f = def2.f AND def2.e >= def.d +---- +2 1 1 NULL 2 1 +1 1 2 1 1 2 + +# Case with maximum and minimum integer bounds. +query IIII rowsort +SELECT * FROM (SELECT * FROM (VALUES (-9223372036854775807::INT), (9223372036854775807::INT))) v(x) +LEFT LOOKUP JOIN abc ON a < x +---- +9223372036854775807 1 1 2 +9223372036854775807 2 1 1 +9223372036854775807 2 NULL 2 +-9223372036854775807 NULL NULL NULL + +# Case with maximum and minimum integer bounds. +query IIII rowsort +SELECT * FROM (SELECT * FROM (VALUES (-9223372036854775807::INT), (9223372036854775807::INT))) v(x) +LEFT LOOKUP JOIN abc ON a > x +---- +-9223372036854775807 1 1 2 +-9223372036854775807 2 1 1 +-9223372036854775807 2 NULL 2 +9223372036854775807 NULL NULL NULL + +# Case with maximum and minimum integer bounds on descending column. +query IIII rowsort +SELECT * FROM (SELECT * FROM (VALUES (-9223372036854775807::INT), (9223372036854775807::INT))) v(x) +LEFT LOOKUP JOIN def_e_desc ON f IN (1, 2) AND e < x +---- +9223372036854775807 NULL 2 1 +9223372036854775807 2 1 1 +9223372036854775807 1 1 2 +-9223372036854775807 NULL NULL NULL + +# Case with maximum and minimum integer bounds on descending column. +query IIII rowsort +SELECT * FROM (SELECT * FROM (VALUES (-9223372036854775807::INT), (9223372036854775807::INT))) v(x) +LEFT LOOKUP JOIN def_e_desc ON f IN (1, 2) AND e > x +---- +-9223372036854775807 NULL 2 1 +-9223372036854775807 2 1 1 +-9223372036854775807 1 1 2 +9223372036854775807 NULL NULL NULL + +# Case with idxCol <= inputCol and decimal column type. +query IIIIRI +SELECT * FROM abc INNER LOOKUP JOIN def_e_decimal ON f = b AND e <= a::DECIMAL ORDER BY a, b, c, d, e, f +---- +1 1 2 2 1 1 +2 1 1 NULL 2 1 +2 1 1 2 1 1 + +# Case with idxCol >= inputCol and decimal column type. +query IIIIRI +SELECT * FROM abc INNER LOOKUP JOIN def_e_decimal ON f = b AND e >= a::DECIMAL ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 +1 1 2 2 1 1 +2 1 1 NULL 2 1 + +# Case with idxCol < inputCol and decimal column type. +query IIIIRI +SELECT * FROM abc INNER LOOKUP JOIN def_e_decimal ON f = b AND e < a::DECIMAL ORDER BY a, b, c, d, e, f +---- +2 1 1 2 1 1 + +# Case with idxCol > inputCol and decimal column type. +query IIIIRI +SELECT * FROM abc INNER LOOKUP JOIN def_e_decimal ON f = b AND e > a::DECIMAL ORDER BY a, b, c, d, e, f +---- +1 1 2 NULL 2 1 + +# Case with idxCol <= inputCol and float column type. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@asc_idx ON x <= a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 NaN 3 +1 1 2 -Inf 5 +1 1 2 1 1 +2 NULL 2 NaN 3 +2 NULL 2 -Inf 5 +2 NULL 2 1 1 +2 NULL 2 2 1 +2 1 1 NaN 3 +2 1 1 -Inf 5 +2 1 1 1 1 +2 1 1 2 1 + +# Case with idxCol >= inputCol and float column type. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@asc_idx ON x >= a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 1 1 +1 1 2 2 1 +1 1 2 +Inf 4 +2 NULL 2 2 1 +2 NULL 2 +Inf 4 +2 1 1 2 1 +2 1 1 +Inf 4 + +# Case with idxCol < inputCol and float column type. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@asc_idx ON x < a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 NaN 3 +1 1 2 -Inf 5 +2 NULL 2 NaN 3 +2 NULL 2 -Inf 5 +2 NULL 2 1 1 +2 1 1 NaN 3 +2 1 1 -Inf 5 +2 1 1 1 1 + +# Case with idxCol > inputCol and float column type. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@asc_idx ON x > a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 2 1 +1 1 2 +Inf 4 +2 NULL 2 +Inf 4 +2 1 1 +Inf 4 + +# Case with idxCol <= inputCol and float column type. Index is descending. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@desc_idx ON x <= a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 NaN 3 +1 1 2 -Inf 5 +1 1 2 1 1 +2 NULL 2 NaN 3 +2 NULL 2 -Inf 5 +2 NULL 2 1 1 +2 NULL 2 2 1 +2 1 1 NaN 3 +2 1 1 -Inf 5 +2 1 1 1 1 +2 1 1 2 1 + +# Case with idxCol >= inputCol and float column type. Index is descending. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@desc_idx ON x >= a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 1 1 +1 1 2 2 1 +1 1 2 +Inf 4 +2 NULL 2 2 1 +2 NULL 2 +Inf 4 +2 1 1 2 1 +2 1 1 +Inf 4 + +# Case with idxCol < inputCol and float column type. Index is descending. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@desc_idx ON x < a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 NaN 3 +1 1 2 -Inf 5 +2 NULL 2 NaN 3 +2 NULL 2 -Inf 5 +2 NULL 2 1 1 +2 1 1 NaN 3 +2 1 1 -Inf 5 +2 1 1 1 1 + +# Case with idxCol > inputCol and float column type. Index is descending. +query IIIFI +SELECT * FROM abc INNER LOOKUP JOIN float_xy@desc_idx ON x > a::FLOAT ORDER BY a, b, c, x, y +---- +1 1 2 2 1 +1 1 2 +Inf 4 +2 NULL 2 +Inf 4 +2 1 1 +Inf 4 + +query TITI +SELECT * FROM string_xy xy1 INNER LOOKUP JOIN string_xy xy2 ON xy2.x < xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +abc 1 · 5 +abcd 2 · 5 +abcd 2 abc 1 +bcd 3 · 5 +bcd 3 abc 1 +bcd 3 abcd 2 +xyz 4 · 5 +xyz 4 abc 1 +xyz 4 abcd 2 +xyz 4 bcd 3 + +query TITI +SELECT * FROM string_xy xy1 INNER LOOKUP JOIN string_xy xy2 ON xy2.x > xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +· 5 abc 1 +· 5 abcd 2 +· 5 bcd 3 +· 5 xyz 4 +abc 1 abcd 2 +abc 1 bcd 3 +abc 1 xyz 4 +abcd 2 bcd 3 +abcd 2 xyz 4 +bcd 3 xyz 4 + +query TITI +SELECT * FROM string_xy xy1 INNER LOOKUP JOIN string_xy xy2 ON xy2.x <= xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +· 5 · 5 +abc 1 · 5 +abc 1 abc 1 +abcd 2 · 5 +abcd 2 abc 1 +abcd 2 abcd 2 +bcd 3 · 5 +bcd 3 abc 1 +bcd 3 abcd 2 +bcd 3 bcd 3 +xyz 4 · 5 +xyz 4 abc 1 +xyz 4 abcd 2 +xyz 4 bcd 3 +xyz 4 xyz 4 + +query TITI +SELECT * FROM string_xy xy1 INNER LOOKUP JOIN string_xy xy2 ON xy2.x >= xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +· 5 · 5 +· 5 abc 1 +· 5 abcd 2 +· 5 bcd 3 +· 5 xyz 4 +abc 1 abc 1 +abc 1 abcd 2 +abc 1 bcd 3 +abc 1 xyz 4 +abcd 2 abcd 2 +abcd 2 bcd 3 +abcd 2 xyz 4 +bcd 3 bcd 3 +bcd 3 xyz 4 +xyz 4 xyz 4 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.x < xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.x > xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.x <= xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.x >= xy1.x ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 00:52:12.19515 +0000 UTC NULL +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:52:12.19515 +0000 UTC NULL 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.y < xy1.y ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.y > xy1.y ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.y <= xy1.y ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +NULL 294276-12-31 23:59:59.999999 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +NULL 294276-12-31 23:59:59.999999 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 + +query TTTT +SELECT * FROM time_xy xy1 INNER LOOKUP JOIN time_xy xy2 ON xy2.y >= xy1.y ORDER BY xy1.x, xy1.y, xy2.x, xy2.y +---- +NULL 294276-12-31 23:59:59.999999 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC -4713-11-24 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 00:00:00 +0000 UTC 2016-06-22 19:10:25 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 +0000-01-01 23:59:59.999999 +0000 UTC 1970-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 NULL 294276-12-31 23:59:59.999999 +0000 +0000 +0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 0000-01-02 00:00:00 +0000 UTC 2042-01-01 00:00:00 +0000 +0000 diff --git a/pkg/sql/logictest/testdata/logic_test/lookup_join_spans b/pkg/sql/logictest/testdata/logic_test/lookup_join_spans index c9201e6b40d2..78146177364d 100644 --- a/pkg/sql/logictest/testdata/logic_test/lookup_join_spans +++ b/pkg/sql/logictest/testdata/logic_test/lookup_join_spans @@ -425,7 +425,7 @@ WHERE name='cpu' ORDER BY value ---- -2 2020-01-01 00:01:01 +0000 UTC -11 4 2 1 cpu +2 2020-01-01 00:01:01 +0000 UTC -11 4 2 1 cpu # Test NULL values in <= unbounded lookup span. query ITIIIIT @@ -452,8 +452,8 @@ WHERE name='cpu' ORDER BY value ---- -2 2020-01-01 00:01:01 +0000 UTC -11 4 2 1 cpu -2 2020-01-01 00:01:02 +0000 UTC -10 5 2 1 cpu +2 2020-01-01 00:01:01 +0000 UTC -11 4 2 1 cpu +2 2020-01-01 00:01:02 +0000 UTC -10 5 2 1 cpu # Test NULL values in WHERE equality conditions. query ITIIIIT diff --git a/pkg/sql/logictest/testdata/logic_test/pg_builtins b/pkg/sql/logictest/testdata/logic_test/pg_builtins index 78b05e746555..04485b716310 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_builtins +++ b/pkg/sql/logictest/testdata/logic_test/pg_builtins @@ -177,42 +177,42 @@ is_updatable b 120 2 28 is_updatable c 120 3 28 false is_updatable_view a 121 1 0 false is_updatable_view b 121 2 0 false -pg_class oid 4294967124 1 0 false -pg_class relname 4294967124 2 0 false -pg_class relnamespace 4294967124 3 0 false -pg_class reltype 4294967124 4 0 false -pg_class reloftype 4294967124 5 0 false -pg_class relowner 4294967124 6 0 false -pg_class relam 4294967124 7 0 false -pg_class relfilenode 4294967124 8 0 false -pg_class reltablespace 4294967124 9 0 false -pg_class relpages 4294967124 10 0 false -pg_class reltuples 4294967124 11 0 false -pg_class relallvisible 4294967124 12 0 false -pg_class reltoastrelid 4294967124 13 0 false -pg_class relhasindex 4294967124 14 0 false -pg_class relisshared 4294967124 15 0 false -pg_class relpersistence 4294967124 16 0 false -pg_class relistemp 4294967124 17 0 false -pg_class relkind 4294967124 18 0 false -pg_class relnatts 4294967124 19 0 false -pg_class relchecks 4294967124 20 0 false -pg_class relhasoids 4294967124 21 0 false -pg_class relhaspkey 4294967124 22 0 false -pg_class relhasrules 4294967124 23 0 false -pg_class relhastriggers 4294967124 24 0 false -pg_class relhassubclass 4294967124 25 0 false -pg_class relfrozenxid 4294967124 26 0 false -pg_class relacl 4294967124 27 0 false -pg_class reloptions 4294967124 28 0 false -pg_class relforcerowsecurity 4294967124 29 0 false -pg_class relispartition 4294967124 30 0 false -pg_class relispopulated 4294967124 31 0 false -pg_class relreplident 4294967124 32 0 false -pg_class relrewrite 4294967124 33 0 false -pg_class relrowsecurity 4294967124 34 0 false -pg_class relpartbound 4294967124 35 0 false -pg_class relminmxid 4294967124 36 0 false +pg_class oid 4294967123 1 0 false +pg_class relname 4294967123 2 0 false +pg_class relnamespace 4294967123 3 0 false +pg_class reltype 4294967123 4 0 false +pg_class reloftype 4294967123 5 0 false +pg_class relowner 4294967123 6 0 false +pg_class relam 4294967123 7 0 false +pg_class relfilenode 4294967123 8 0 false +pg_class reltablespace 4294967123 9 0 false +pg_class relpages 4294967123 10 0 false +pg_class reltuples 4294967123 11 0 false +pg_class relallvisible 4294967123 12 0 false +pg_class reltoastrelid 4294967123 13 0 false +pg_class relhasindex 4294967123 14 0 false +pg_class relisshared 4294967123 15 0 false +pg_class relpersistence 4294967123 16 0 false +pg_class relistemp 4294967123 17 0 false +pg_class relkind 4294967123 18 0 false +pg_class relnatts 4294967123 19 0 false +pg_class relchecks 4294967123 20 0 false +pg_class relhasoids 4294967123 21 0 false +pg_class relhaspkey 4294967123 22 0 false +pg_class relhasrules 4294967123 23 0 false +pg_class relhastriggers 4294967123 24 0 false +pg_class relhassubclass 4294967123 25 0 false +pg_class relfrozenxid 4294967123 26 0 false +pg_class relacl 4294967123 27 0 false +pg_class reloptions 4294967123 28 0 false +pg_class relforcerowsecurity 4294967123 29 0 false +pg_class relispartition 4294967123 30 0 false +pg_class relispopulated 4294967123 31 0 false +pg_class relreplident 4294967123 32 0 false +pg_class relrewrite 4294967123 33 0 false +pg_class relrowsecurity 4294967123 34 0 false +pg_class relpartbound 4294967123 35 0 false +pg_class relminmxid 4294967123 36 0 false # Check that the oid does not exist. If this test fail, change the oid here and in diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 9e335baf9ba0..166843d4f597 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -1479,16 +1479,16 @@ FROM pg_catalog.pg_depend ORDER BY objid, refobjid, refobjsubid ---- classid objid objsubid refclassid refobjid refobjsubid deptype -4294967121 111 0 4294967124 110 14 a -4294967121 112 0 4294967124 110 15 a -4294967121 192087236 0 4294967124 0 0 n -4294967078 842401391 0 4294967124 110 1 n -4294967078 842401391 0 4294967124 110 2 n -4294967078 842401391 0 4294967124 110 3 n -4294967078 842401391 0 4294967124 110 4 n -4294967121 2061447344 0 4294967124 3687884464 0 n -4294967121 3764151187 0 4294967124 0 0 n -4294967121 3836426375 0 4294967124 3687884465 0 n +4294967120 111 0 4294967123 110 14 a +4294967120 112 0 4294967123 110 15 a +4294967120 192087236 0 4294967123 0 0 n +4294967077 842401391 0 4294967123 110 1 n +4294967077 842401391 0 4294967123 110 2 n +4294967077 842401391 0 4294967123 110 3 n +4294967077 842401391 0 4294967123 110 4 n +4294967120 2061447344 0 4294967123 3687884464 0 n +4294967120 3764151187 0 4294967123 0 0 n +4294967120 3836426375 0 4294967123 3687884465 0 n # Some entries in pg_depend are dependency links from the pg_constraint system # table to the pg_class system table. Other entries are links to pg_class when it is @@ -1501,8 +1501,8 @@ JOIN pg_class cla ON classid=cla.oid JOIN pg_class refcla ON refclassid=refcla.oid ---- classid refclassid tablename reftablename -4294967078 4294967124 pg_rewrite pg_class -4294967121 4294967124 pg_constraint pg_class +4294967077 4294967123 pg_rewrite pg_class +4294967120 4294967123 pg_constraint pg_class # Some entries in pg_depend are foreign key constraints that reference an index # in pg_class. Other entries are table-view dependencies @@ -1697,287 +1697,288 @@ oid typname typnamespace typowner typ 100132 _newtype1 3082627813 1546506610 -1 false b 100133 newtype2 3082627813 1546506610 -1 false e 100134 _newtype2 3082627813 1546506610 -1 false b -4294967003 spatial_ref_sys 1700435119 2310524507 -1 false c -4294967004 geometry_columns 1700435119 2310524507 -1 false c -4294967005 geography_columns 1700435119 2310524507 -1 false c -4294967007 pg_views 591606261 2310524507 -1 false c -4294967008 pg_user 591606261 2310524507 -1 false c -4294967009 pg_user_mappings 591606261 2310524507 -1 false c -4294967010 pg_user_mapping 591606261 2310524507 -1 false c -4294967011 pg_type 591606261 2310524507 -1 false c -4294967012 pg_ts_template 591606261 2310524507 -1 false c -4294967013 pg_ts_parser 591606261 2310524507 -1 false c -4294967014 pg_ts_dict 591606261 2310524507 -1 false c -4294967015 pg_ts_config 591606261 2310524507 -1 false c -4294967016 pg_ts_config_map 591606261 2310524507 -1 false c -4294967017 pg_trigger 591606261 2310524507 -1 false c -4294967018 pg_transform 591606261 2310524507 -1 false c -4294967019 pg_timezone_names 591606261 2310524507 -1 false c -4294967020 pg_timezone_abbrevs 591606261 2310524507 -1 false c -4294967021 pg_tablespace 591606261 2310524507 -1 false c -4294967022 pg_tables 591606261 2310524507 -1 false c -4294967023 pg_subscription 591606261 2310524507 -1 false c -4294967024 pg_subscription_rel 591606261 2310524507 -1 false c -4294967025 pg_stats 591606261 2310524507 -1 false c -4294967026 pg_stats_ext 591606261 2310524507 -1 false c -4294967027 pg_statistic 591606261 2310524507 -1 false c -4294967028 pg_statistic_ext 591606261 2310524507 -1 false c -4294967029 pg_statistic_ext_data 591606261 2310524507 -1 false c -4294967030 pg_statio_user_tables 591606261 2310524507 -1 false c -4294967031 pg_statio_user_sequences 591606261 2310524507 -1 false c -4294967032 pg_statio_user_indexes 591606261 2310524507 -1 false c -4294967033 pg_statio_sys_tables 591606261 2310524507 -1 false c -4294967034 pg_statio_sys_sequences 591606261 2310524507 -1 false c -4294967035 pg_statio_sys_indexes 591606261 2310524507 -1 false c -4294967036 pg_statio_all_tables 591606261 2310524507 -1 false c -4294967037 pg_statio_all_sequences 591606261 2310524507 -1 false c -4294967038 pg_statio_all_indexes 591606261 2310524507 -1 false c -4294967039 pg_stat_xact_user_tables 591606261 2310524507 -1 false c -4294967040 pg_stat_xact_user_functions 591606261 2310524507 -1 false c -4294967041 pg_stat_xact_sys_tables 591606261 2310524507 -1 false c -4294967042 pg_stat_xact_all_tables 591606261 2310524507 -1 false c -4294967043 pg_stat_wal_receiver 591606261 2310524507 -1 false c -4294967044 pg_stat_user_tables 591606261 2310524507 -1 false c -4294967045 pg_stat_user_indexes 591606261 2310524507 -1 false c -4294967046 pg_stat_user_functions 591606261 2310524507 -1 false c -4294967047 pg_stat_sys_tables 591606261 2310524507 -1 false c -4294967048 pg_stat_sys_indexes 591606261 2310524507 -1 false c -4294967049 pg_stat_subscription 591606261 2310524507 -1 false c -4294967050 pg_stat_ssl 591606261 2310524507 -1 false c -4294967051 pg_stat_slru 591606261 2310524507 -1 false c -4294967052 pg_stat_replication 591606261 2310524507 -1 false c -4294967053 pg_stat_progress_vacuum 591606261 2310524507 -1 false c -4294967054 pg_stat_progress_create_index 591606261 2310524507 -1 false c -4294967055 pg_stat_progress_cluster 591606261 2310524507 -1 false c -4294967056 pg_stat_progress_basebackup 591606261 2310524507 -1 false c -4294967057 pg_stat_progress_analyze 591606261 2310524507 -1 false c -4294967058 pg_stat_gssapi 591606261 2310524507 -1 false c -4294967059 pg_stat_database 591606261 2310524507 -1 false c -4294967060 pg_stat_database_conflicts 591606261 2310524507 -1 false c -4294967061 pg_stat_bgwriter 591606261 2310524507 -1 false c -4294967062 pg_stat_archiver 591606261 2310524507 -1 false c -4294967063 pg_stat_all_tables 591606261 2310524507 -1 false c -4294967064 pg_stat_all_indexes 591606261 2310524507 -1 false c -4294967065 pg_stat_activity 591606261 2310524507 -1 false c -4294967066 pg_shmem_allocations 591606261 2310524507 -1 false c -4294967067 pg_shdepend 591606261 2310524507 -1 false c -4294967068 pg_shseclabel 591606261 2310524507 -1 false c -4294967069 pg_shdescription 591606261 2310524507 -1 false c -4294967070 pg_shadow 591606261 2310524507 -1 false c -4294967071 pg_settings 591606261 2310524507 -1 false c -4294967072 pg_sequences 591606261 2310524507 -1 false c -4294967073 pg_sequence 591606261 2310524507 -1 false c -4294967074 pg_seclabel 591606261 2310524507 -1 false c -4294967075 pg_seclabels 591606261 2310524507 -1 false c -4294967076 pg_rules 591606261 2310524507 -1 false c -4294967077 pg_roles 591606261 2310524507 -1 false c -4294967078 pg_rewrite 591606261 2310524507 -1 false c -4294967079 pg_replication_slots 591606261 2310524507 -1 false c -4294967080 pg_replication_origin 591606261 2310524507 -1 false c -4294967081 pg_replication_origin_status 591606261 2310524507 -1 false c -4294967082 pg_range 591606261 2310524507 -1 false c -4294967083 pg_publication_tables 591606261 2310524507 -1 false c -4294967084 pg_publication 591606261 2310524507 -1 false c -4294967085 pg_publication_rel 591606261 2310524507 -1 false c -4294967086 pg_proc 591606261 2310524507 -1 false c -4294967087 pg_prepared_xacts 591606261 2310524507 -1 false c -4294967088 pg_prepared_statements 591606261 2310524507 -1 false c -4294967089 pg_policy 591606261 2310524507 -1 false c -4294967090 pg_policies 591606261 2310524507 -1 false c -4294967091 pg_partitioned_table 591606261 2310524507 -1 false c -4294967092 pg_opfamily 591606261 2310524507 -1 false c -4294967093 pg_operator 591606261 2310524507 -1 false c -4294967094 pg_opclass 591606261 2310524507 -1 false c -4294967095 pg_namespace 591606261 2310524507 -1 false c -4294967096 pg_matviews 591606261 2310524507 -1 false c -4294967097 pg_locks 591606261 2310524507 -1 false c -4294967098 pg_largeobject 591606261 2310524507 -1 false c -4294967099 pg_largeobject_metadata 591606261 2310524507 -1 false c -4294967100 pg_language 591606261 2310524507 -1 false c -4294967101 pg_init_privs 591606261 2310524507 -1 false c -4294967102 pg_inherits 591606261 2310524507 -1 false c -4294967103 pg_indexes 591606261 2310524507 -1 false c -4294967104 pg_index 591606261 2310524507 -1 false c -4294967105 pg_hba_file_rules 591606261 2310524507 -1 false c -4294967106 pg_group 591606261 2310524507 -1 false c -4294967107 pg_foreign_table 591606261 2310524507 -1 false c -4294967108 pg_foreign_server 591606261 2310524507 -1 false c -4294967109 pg_foreign_data_wrapper 591606261 2310524507 -1 false c -4294967110 pg_file_settings 591606261 2310524507 -1 false c -4294967111 pg_extension 591606261 2310524507 -1 false c -4294967112 pg_event_trigger 591606261 2310524507 -1 false c -4294967113 pg_enum 591606261 2310524507 -1 false c -4294967114 pg_description 591606261 2310524507 -1 false c -4294967115 pg_depend 591606261 2310524507 -1 false c -4294967116 pg_default_acl 591606261 2310524507 -1 false c -4294967117 pg_db_role_setting 591606261 2310524507 -1 false c -4294967118 pg_database 591606261 2310524507 -1 false c -4294967119 pg_cursors 591606261 2310524507 -1 false c -4294967120 pg_conversion 591606261 2310524507 -1 false c -4294967121 pg_constraint 591606261 2310524507 -1 false c -4294967122 pg_config 591606261 2310524507 -1 false c -4294967123 pg_collation 591606261 2310524507 -1 false c -4294967124 pg_class 591606261 2310524507 -1 false c -4294967125 pg_cast 591606261 2310524507 -1 false c -4294967126 pg_available_extensions 591606261 2310524507 -1 false c -4294967127 pg_available_extension_versions 591606261 2310524507 -1 false c -4294967128 pg_auth_members 591606261 2310524507 -1 false c -4294967129 pg_authid 591606261 2310524507 -1 false c -4294967130 pg_attribute 591606261 2310524507 -1 false c -4294967131 pg_attrdef 591606261 2310524507 -1 false c -4294967132 pg_amproc 591606261 2310524507 -1 false c -4294967133 pg_amop 591606261 2310524507 -1 false c -4294967134 pg_am 591606261 2310524507 -1 false c -4294967135 pg_aggregate 591606261 2310524507 -1 false c -4294967137 views 198834802 2310524507 -1 false c -4294967138 view_table_usage 198834802 2310524507 -1 false c -4294967139 view_routine_usage 198834802 2310524507 -1 false c -4294967140 view_column_usage 198834802 2310524507 -1 false c -4294967141 user_privileges 198834802 2310524507 -1 false c -4294967142 user_mappings 198834802 2310524507 -1 false c -4294967143 user_mapping_options 198834802 2310524507 -1 false c -4294967144 user_defined_types 198834802 2310524507 -1 false c -4294967145 user_attributes 198834802 2310524507 -1 false c -4294967146 usage_privileges 198834802 2310524507 -1 false c -4294967147 udt_privileges 198834802 2310524507 -1 false c -4294967148 type_privileges 198834802 2310524507 -1 false c -4294967149 triggers 198834802 2310524507 -1 false c -4294967150 triggered_update_columns 198834802 2310524507 -1 false c -4294967151 transforms 198834802 2310524507 -1 false c -4294967152 tablespaces 198834802 2310524507 -1 false c -4294967153 tablespaces_extensions 198834802 2310524507 -1 false c -4294967154 tables 198834802 2310524507 -1 false c -4294967155 tables_extensions 198834802 2310524507 -1 false c -4294967156 table_privileges 198834802 2310524507 -1 false c -4294967157 table_constraints_extensions 198834802 2310524507 -1 false c -4294967158 table_constraints 198834802 2310524507 -1 false c -4294967159 statistics 198834802 2310524507 -1 false c -4294967160 st_units_of_measure 198834802 2310524507 -1 false c -4294967161 st_spatial_reference_systems 198834802 2310524507 -1 false c -4294967162 st_geometry_columns 198834802 2310524507 -1 false c -4294967163 session_variables 198834802 2310524507 -1 false c -4294967164 sequences 198834802 2310524507 -1 false c -4294967165 schema_privileges 198834802 2310524507 -1 false c -4294967166 schemata 198834802 2310524507 -1 false c -4294967167 schemata_extensions 198834802 2310524507 -1 false c -4294967168 sql_sizing 198834802 2310524507 -1 false c -4294967169 sql_parts 198834802 2310524507 -1 false c -4294967170 sql_implementation_info 198834802 2310524507 -1 false c -4294967171 sql_features 198834802 2310524507 -1 false c -4294967172 routines 198834802 2310524507 -1 false c -4294967173 routine_privileges 198834802 2310524507 -1 false c -4294967174 role_usage_grants 198834802 2310524507 -1 false c -4294967175 role_udt_grants 198834802 2310524507 -1 false c -4294967176 role_table_grants 198834802 2310524507 -1 false c -4294967177 role_routine_grants 198834802 2310524507 -1 false c -4294967178 role_column_grants 198834802 2310524507 -1 false c -4294967179 resource_groups 198834802 2310524507 -1 false c -4294967180 referential_constraints 198834802 2310524507 -1 false c -4294967181 profiling 198834802 2310524507 -1 false c -4294967182 processlist 198834802 2310524507 -1 false c -4294967183 plugins 198834802 2310524507 -1 false c -4294967184 partitions 198834802 2310524507 -1 false c -4294967185 parameters 198834802 2310524507 -1 false c -4294967186 optimizer_trace 198834802 2310524507 -1 false c -4294967187 keywords 198834802 2310524507 -1 false c -4294967188 key_column_usage 198834802 2310524507 -1 false c -4294967189 information_schema_catalog_name 198834802 2310524507 -1 false c -4294967190 foreign_tables 198834802 2310524507 -1 false c -4294967191 foreign_table_options 198834802 2310524507 -1 false c -4294967192 foreign_servers 198834802 2310524507 -1 false c -4294967193 foreign_server_options 198834802 2310524507 -1 false c -4294967194 foreign_data_wrappers 198834802 2310524507 -1 false c -4294967195 foreign_data_wrapper_options 198834802 2310524507 -1 false c -4294967196 files 198834802 2310524507 -1 false c -4294967197 events 198834802 2310524507 -1 false c -4294967198 engines 198834802 2310524507 -1 false c -4294967199 enabled_roles 198834802 2310524507 -1 false c -4294967200 element_types 198834802 2310524507 -1 false c -4294967201 domains 198834802 2310524507 -1 false c -4294967202 domain_udt_usage 198834802 2310524507 -1 false c -4294967203 domain_constraints 198834802 2310524507 -1 false c -4294967204 data_type_privileges 198834802 2310524507 -1 false c -4294967205 constraint_table_usage 198834802 2310524507 -1 false c -4294967206 constraint_column_usage 198834802 2310524507 -1 false c -4294967207 columns 198834802 2310524507 -1 false c -4294967208 columns_extensions 198834802 2310524507 -1 false c -4294967209 column_udt_usage 198834802 2310524507 -1 false c -4294967210 column_statistics 198834802 2310524507 -1 false c -4294967211 column_privileges 198834802 2310524507 -1 false c -4294967212 column_options 198834802 2310524507 -1 false c -4294967213 column_domain_usage 198834802 2310524507 -1 false c -4294967214 column_column_usage 198834802 2310524507 -1 false c -4294967215 collations 198834802 2310524507 -1 false c -4294967216 collation_character_set_applicability 198834802 2310524507 -1 false c -4294967217 check_constraints 198834802 2310524507 -1 false c -4294967218 check_constraint_routine_usage 198834802 2310524507 -1 false c -4294967219 character_sets 198834802 2310524507 -1 false c -4294967220 attributes 198834802 2310524507 -1 false c -4294967221 applicable_roles 198834802 2310524507 -1 false c -4294967222 administrable_role_authorizations 198834802 2310524507 -1 false c -4294967224 super_regions 194902141 2310524507 -1 false c -4294967225 pg_catalog_table_is_implemented 194902141 2310524507 -1 false c -4294967226 tenant_usage_details 194902141 2310524507 -1 false c -4294967227 active_range_feeds 194902141 2310524507 -1 false c -4294967228 default_privileges 194902141 2310524507 -1 false c -4294967229 regions 194902141 2310524507 -1 false c -4294967230 cluster_inflight_traces 194902141 2310524507 -1 false c -4294967231 lost_descriptors_with_data 194902141 2310524507 -1 false c -4294967232 cross_db_references 194902141 2310524507 -1 false c -4294967233 cluster_database_privileges 194902141 2310524507 -1 false c -4294967234 invalid_objects 194902141 2310524507 -1 false c -4294967235 zones 194902141 2310524507 -1 false c -4294967236 transaction_statistics 194902141 2310524507 -1 false c -4294967237 node_transaction_statistics 194902141 2310524507 -1 false c -4294967238 table_row_statistics 194902141 2310524507 -1 false c -4294967239 tables 194902141 2310524507 -1 false c -4294967240 table_indexes 194902141 2310524507 -1 false c -4294967241 table_columns 194902141 2310524507 -1 false c -4294967242 statement_statistics 194902141 2310524507 -1 false c -4294967243 session_variables 194902141 2310524507 -1 false c -4294967244 session_trace 194902141 2310524507 -1 false c -4294967245 schema_changes 194902141 2310524507 -1 false c -4294967246 node_runtime_info 194902141 2310524507 -1 false c -4294967247 ranges 194902141 2310524507 -1 false c -4294967248 ranges_no_leases 194902141 2310524507 -1 false c -4294967249 predefined_comments 194902141 2310524507 -1 false c -4294967250 partitions 194902141 2310524507 -1 false c -4294967251 node_txn_stats 194902141 2310524507 -1 false c -4294967252 node_statement_statistics 194902141 2310524507 -1 false c -4294967253 node_metrics 194902141 2310524507 -1 false c -4294967254 node_sessions 194902141 2310524507 -1 false c -4294967255 node_transactions 194902141 2310524507 -1 false c -4294967256 node_queries 194902141 2310524507 -1 false c -4294967257 node_execution_insights 194902141 2310524507 -1 false c -4294967258 node_distsql_flows 194902141 2310524507 -1 false c -4294967259 node_contention_events 194902141 2310524507 -1 false c -4294967260 leases 194902141 2310524507 -1 false c -4294967261 kv_store_status 194902141 2310524507 -1 false c -4294967262 kv_node_status 194902141 2310524507 -1 false c -4294967263 jobs 194902141 2310524507 -1 false c -4294967264 node_inflight_trace_spans 194902141 2310524507 -1 false c -4294967265 index_usage_statistics 194902141 2310524507 -1 false c -4294967266 index_columns 194902141 2310524507 -1 false c -4294967267 transaction_contention_events 194902141 2310524507 -1 false c -4294967268 gossip_network 194902141 2310524507 -1 false c -4294967269 gossip_liveness 194902141 2310524507 -1 false c -4294967270 gossip_alerts 194902141 2310524507 -1 false c -4294967271 gossip_nodes 194902141 2310524507 -1 false c -4294967272 kv_node_liveness 194902141 2310524507 -1 false c -4294967273 forward_dependencies 194902141 2310524507 -1 false c -4294967274 feature_usage 194902141 2310524507 -1 false c -4294967275 databases 194902141 2310524507 -1 false c -4294967276 create_type_statements 194902141 2310524507 -1 false c -4294967277 create_statements 194902141 2310524507 -1 false c -4294967278 create_schema_statements 194902141 2310524507 -1 false c -4294967279 create_function_statements 194902141 2310524507 -1 false c -4294967280 cluster_transaction_statistics 194902141 2310524507 -1 false c -4294967281 cluster_statement_statistics 194902141 2310524507 -1 false c -4294967282 cluster_settings 194902141 2310524507 -1 false c -4294967283 cluster_sessions 194902141 2310524507 -1 false c -4294967284 cluster_transactions 194902141 2310524507 -1 false c -4294967285 cluster_queries 194902141 2310524507 -1 false c -4294967286 cluster_locks 194902141 2310524507 -1 false c +4294967002 spatial_ref_sys 1700435119 2310524507 -1 false c +4294967003 geometry_columns 1700435119 2310524507 -1 false c +4294967004 geography_columns 1700435119 2310524507 -1 false c +4294967006 pg_views 591606261 2310524507 -1 false c +4294967007 pg_user 591606261 2310524507 -1 false c +4294967008 pg_user_mappings 591606261 2310524507 -1 false c +4294967009 pg_user_mapping 591606261 2310524507 -1 false c +4294967010 pg_type 591606261 2310524507 -1 false c +4294967011 pg_ts_template 591606261 2310524507 -1 false c +4294967012 pg_ts_parser 591606261 2310524507 -1 false c +4294967013 pg_ts_dict 591606261 2310524507 -1 false c +4294967014 pg_ts_config 591606261 2310524507 -1 false c +4294967015 pg_ts_config_map 591606261 2310524507 -1 false c +4294967016 pg_trigger 591606261 2310524507 -1 false c +4294967017 pg_transform 591606261 2310524507 -1 false c +4294967018 pg_timezone_names 591606261 2310524507 -1 false c +4294967019 pg_timezone_abbrevs 591606261 2310524507 -1 false c +4294967020 pg_tablespace 591606261 2310524507 -1 false c +4294967021 pg_tables 591606261 2310524507 -1 false c +4294967022 pg_subscription 591606261 2310524507 -1 false c +4294967023 pg_subscription_rel 591606261 2310524507 -1 false c +4294967024 pg_stats 591606261 2310524507 -1 false c +4294967025 pg_stats_ext 591606261 2310524507 -1 false c +4294967026 pg_statistic 591606261 2310524507 -1 false c +4294967027 pg_statistic_ext 591606261 2310524507 -1 false c +4294967028 pg_statistic_ext_data 591606261 2310524507 -1 false c +4294967029 pg_statio_user_tables 591606261 2310524507 -1 false c +4294967030 pg_statio_user_sequences 591606261 2310524507 -1 false c +4294967031 pg_statio_user_indexes 591606261 2310524507 -1 false c +4294967032 pg_statio_sys_tables 591606261 2310524507 -1 false c +4294967033 pg_statio_sys_sequences 591606261 2310524507 -1 false c +4294967034 pg_statio_sys_indexes 591606261 2310524507 -1 false c +4294967035 pg_statio_all_tables 591606261 2310524507 -1 false c +4294967036 pg_statio_all_sequences 591606261 2310524507 -1 false c +4294967037 pg_statio_all_indexes 591606261 2310524507 -1 false c +4294967038 pg_stat_xact_user_tables 591606261 2310524507 -1 false c +4294967039 pg_stat_xact_user_functions 591606261 2310524507 -1 false c +4294967040 pg_stat_xact_sys_tables 591606261 2310524507 -1 false c +4294967041 pg_stat_xact_all_tables 591606261 2310524507 -1 false c +4294967042 pg_stat_wal_receiver 591606261 2310524507 -1 false c +4294967043 pg_stat_user_tables 591606261 2310524507 -1 false c +4294967044 pg_stat_user_indexes 591606261 2310524507 -1 false c +4294967045 pg_stat_user_functions 591606261 2310524507 -1 false c +4294967046 pg_stat_sys_tables 591606261 2310524507 -1 false c +4294967047 pg_stat_sys_indexes 591606261 2310524507 -1 false c +4294967048 pg_stat_subscription 591606261 2310524507 -1 false c +4294967049 pg_stat_ssl 591606261 2310524507 -1 false c +4294967050 pg_stat_slru 591606261 2310524507 -1 false c +4294967051 pg_stat_replication 591606261 2310524507 -1 false c +4294967052 pg_stat_progress_vacuum 591606261 2310524507 -1 false c +4294967053 pg_stat_progress_create_index 591606261 2310524507 -1 false c +4294967054 pg_stat_progress_cluster 591606261 2310524507 -1 false c +4294967055 pg_stat_progress_basebackup 591606261 2310524507 -1 false c +4294967056 pg_stat_progress_analyze 591606261 2310524507 -1 false c +4294967057 pg_stat_gssapi 591606261 2310524507 -1 false c +4294967058 pg_stat_database 591606261 2310524507 -1 false c +4294967059 pg_stat_database_conflicts 591606261 2310524507 -1 false c +4294967060 pg_stat_bgwriter 591606261 2310524507 -1 false c +4294967061 pg_stat_archiver 591606261 2310524507 -1 false c +4294967062 pg_stat_all_tables 591606261 2310524507 -1 false c +4294967063 pg_stat_all_indexes 591606261 2310524507 -1 false c +4294967064 pg_stat_activity 591606261 2310524507 -1 false c +4294967065 pg_shmem_allocations 591606261 2310524507 -1 false c +4294967066 pg_shdepend 591606261 2310524507 -1 false c +4294967067 pg_shseclabel 591606261 2310524507 -1 false c +4294967068 pg_shdescription 591606261 2310524507 -1 false c +4294967069 pg_shadow 591606261 2310524507 -1 false c +4294967070 pg_settings 591606261 2310524507 -1 false c +4294967071 pg_sequences 591606261 2310524507 -1 false c +4294967072 pg_sequence 591606261 2310524507 -1 false c +4294967073 pg_seclabel 591606261 2310524507 -1 false c +4294967074 pg_seclabels 591606261 2310524507 -1 false c +4294967075 pg_rules 591606261 2310524507 -1 false c +4294967076 pg_roles 591606261 2310524507 -1 false c +4294967077 pg_rewrite 591606261 2310524507 -1 false c +4294967078 pg_replication_slots 591606261 2310524507 -1 false c +4294967079 pg_replication_origin 591606261 2310524507 -1 false c +4294967080 pg_replication_origin_status 591606261 2310524507 -1 false c +4294967081 pg_range 591606261 2310524507 -1 false c +4294967082 pg_publication_tables 591606261 2310524507 -1 false c +4294967083 pg_publication 591606261 2310524507 -1 false c +4294967084 pg_publication_rel 591606261 2310524507 -1 false c +4294967085 pg_proc 591606261 2310524507 -1 false c +4294967086 pg_prepared_xacts 591606261 2310524507 -1 false c +4294967087 pg_prepared_statements 591606261 2310524507 -1 false c +4294967088 pg_policy 591606261 2310524507 -1 false c +4294967089 pg_policies 591606261 2310524507 -1 false c +4294967090 pg_partitioned_table 591606261 2310524507 -1 false c +4294967091 pg_opfamily 591606261 2310524507 -1 false c +4294967092 pg_operator 591606261 2310524507 -1 false c +4294967093 pg_opclass 591606261 2310524507 -1 false c +4294967094 pg_namespace 591606261 2310524507 -1 false c +4294967095 pg_matviews 591606261 2310524507 -1 false c +4294967096 pg_locks 591606261 2310524507 -1 false c +4294967097 pg_largeobject 591606261 2310524507 -1 false c +4294967098 pg_largeobject_metadata 591606261 2310524507 -1 false c +4294967099 pg_language 591606261 2310524507 -1 false c +4294967100 pg_init_privs 591606261 2310524507 -1 false c +4294967101 pg_inherits 591606261 2310524507 -1 false c +4294967102 pg_indexes 591606261 2310524507 -1 false c +4294967103 pg_index 591606261 2310524507 -1 false c +4294967104 pg_hba_file_rules 591606261 2310524507 -1 false c +4294967105 pg_group 591606261 2310524507 -1 false c +4294967106 pg_foreign_table 591606261 2310524507 -1 false c +4294967107 pg_foreign_server 591606261 2310524507 -1 false c +4294967108 pg_foreign_data_wrapper 591606261 2310524507 -1 false c +4294967109 pg_file_settings 591606261 2310524507 -1 false c +4294967110 pg_extension 591606261 2310524507 -1 false c +4294967111 pg_event_trigger 591606261 2310524507 -1 false c +4294967112 pg_enum 591606261 2310524507 -1 false c +4294967113 pg_description 591606261 2310524507 -1 false c +4294967114 pg_depend 591606261 2310524507 -1 false c +4294967115 pg_default_acl 591606261 2310524507 -1 false c +4294967116 pg_db_role_setting 591606261 2310524507 -1 false c +4294967117 pg_database 591606261 2310524507 -1 false c +4294967118 pg_cursors 591606261 2310524507 -1 false c +4294967119 pg_conversion 591606261 2310524507 -1 false c +4294967120 pg_constraint 591606261 2310524507 -1 false c +4294967121 pg_config 591606261 2310524507 -1 false c +4294967122 pg_collation 591606261 2310524507 -1 false c +4294967123 pg_class 591606261 2310524507 -1 false c +4294967124 pg_cast 591606261 2310524507 -1 false c +4294967125 pg_available_extensions 591606261 2310524507 -1 false c +4294967126 pg_available_extension_versions 591606261 2310524507 -1 false c +4294967127 pg_auth_members 591606261 2310524507 -1 false c +4294967128 pg_authid 591606261 2310524507 -1 false c +4294967129 pg_attribute 591606261 2310524507 -1 false c +4294967130 pg_attrdef 591606261 2310524507 -1 false c +4294967131 pg_amproc 591606261 2310524507 -1 false c +4294967132 pg_amop 591606261 2310524507 -1 false c +4294967133 pg_am 591606261 2310524507 -1 false c +4294967134 pg_aggregate 591606261 2310524507 -1 false c +4294967136 views 198834802 2310524507 -1 false c +4294967137 view_table_usage 198834802 2310524507 -1 false c +4294967138 view_routine_usage 198834802 2310524507 -1 false c +4294967139 view_column_usage 198834802 2310524507 -1 false c +4294967140 user_privileges 198834802 2310524507 -1 false c +4294967141 user_mappings 198834802 2310524507 -1 false c +4294967142 user_mapping_options 198834802 2310524507 -1 false c +4294967143 user_defined_types 198834802 2310524507 -1 false c +4294967144 user_attributes 198834802 2310524507 -1 false c +4294967145 usage_privileges 198834802 2310524507 -1 false c +4294967146 udt_privileges 198834802 2310524507 -1 false c +4294967147 type_privileges 198834802 2310524507 -1 false c +4294967148 triggers 198834802 2310524507 -1 false c +4294967149 triggered_update_columns 198834802 2310524507 -1 false c +4294967150 transforms 198834802 2310524507 -1 false c +4294967151 tablespaces 198834802 2310524507 -1 false c +4294967152 tablespaces_extensions 198834802 2310524507 -1 false c +4294967153 tables 198834802 2310524507 -1 false c +4294967154 tables_extensions 198834802 2310524507 -1 false c +4294967155 table_privileges 198834802 2310524507 -1 false c +4294967156 table_constraints_extensions 198834802 2310524507 -1 false c +4294967157 table_constraints 198834802 2310524507 -1 false c +4294967158 statistics 198834802 2310524507 -1 false c +4294967159 st_units_of_measure 198834802 2310524507 -1 false c +4294967160 st_spatial_reference_systems 198834802 2310524507 -1 false c +4294967161 st_geometry_columns 198834802 2310524507 -1 false c +4294967162 session_variables 198834802 2310524507 -1 false c +4294967163 sequences 198834802 2310524507 -1 false c +4294967164 schema_privileges 198834802 2310524507 -1 false c +4294967165 schemata 198834802 2310524507 -1 false c +4294967166 schemata_extensions 198834802 2310524507 -1 false c +4294967167 sql_sizing 198834802 2310524507 -1 false c +4294967168 sql_parts 198834802 2310524507 -1 false c +4294967169 sql_implementation_info 198834802 2310524507 -1 false c +4294967170 sql_features 198834802 2310524507 -1 false c +4294967171 routines 198834802 2310524507 -1 false c +4294967172 routine_privileges 198834802 2310524507 -1 false c +4294967173 role_usage_grants 198834802 2310524507 -1 false c +4294967174 role_udt_grants 198834802 2310524507 -1 false c +4294967175 role_table_grants 198834802 2310524507 -1 false c +4294967176 role_routine_grants 198834802 2310524507 -1 false c +4294967177 role_column_grants 198834802 2310524507 -1 false c +4294967178 resource_groups 198834802 2310524507 -1 false c +4294967179 referential_constraints 198834802 2310524507 -1 false c +4294967180 profiling 198834802 2310524507 -1 false c +4294967181 processlist 198834802 2310524507 -1 false c +4294967182 plugins 198834802 2310524507 -1 false c +4294967183 partitions 198834802 2310524507 -1 false c +4294967184 parameters 198834802 2310524507 -1 false c +4294967185 optimizer_trace 198834802 2310524507 -1 false c +4294967186 keywords 198834802 2310524507 -1 false c +4294967187 key_column_usage 198834802 2310524507 -1 false c +4294967188 information_schema_catalog_name 198834802 2310524507 -1 false c +4294967189 foreign_tables 198834802 2310524507 -1 false c +4294967190 foreign_table_options 198834802 2310524507 -1 false c +4294967191 foreign_servers 198834802 2310524507 -1 false c +4294967192 foreign_server_options 198834802 2310524507 -1 false c +4294967193 foreign_data_wrappers 198834802 2310524507 -1 false c +4294967194 foreign_data_wrapper_options 198834802 2310524507 -1 false c +4294967195 files 198834802 2310524507 -1 false c +4294967196 events 198834802 2310524507 -1 false c +4294967197 engines 198834802 2310524507 -1 false c +4294967198 enabled_roles 198834802 2310524507 -1 false c +4294967199 element_types 198834802 2310524507 -1 false c +4294967200 domains 198834802 2310524507 -1 false c +4294967201 domain_udt_usage 198834802 2310524507 -1 false c +4294967202 domain_constraints 198834802 2310524507 -1 false c +4294967203 data_type_privileges 198834802 2310524507 -1 false c +4294967204 constraint_table_usage 198834802 2310524507 -1 false c +4294967205 constraint_column_usage 198834802 2310524507 -1 false c +4294967206 columns 198834802 2310524507 -1 false c +4294967207 columns_extensions 198834802 2310524507 -1 false c +4294967208 column_udt_usage 198834802 2310524507 -1 false c +4294967209 column_statistics 198834802 2310524507 -1 false c +4294967210 column_privileges 198834802 2310524507 -1 false c +4294967211 column_options 198834802 2310524507 -1 false c +4294967212 column_domain_usage 198834802 2310524507 -1 false c +4294967213 column_column_usage 198834802 2310524507 -1 false c +4294967214 collations 198834802 2310524507 -1 false c +4294967215 collation_character_set_applicability 198834802 2310524507 -1 false c +4294967216 check_constraints 198834802 2310524507 -1 false c +4294967217 check_constraint_routine_usage 198834802 2310524507 -1 false c +4294967218 character_sets 198834802 2310524507 -1 false c +4294967219 attributes 198834802 2310524507 -1 false c +4294967220 applicable_roles 198834802 2310524507 -1 false c +4294967221 administrable_role_authorizations 198834802 2310524507 -1 false c +4294967223 super_regions 194902141 2310524507 -1 false c +4294967224 pg_catalog_table_is_implemented 194902141 2310524507 -1 false c +4294967225 tenant_usage_details 194902141 2310524507 -1 false c +4294967226 active_range_feeds 194902141 2310524507 -1 false c +4294967227 default_privileges 194902141 2310524507 -1 false c +4294967228 regions 194902141 2310524507 -1 false c +4294967229 cluster_inflight_traces 194902141 2310524507 -1 false c +4294967230 lost_descriptors_with_data 194902141 2310524507 -1 false c +4294967231 cross_db_references 194902141 2310524507 -1 false c +4294967232 cluster_database_privileges 194902141 2310524507 -1 false c +4294967233 invalid_objects 194902141 2310524507 -1 false c +4294967234 zones 194902141 2310524507 -1 false c +4294967235 transaction_statistics 194902141 2310524507 -1 false c +4294967236 node_transaction_statistics 194902141 2310524507 -1 false c +4294967237 table_row_statistics 194902141 2310524507 -1 false c +4294967238 tables 194902141 2310524507 -1 false c +4294967239 table_indexes 194902141 2310524507 -1 false c +4294967240 table_columns 194902141 2310524507 -1 false c +4294967241 statement_statistics 194902141 2310524507 -1 false c +4294967242 session_variables 194902141 2310524507 -1 false c +4294967243 session_trace 194902141 2310524507 -1 false c +4294967244 schema_changes 194902141 2310524507 -1 false c +4294967245 node_runtime_info 194902141 2310524507 -1 false c +4294967246 ranges 194902141 2310524507 -1 false c +4294967247 ranges_no_leases 194902141 2310524507 -1 false c +4294967248 predefined_comments 194902141 2310524507 -1 false c +4294967249 partitions 194902141 2310524507 -1 false c +4294967250 node_txn_stats 194902141 2310524507 -1 false c +4294967251 node_statement_statistics 194902141 2310524507 -1 false c +4294967252 node_metrics 194902141 2310524507 -1 false c +4294967253 node_sessions 194902141 2310524507 -1 false c +4294967254 node_transactions 194902141 2310524507 -1 false c +4294967255 node_queries 194902141 2310524507 -1 false c +4294967256 node_execution_insights 194902141 2310524507 -1 false c +4294967257 node_distsql_flows 194902141 2310524507 -1 false c +4294967258 node_contention_events 194902141 2310524507 -1 false c +4294967259 leases 194902141 2310524507 -1 false c +4294967260 kv_store_status 194902141 2310524507 -1 false c +4294967261 kv_node_status 194902141 2310524507 -1 false c +4294967262 jobs 194902141 2310524507 -1 false c +4294967263 node_inflight_trace_spans 194902141 2310524507 -1 false c +4294967264 index_usage_statistics 194902141 2310524507 -1 false c +4294967265 index_columns 194902141 2310524507 -1 false c +4294967266 transaction_contention_events 194902141 2310524507 -1 false c +4294967267 gossip_network 194902141 2310524507 -1 false c +4294967268 gossip_liveness 194902141 2310524507 -1 false c +4294967269 gossip_alerts 194902141 2310524507 -1 false c +4294967270 gossip_nodes 194902141 2310524507 -1 false c +4294967271 kv_node_liveness 194902141 2310524507 -1 false c +4294967272 forward_dependencies 194902141 2310524507 -1 false c +4294967273 feature_usage 194902141 2310524507 -1 false c +4294967274 databases 194902141 2310524507 -1 false c +4294967275 create_type_statements 194902141 2310524507 -1 false c +4294967276 create_statements 194902141 2310524507 -1 false c +4294967277 create_schema_statements 194902141 2310524507 -1 false c +4294967278 create_function_statements 194902141 2310524507 -1 false c +4294967279 cluster_transaction_statistics 194902141 2310524507 -1 false c +4294967280 cluster_statement_statistics 194902141 2310524507 -1 false c +4294967281 cluster_settings 194902141 2310524507 -1 false c +4294967282 cluster_sessions 194902141 2310524507 -1 false c +4294967283 cluster_transactions 194902141 2310524507 -1 false c +4294967284 cluster_queries 194902141 2310524507 -1 false c +4294967285 cluster_locks 194902141 2310524507 -1 false c +4294967286 cluster_execution_insights 194902141 2310524507 -1 false c 4294967287 cluster_distsql_flows 194902141 2310524507 -1 false c 4294967288 cluster_contention_events 194902141 2310524507 -1 false c 4294967289 cluster_contended_tables 194902141 2310524507 -1 false c @@ -2090,287 +2091,288 @@ oid typname typcategory typispreferred 100132 _newtype1 A false true , 0 100131 0 100133 newtype2 E false true , 0 0 100134 100134 _newtype2 A false true , 0 100133 0 -4294967003 spatial_ref_sys C false true , 4294967003 0 0 -4294967004 geometry_columns C false true , 4294967004 0 0 -4294967005 geography_columns C false true , 4294967005 0 0 -4294967007 pg_views C false true , 4294967007 0 0 -4294967008 pg_user C false true , 4294967008 0 0 -4294967009 pg_user_mappings C false true , 4294967009 0 0 -4294967010 pg_user_mapping C false true , 4294967010 0 0 -4294967011 pg_type C false true , 4294967011 0 0 -4294967012 pg_ts_template C false true , 4294967012 0 0 -4294967013 pg_ts_parser C false true , 4294967013 0 0 -4294967014 pg_ts_dict C false true , 4294967014 0 0 -4294967015 pg_ts_config C false true , 4294967015 0 0 -4294967016 pg_ts_config_map C false true , 4294967016 0 0 -4294967017 pg_trigger C false true , 4294967017 0 0 -4294967018 pg_transform C false true , 4294967018 0 0 -4294967019 pg_timezone_names C false true , 4294967019 0 0 -4294967020 pg_timezone_abbrevs C false true , 4294967020 0 0 -4294967021 pg_tablespace C false true , 4294967021 0 0 -4294967022 pg_tables C false true , 4294967022 0 0 -4294967023 pg_subscription C false true , 4294967023 0 0 -4294967024 pg_subscription_rel C false true , 4294967024 0 0 -4294967025 pg_stats C false true , 4294967025 0 0 -4294967026 pg_stats_ext C false true , 4294967026 0 0 -4294967027 pg_statistic C false true , 4294967027 0 0 -4294967028 pg_statistic_ext C false true , 4294967028 0 0 -4294967029 pg_statistic_ext_data C false true , 4294967029 0 0 -4294967030 pg_statio_user_tables C false true , 4294967030 0 0 -4294967031 pg_statio_user_sequences C false true , 4294967031 0 0 -4294967032 pg_statio_user_indexes C false true , 4294967032 0 0 -4294967033 pg_statio_sys_tables C false true , 4294967033 0 0 -4294967034 pg_statio_sys_sequences C false true , 4294967034 0 0 -4294967035 pg_statio_sys_indexes C false true , 4294967035 0 0 -4294967036 pg_statio_all_tables C false true , 4294967036 0 0 -4294967037 pg_statio_all_sequences C false true , 4294967037 0 0 -4294967038 pg_statio_all_indexes C false true , 4294967038 0 0 -4294967039 pg_stat_xact_user_tables C false true , 4294967039 0 0 -4294967040 pg_stat_xact_user_functions C false true , 4294967040 0 0 -4294967041 pg_stat_xact_sys_tables C false true , 4294967041 0 0 -4294967042 pg_stat_xact_all_tables C false true , 4294967042 0 0 -4294967043 pg_stat_wal_receiver C false true , 4294967043 0 0 -4294967044 pg_stat_user_tables C false true , 4294967044 0 0 -4294967045 pg_stat_user_indexes C false true , 4294967045 0 0 -4294967046 pg_stat_user_functions C false true , 4294967046 0 0 -4294967047 pg_stat_sys_tables C false true , 4294967047 0 0 -4294967048 pg_stat_sys_indexes C false true , 4294967048 0 0 -4294967049 pg_stat_subscription C false true , 4294967049 0 0 -4294967050 pg_stat_ssl C false true , 4294967050 0 0 -4294967051 pg_stat_slru C false true , 4294967051 0 0 -4294967052 pg_stat_replication C false true , 4294967052 0 0 -4294967053 pg_stat_progress_vacuum C false true , 4294967053 0 0 -4294967054 pg_stat_progress_create_index C false true , 4294967054 0 0 -4294967055 pg_stat_progress_cluster C false true , 4294967055 0 0 -4294967056 pg_stat_progress_basebackup C false true , 4294967056 0 0 -4294967057 pg_stat_progress_analyze C false true , 4294967057 0 0 -4294967058 pg_stat_gssapi C false true , 4294967058 0 0 -4294967059 pg_stat_database C false true , 4294967059 0 0 -4294967060 pg_stat_database_conflicts C false true , 4294967060 0 0 -4294967061 pg_stat_bgwriter C false true , 4294967061 0 0 -4294967062 pg_stat_archiver C false true , 4294967062 0 0 -4294967063 pg_stat_all_tables C false true , 4294967063 0 0 -4294967064 pg_stat_all_indexes C false true , 4294967064 0 0 -4294967065 pg_stat_activity C false true , 4294967065 0 0 -4294967066 pg_shmem_allocations C false true , 4294967066 0 0 -4294967067 pg_shdepend C false true , 4294967067 0 0 -4294967068 pg_shseclabel C false true , 4294967068 0 0 -4294967069 pg_shdescription C false true , 4294967069 0 0 -4294967070 pg_shadow C false true , 4294967070 0 0 -4294967071 pg_settings C false true , 4294967071 0 0 -4294967072 pg_sequences C false true , 4294967072 0 0 -4294967073 pg_sequence C false true , 4294967073 0 0 -4294967074 pg_seclabel C false true , 4294967074 0 0 -4294967075 pg_seclabels C false true , 4294967075 0 0 -4294967076 pg_rules C false true , 4294967076 0 0 -4294967077 pg_roles C false true , 4294967077 0 0 -4294967078 pg_rewrite C false true , 4294967078 0 0 -4294967079 pg_replication_slots C false true , 4294967079 0 0 -4294967080 pg_replication_origin C false true , 4294967080 0 0 -4294967081 pg_replication_origin_status C false true , 4294967081 0 0 -4294967082 pg_range C false true , 4294967082 0 0 -4294967083 pg_publication_tables C false true , 4294967083 0 0 -4294967084 pg_publication C false true , 4294967084 0 0 -4294967085 pg_publication_rel C false true , 4294967085 0 0 -4294967086 pg_proc C false true , 4294967086 0 0 -4294967087 pg_prepared_xacts C false true , 4294967087 0 0 -4294967088 pg_prepared_statements C false true , 4294967088 0 0 -4294967089 pg_policy C false true , 4294967089 0 0 -4294967090 pg_policies C false true , 4294967090 0 0 -4294967091 pg_partitioned_table C false true , 4294967091 0 0 -4294967092 pg_opfamily C false true , 4294967092 0 0 -4294967093 pg_operator C false true , 4294967093 0 0 -4294967094 pg_opclass C false true , 4294967094 0 0 -4294967095 pg_namespace C false true , 4294967095 0 0 -4294967096 pg_matviews C false true , 4294967096 0 0 -4294967097 pg_locks C false true , 4294967097 0 0 -4294967098 pg_largeobject C false true , 4294967098 0 0 -4294967099 pg_largeobject_metadata C false true , 4294967099 0 0 -4294967100 pg_language C false true , 4294967100 0 0 -4294967101 pg_init_privs C false true , 4294967101 0 0 -4294967102 pg_inherits C false true , 4294967102 0 0 -4294967103 pg_indexes C false true , 4294967103 0 0 -4294967104 pg_index C false true , 4294967104 0 0 -4294967105 pg_hba_file_rules C false true , 4294967105 0 0 -4294967106 pg_group C false true , 4294967106 0 0 -4294967107 pg_foreign_table C false true , 4294967107 0 0 -4294967108 pg_foreign_server C false true , 4294967108 0 0 -4294967109 pg_foreign_data_wrapper C false true , 4294967109 0 0 -4294967110 pg_file_settings C false true , 4294967110 0 0 -4294967111 pg_extension C false true , 4294967111 0 0 -4294967112 pg_event_trigger C false true , 4294967112 0 0 -4294967113 pg_enum C false true , 4294967113 0 0 -4294967114 pg_description C false true , 4294967114 0 0 -4294967115 pg_depend C false true , 4294967115 0 0 -4294967116 pg_default_acl C false true , 4294967116 0 0 -4294967117 pg_db_role_setting C false true , 4294967117 0 0 -4294967118 pg_database C false true , 4294967118 0 0 -4294967119 pg_cursors C false true , 4294967119 0 0 -4294967120 pg_conversion C false true , 4294967120 0 0 -4294967121 pg_constraint C false true , 4294967121 0 0 -4294967122 pg_config C false true , 4294967122 0 0 -4294967123 pg_collation C false true , 4294967123 0 0 -4294967124 pg_class C false true , 4294967124 0 0 -4294967125 pg_cast C false true , 4294967125 0 0 -4294967126 pg_available_extensions C false true , 4294967126 0 0 -4294967127 pg_available_extension_versions C false true , 4294967127 0 0 -4294967128 pg_auth_members C false true , 4294967128 0 0 -4294967129 pg_authid C false true , 4294967129 0 0 -4294967130 pg_attribute C false true , 4294967130 0 0 -4294967131 pg_attrdef C false true , 4294967131 0 0 -4294967132 pg_amproc C false true , 4294967132 0 0 -4294967133 pg_amop C false true , 4294967133 0 0 -4294967134 pg_am C false true , 4294967134 0 0 -4294967135 pg_aggregate C false true , 4294967135 0 0 -4294967137 views C false true , 4294967137 0 0 -4294967138 view_table_usage C false true , 4294967138 0 0 -4294967139 view_routine_usage C false true , 4294967139 0 0 -4294967140 view_column_usage C false true , 4294967140 0 0 -4294967141 user_privileges C false true , 4294967141 0 0 -4294967142 user_mappings C false true , 4294967142 0 0 -4294967143 user_mapping_options C false true , 4294967143 0 0 -4294967144 user_defined_types C false true , 4294967144 0 0 -4294967145 user_attributes C false true , 4294967145 0 0 -4294967146 usage_privileges C false true , 4294967146 0 0 -4294967147 udt_privileges C false true , 4294967147 0 0 -4294967148 type_privileges C false true , 4294967148 0 0 -4294967149 triggers C false true , 4294967149 0 0 -4294967150 triggered_update_columns C false true , 4294967150 0 0 -4294967151 transforms C false true , 4294967151 0 0 -4294967152 tablespaces C false true , 4294967152 0 0 -4294967153 tablespaces_extensions C false true , 4294967153 0 0 -4294967154 tables C false true , 4294967154 0 0 -4294967155 tables_extensions C false true , 4294967155 0 0 -4294967156 table_privileges C false true , 4294967156 0 0 -4294967157 table_constraints_extensions C false true , 4294967157 0 0 -4294967158 table_constraints C false true , 4294967158 0 0 -4294967159 statistics C false true , 4294967159 0 0 -4294967160 st_units_of_measure C false true , 4294967160 0 0 -4294967161 st_spatial_reference_systems C false true , 4294967161 0 0 -4294967162 st_geometry_columns C false true , 4294967162 0 0 -4294967163 session_variables C false true , 4294967163 0 0 -4294967164 sequences C false true , 4294967164 0 0 -4294967165 schema_privileges C false true , 4294967165 0 0 -4294967166 schemata C false true , 4294967166 0 0 -4294967167 schemata_extensions C false true , 4294967167 0 0 -4294967168 sql_sizing C false true , 4294967168 0 0 -4294967169 sql_parts C false true , 4294967169 0 0 -4294967170 sql_implementation_info C false true , 4294967170 0 0 -4294967171 sql_features C false true , 4294967171 0 0 -4294967172 routines C false true , 4294967172 0 0 -4294967173 routine_privileges C false true , 4294967173 0 0 -4294967174 role_usage_grants C false true , 4294967174 0 0 -4294967175 role_udt_grants C false true , 4294967175 0 0 -4294967176 role_table_grants C false true , 4294967176 0 0 -4294967177 role_routine_grants C false true , 4294967177 0 0 -4294967178 role_column_grants C false true , 4294967178 0 0 -4294967179 resource_groups C false true , 4294967179 0 0 -4294967180 referential_constraints C false true , 4294967180 0 0 -4294967181 profiling C false true , 4294967181 0 0 -4294967182 processlist C false true , 4294967182 0 0 -4294967183 plugins C false true , 4294967183 0 0 -4294967184 partitions C false true , 4294967184 0 0 -4294967185 parameters C false true , 4294967185 0 0 -4294967186 optimizer_trace C false true , 4294967186 0 0 -4294967187 keywords C false true , 4294967187 0 0 -4294967188 key_column_usage C false true , 4294967188 0 0 -4294967189 information_schema_catalog_name C false true , 4294967189 0 0 -4294967190 foreign_tables C false true , 4294967190 0 0 -4294967191 foreign_table_options C false true , 4294967191 0 0 -4294967192 foreign_servers C false true , 4294967192 0 0 -4294967193 foreign_server_options C false true , 4294967193 0 0 -4294967194 foreign_data_wrappers C false true , 4294967194 0 0 -4294967195 foreign_data_wrapper_options C false true , 4294967195 0 0 -4294967196 files C false true , 4294967196 0 0 -4294967197 events C false true , 4294967197 0 0 -4294967198 engines C false true , 4294967198 0 0 -4294967199 enabled_roles C false true , 4294967199 0 0 -4294967200 element_types C false true , 4294967200 0 0 -4294967201 domains C false true , 4294967201 0 0 -4294967202 domain_udt_usage C false true , 4294967202 0 0 -4294967203 domain_constraints C false true , 4294967203 0 0 -4294967204 data_type_privileges C false true , 4294967204 0 0 -4294967205 constraint_table_usage C false true , 4294967205 0 0 -4294967206 constraint_column_usage C false true , 4294967206 0 0 -4294967207 columns C false true , 4294967207 0 0 -4294967208 columns_extensions C false true , 4294967208 0 0 -4294967209 column_udt_usage C false true , 4294967209 0 0 -4294967210 column_statistics C false true , 4294967210 0 0 -4294967211 column_privileges C false true , 4294967211 0 0 -4294967212 column_options C false true , 4294967212 0 0 -4294967213 column_domain_usage C false true , 4294967213 0 0 -4294967214 column_column_usage C false true , 4294967214 0 0 -4294967215 collations C false true , 4294967215 0 0 -4294967216 collation_character_set_applicability C false true , 4294967216 0 0 -4294967217 check_constraints C false true , 4294967217 0 0 -4294967218 check_constraint_routine_usage C false true , 4294967218 0 0 -4294967219 character_sets C false true , 4294967219 0 0 -4294967220 attributes C false true , 4294967220 0 0 -4294967221 applicable_roles C false true , 4294967221 0 0 -4294967222 administrable_role_authorizations C false true , 4294967222 0 0 -4294967224 super_regions C false true , 4294967224 0 0 -4294967225 pg_catalog_table_is_implemented C false true , 4294967225 0 0 -4294967226 tenant_usage_details C false true , 4294967226 0 0 -4294967227 active_range_feeds C false true , 4294967227 0 0 -4294967228 default_privileges C false true , 4294967228 0 0 -4294967229 regions C false true , 4294967229 0 0 -4294967230 cluster_inflight_traces C false true , 4294967230 0 0 -4294967231 lost_descriptors_with_data C false true , 4294967231 0 0 -4294967232 cross_db_references C false true , 4294967232 0 0 -4294967233 cluster_database_privileges C false true , 4294967233 0 0 -4294967234 invalid_objects C false true , 4294967234 0 0 -4294967235 zones C false true , 4294967235 0 0 -4294967236 transaction_statistics C false true , 4294967236 0 0 -4294967237 node_transaction_statistics C false true , 4294967237 0 0 -4294967238 table_row_statistics C false true , 4294967238 0 0 -4294967239 tables C false true , 4294967239 0 0 -4294967240 table_indexes C false true , 4294967240 0 0 -4294967241 table_columns C false true , 4294967241 0 0 -4294967242 statement_statistics C false true , 4294967242 0 0 -4294967243 session_variables C false true , 4294967243 0 0 -4294967244 session_trace C false true , 4294967244 0 0 -4294967245 schema_changes C false true , 4294967245 0 0 -4294967246 node_runtime_info C false true , 4294967246 0 0 -4294967247 ranges C false true , 4294967247 0 0 -4294967248 ranges_no_leases C false true , 4294967248 0 0 -4294967249 predefined_comments C false true , 4294967249 0 0 -4294967250 partitions C false true , 4294967250 0 0 -4294967251 node_txn_stats C false true , 4294967251 0 0 -4294967252 node_statement_statistics C false true , 4294967252 0 0 -4294967253 node_metrics C false true , 4294967253 0 0 -4294967254 node_sessions C false true , 4294967254 0 0 -4294967255 node_transactions C false true , 4294967255 0 0 -4294967256 node_queries C false true , 4294967256 0 0 -4294967257 node_execution_insights C false true , 4294967257 0 0 -4294967258 node_distsql_flows C false true , 4294967258 0 0 -4294967259 node_contention_events C false true , 4294967259 0 0 -4294967260 leases C false true , 4294967260 0 0 -4294967261 kv_store_status C false true , 4294967261 0 0 -4294967262 kv_node_status C false true , 4294967262 0 0 -4294967263 jobs C false true , 4294967263 0 0 -4294967264 node_inflight_trace_spans C false true , 4294967264 0 0 -4294967265 index_usage_statistics C false true , 4294967265 0 0 -4294967266 index_columns C false true , 4294967266 0 0 -4294967267 transaction_contention_events C false true , 4294967267 0 0 -4294967268 gossip_network C false true , 4294967268 0 0 -4294967269 gossip_liveness C false true , 4294967269 0 0 -4294967270 gossip_alerts C false true , 4294967270 0 0 -4294967271 gossip_nodes C false true , 4294967271 0 0 -4294967272 kv_node_liveness C false true , 4294967272 0 0 -4294967273 forward_dependencies C false true , 4294967273 0 0 -4294967274 feature_usage C false true , 4294967274 0 0 -4294967275 databases C false true , 4294967275 0 0 -4294967276 create_type_statements C false true , 4294967276 0 0 -4294967277 create_statements C false true , 4294967277 0 0 -4294967278 create_schema_statements C false true , 4294967278 0 0 -4294967279 create_function_statements C false true , 4294967279 0 0 -4294967280 cluster_transaction_statistics C false true , 4294967280 0 0 -4294967281 cluster_statement_statistics C false true , 4294967281 0 0 -4294967282 cluster_settings C false true , 4294967282 0 0 -4294967283 cluster_sessions C false true , 4294967283 0 0 -4294967284 cluster_transactions C false true , 4294967284 0 0 -4294967285 cluster_queries C false true , 4294967285 0 0 -4294967286 cluster_locks C false true , 4294967286 0 0 +4294967002 spatial_ref_sys C false true , 4294967002 0 0 +4294967003 geometry_columns C false true , 4294967003 0 0 +4294967004 geography_columns C false true , 4294967004 0 0 +4294967006 pg_views C false true , 4294967006 0 0 +4294967007 pg_user C false true , 4294967007 0 0 +4294967008 pg_user_mappings C false true , 4294967008 0 0 +4294967009 pg_user_mapping C false true , 4294967009 0 0 +4294967010 pg_type C false true , 4294967010 0 0 +4294967011 pg_ts_template C false true , 4294967011 0 0 +4294967012 pg_ts_parser C false true , 4294967012 0 0 +4294967013 pg_ts_dict C false true , 4294967013 0 0 +4294967014 pg_ts_config C false true , 4294967014 0 0 +4294967015 pg_ts_config_map C false true , 4294967015 0 0 +4294967016 pg_trigger C false true , 4294967016 0 0 +4294967017 pg_transform C false true , 4294967017 0 0 +4294967018 pg_timezone_names C false true , 4294967018 0 0 +4294967019 pg_timezone_abbrevs C false true , 4294967019 0 0 +4294967020 pg_tablespace C false true , 4294967020 0 0 +4294967021 pg_tables C false true , 4294967021 0 0 +4294967022 pg_subscription C false true , 4294967022 0 0 +4294967023 pg_subscription_rel C false true , 4294967023 0 0 +4294967024 pg_stats C false true , 4294967024 0 0 +4294967025 pg_stats_ext C false true , 4294967025 0 0 +4294967026 pg_statistic C false true , 4294967026 0 0 +4294967027 pg_statistic_ext C false true , 4294967027 0 0 +4294967028 pg_statistic_ext_data C false true , 4294967028 0 0 +4294967029 pg_statio_user_tables C false true , 4294967029 0 0 +4294967030 pg_statio_user_sequences C false true , 4294967030 0 0 +4294967031 pg_statio_user_indexes C false true , 4294967031 0 0 +4294967032 pg_statio_sys_tables C false true , 4294967032 0 0 +4294967033 pg_statio_sys_sequences C false true , 4294967033 0 0 +4294967034 pg_statio_sys_indexes C false true , 4294967034 0 0 +4294967035 pg_statio_all_tables C false true , 4294967035 0 0 +4294967036 pg_statio_all_sequences C false true , 4294967036 0 0 +4294967037 pg_statio_all_indexes C false true , 4294967037 0 0 +4294967038 pg_stat_xact_user_tables C false true , 4294967038 0 0 +4294967039 pg_stat_xact_user_functions C false true , 4294967039 0 0 +4294967040 pg_stat_xact_sys_tables C false true , 4294967040 0 0 +4294967041 pg_stat_xact_all_tables C false true , 4294967041 0 0 +4294967042 pg_stat_wal_receiver C false true , 4294967042 0 0 +4294967043 pg_stat_user_tables C false true , 4294967043 0 0 +4294967044 pg_stat_user_indexes C false true , 4294967044 0 0 +4294967045 pg_stat_user_functions C false true , 4294967045 0 0 +4294967046 pg_stat_sys_tables C false true , 4294967046 0 0 +4294967047 pg_stat_sys_indexes C false true , 4294967047 0 0 +4294967048 pg_stat_subscription C false true , 4294967048 0 0 +4294967049 pg_stat_ssl C false true , 4294967049 0 0 +4294967050 pg_stat_slru C false true , 4294967050 0 0 +4294967051 pg_stat_replication C false true , 4294967051 0 0 +4294967052 pg_stat_progress_vacuum C false true , 4294967052 0 0 +4294967053 pg_stat_progress_create_index C false true , 4294967053 0 0 +4294967054 pg_stat_progress_cluster C false true , 4294967054 0 0 +4294967055 pg_stat_progress_basebackup C false true , 4294967055 0 0 +4294967056 pg_stat_progress_analyze C false true , 4294967056 0 0 +4294967057 pg_stat_gssapi C false true , 4294967057 0 0 +4294967058 pg_stat_database C false true , 4294967058 0 0 +4294967059 pg_stat_database_conflicts C false true , 4294967059 0 0 +4294967060 pg_stat_bgwriter C false true , 4294967060 0 0 +4294967061 pg_stat_archiver C false true , 4294967061 0 0 +4294967062 pg_stat_all_tables C false true , 4294967062 0 0 +4294967063 pg_stat_all_indexes C false true , 4294967063 0 0 +4294967064 pg_stat_activity C false true , 4294967064 0 0 +4294967065 pg_shmem_allocations C false true , 4294967065 0 0 +4294967066 pg_shdepend C false true , 4294967066 0 0 +4294967067 pg_shseclabel C false true , 4294967067 0 0 +4294967068 pg_shdescription C false true , 4294967068 0 0 +4294967069 pg_shadow C false true , 4294967069 0 0 +4294967070 pg_settings C false true , 4294967070 0 0 +4294967071 pg_sequences C false true , 4294967071 0 0 +4294967072 pg_sequence C false true , 4294967072 0 0 +4294967073 pg_seclabel C false true , 4294967073 0 0 +4294967074 pg_seclabels C false true , 4294967074 0 0 +4294967075 pg_rules C false true , 4294967075 0 0 +4294967076 pg_roles C false true , 4294967076 0 0 +4294967077 pg_rewrite C false true , 4294967077 0 0 +4294967078 pg_replication_slots C false true , 4294967078 0 0 +4294967079 pg_replication_origin C false true , 4294967079 0 0 +4294967080 pg_replication_origin_status C false true , 4294967080 0 0 +4294967081 pg_range C false true , 4294967081 0 0 +4294967082 pg_publication_tables C false true , 4294967082 0 0 +4294967083 pg_publication C false true , 4294967083 0 0 +4294967084 pg_publication_rel C false true , 4294967084 0 0 +4294967085 pg_proc C false true , 4294967085 0 0 +4294967086 pg_prepared_xacts C false true , 4294967086 0 0 +4294967087 pg_prepared_statements C false true , 4294967087 0 0 +4294967088 pg_policy C false true , 4294967088 0 0 +4294967089 pg_policies C false true , 4294967089 0 0 +4294967090 pg_partitioned_table C false true , 4294967090 0 0 +4294967091 pg_opfamily C false true , 4294967091 0 0 +4294967092 pg_operator C false true , 4294967092 0 0 +4294967093 pg_opclass C false true , 4294967093 0 0 +4294967094 pg_namespace C false true , 4294967094 0 0 +4294967095 pg_matviews C false true , 4294967095 0 0 +4294967096 pg_locks C false true , 4294967096 0 0 +4294967097 pg_largeobject C false true , 4294967097 0 0 +4294967098 pg_largeobject_metadata C false true , 4294967098 0 0 +4294967099 pg_language C false true , 4294967099 0 0 +4294967100 pg_init_privs C false true , 4294967100 0 0 +4294967101 pg_inherits C false true , 4294967101 0 0 +4294967102 pg_indexes C false true , 4294967102 0 0 +4294967103 pg_index C false true , 4294967103 0 0 +4294967104 pg_hba_file_rules C false true , 4294967104 0 0 +4294967105 pg_group C false true , 4294967105 0 0 +4294967106 pg_foreign_table C false true , 4294967106 0 0 +4294967107 pg_foreign_server C false true , 4294967107 0 0 +4294967108 pg_foreign_data_wrapper C false true , 4294967108 0 0 +4294967109 pg_file_settings C false true , 4294967109 0 0 +4294967110 pg_extension C false true , 4294967110 0 0 +4294967111 pg_event_trigger C false true , 4294967111 0 0 +4294967112 pg_enum C false true , 4294967112 0 0 +4294967113 pg_description C false true , 4294967113 0 0 +4294967114 pg_depend C false true , 4294967114 0 0 +4294967115 pg_default_acl C false true , 4294967115 0 0 +4294967116 pg_db_role_setting C false true , 4294967116 0 0 +4294967117 pg_database C false true , 4294967117 0 0 +4294967118 pg_cursors C false true , 4294967118 0 0 +4294967119 pg_conversion C false true , 4294967119 0 0 +4294967120 pg_constraint C false true , 4294967120 0 0 +4294967121 pg_config C false true , 4294967121 0 0 +4294967122 pg_collation C false true , 4294967122 0 0 +4294967123 pg_class C false true , 4294967123 0 0 +4294967124 pg_cast C false true , 4294967124 0 0 +4294967125 pg_available_extensions C false true , 4294967125 0 0 +4294967126 pg_available_extension_versions C false true , 4294967126 0 0 +4294967127 pg_auth_members C false true , 4294967127 0 0 +4294967128 pg_authid C false true , 4294967128 0 0 +4294967129 pg_attribute C false true , 4294967129 0 0 +4294967130 pg_attrdef C false true , 4294967130 0 0 +4294967131 pg_amproc C false true , 4294967131 0 0 +4294967132 pg_amop C false true , 4294967132 0 0 +4294967133 pg_am C false true , 4294967133 0 0 +4294967134 pg_aggregate C false true , 4294967134 0 0 +4294967136 views C false true , 4294967136 0 0 +4294967137 view_table_usage C false true , 4294967137 0 0 +4294967138 view_routine_usage C false true , 4294967138 0 0 +4294967139 view_column_usage C false true , 4294967139 0 0 +4294967140 user_privileges C false true , 4294967140 0 0 +4294967141 user_mappings C false true , 4294967141 0 0 +4294967142 user_mapping_options C false true , 4294967142 0 0 +4294967143 user_defined_types C false true , 4294967143 0 0 +4294967144 user_attributes C false true , 4294967144 0 0 +4294967145 usage_privileges C false true , 4294967145 0 0 +4294967146 udt_privileges C false true , 4294967146 0 0 +4294967147 type_privileges C false true , 4294967147 0 0 +4294967148 triggers C false true , 4294967148 0 0 +4294967149 triggered_update_columns C false true , 4294967149 0 0 +4294967150 transforms C false true , 4294967150 0 0 +4294967151 tablespaces C false true , 4294967151 0 0 +4294967152 tablespaces_extensions C false true , 4294967152 0 0 +4294967153 tables C false true , 4294967153 0 0 +4294967154 tables_extensions C false true , 4294967154 0 0 +4294967155 table_privileges C false true , 4294967155 0 0 +4294967156 table_constraints_extensions C false true , 4294967156 0 0 +4294967157 table_constraints C false true , 4294967157 0 0 +4294967158 statistics C false true , 4294967158 0 0 +4294967159 st_units_of_measure C false true , 4294967159 0 0 +4294967160 st_spatial_reference_systems C false true , 4294967160 0 0 +4294967161 st_geometry_columns C false true , 4294967161 0 0 +4294967162 session_variables C false true , 4294967162 0 0 +4294967163 sequences C false true , 4294967163 0 0 +4294967164 schema_privileges C false true , 4294967164 0 0 +4294967165 schemata C false true , 4294967165 0 0 +4294967166 schemata_extensions C false true , 4294967166 0 0 +4294967167 sql_sizing C false true , 4294967167 0 0 +4294967168 sql_parts C false true , 4294967168 0 0 +4294967169 sql_implementation_info C false true , 4294967169 0 0 +4294967170 sql_features C false true , 4294967170 0 0 +4294967171 routines C false true , 4294967171 0 0 +4294967172 routine_privileges C false true , 4294967172 0 0 +4294967173 role_usage_grants C false true , 4294967173 0 0 +4294967174 role_udt_grants C false true , 4294967174 0 0 +4294967175 role_table_grants C false true , 4294967175 0 0 +4294967176 role_routine_grants C false true , 4294967176 0 0 +4294967177 role_column_grants C false true , 4294967177 0 0 +4294967178 resource_groups C false true , 4294967178 0 0 +4294967179 referential_constraints C false true , 4294967179 0 0 +4294967180 profiling C false true , 4294967180 0 0 +4294967181 processlist C false true , 4294967181 0 0 +4294967182 plugins C false true , 4294967182 0 0 +4294967183 partitions C false true , 4294967183 0 0 +4294967184 parameters C false true , 4294967184 0 0 +4294967185 optimizer_trace C false true , 4294967185 0 0 +4294967186 keywords C false true , 4294967186 0 0 +4294967187 key_column_usage C false true , 4294967187 0 0 +4294967188 information_schema_catalog_name C false true , 4294967188 0 0 +4294967189 foreign_tables C false true , 4294967189 0 0 +4294967190 foreign_table_options C false true , 4294967190 0 0 +4294967191 foreign_servers C false true , 4294967191 0 0 +4294967192 foreign_server_options C false true , 4294967192 0 0 +4294967193 foreign_data_wrappers C false true , 4294967193 0 0 +4294967194 foreign_data_wrapper_options C false true , 4294967194 0 0 +4294967195 files C false true , 4294967195 0 0 +4294967196 events C false true , 4294967196 0 0 +4294967197 engines C false true , 4294967197 0 0 +4294967198 enabled_roles C false true , 4294967198 0 0 +4294967199 element_types C false true , 4294967199 0 0 +4294967200 domains C false true , 4294967200 0 0 +4294967201 domain_udt_usage C false true , 4294967201 0 0 +4294967202 domain_constraints C false true , 4294967202 0 0 +4294967203 data_type_privileges C false true , 4294967203 0 0 +4294967204 constraint_table_usage C false true , 4294967204 0 0 +4294967205 constraint_column_usage C false true , 4294967205 0 0 +4294967206 columns C false true , 4294967206 0 0 +4294967207 columns_extensions C false true , 4294967207 0 0 +4294967208 column_udt_usage C false true , 4294967208 0 0 +4294967209 column_statistics C false true , 4294967209 0 0 +4294967210 column_privileges C false true , 4294967210 0 0 +4294967211 column_options C false true , 4294967211 0 0 +4294967212 column_domain_usage C false true , 4294967212 0 0 +4294967213 column_column_usage C false true , 4294967213 0 0 +4294967214 collations C false true , 4294967214 0 0 +4294967215 collation_character_set_applicability C false true , 4294967215 0 0 +4294967216 check_constraints C false true , 4294967216 0 0 +4294967217 check_constraint_routine_usage C false true , 4294967217 0 0 +4294967218 character_sets C false true , 4294967218 0 0 +4294967219 attributes C false true , 4294967219 0 0 +4294967220 applicable_roles C false true , 4294967220 0 0 +4294967221 administrable_role_authorizations C false true , 4294967221 0 0 +4294967223 super_regions C false true , 4294967223 0 0 +4294967224 pg_catalog_table_is_implemented C false true , 4294967224 0 0 +4294967225 tenant_usage_details C false true , 4294967225 0 0 +4294967226 active_range_feeds C false true , 4294967226 0 0 +4294967227 default_privileges C false true , 4294967227 0 0 +4294967228 regions C false true , 4294967228 0 0 +4294967229 cluster_inflight_traces C false true , 4294967229 0 0 +4294967230 lost_descriptors_with_data C false true , 4294967230 0 0 +4294967231 cross_db_references C false true , 4294967231 0 0 +4294967232 cluster_database_privileges C false true , 4294967232 0 0 +4294967233 invalid_objects C false true , 4294967233 0 0 +4294967234 zones C false true , 4294967234 0 0 +4294967235 transaction_statistics C false true , 4294967235 0 0 +4294967236 node_transaction_statistics C false true , 4294967236 0 0 +4294967237 table_row_statistics C false true , 4294967237 0 0 +4294967238 tables C false true , 4294967238 0 0 +4294967239 table_indexes C false true , 4294967239 0 0 +4294967240 table_columns C false true , 4294967240 0 0 +4294967241 statement_statistics C false true , 4294967241 0 0 +4294967242 session_variables C false true , 4294967242 0 0 +4294967243 session_trace C false true , 4294967243 0 0 +4294967244 schema_changes C false true , 4294967244 0 0 +4294967245 node_runtime_info C false true , 4294967245 0 0 +4294967246 ranges C false true , 4294967246 0 0 +4294967247 ranges_no_leases C false true , 4294967247 0 0 +4294967248 predefined_comments C false true , 4294967248 0 0 +4294967249 partitions C false true , 4294967249 0 0 +4294967250 node_txn_stats C false true , 4294967250 0 0 +4294967251 node_statement_statistics C false true , 4294967251 0 0 +4294967252 node_metrics C false true , 4294967252 0 0 +4294967253 node_sessions C false true , 4294967253 0 0 +4294967254 node_transactions C false true , 4294967254 0 0 +4294967255 node_queries C false true , 4294967255 0 0 +4294967256 node_execution_insights C false true , 4294967256 0 0 +4294967257 node_distsql_flows C false true , 4294967257 0 0 +4294967258 node_contention_events C false true , 4294967258 0 0 +4294967259 leases C false true , 4294967259 0 0 +4294967260 kv_store_status C false true , 4294967260 0 0 +4294967261 kv_node_status C false true , 4294967261 0 0 +4294967262 jobs C false true , 4294967262 0 0 +4294967263 node_inflight_trace_spans C false true , 4294967263 0 0 +4294967264 index_usage_statistics C false true , 4294967264 0 0 +4294967265 index_columns C false true , 4294967265 0 0 +4294967266 transaction_contention_events C false true , 4294967266 0 0 +4294967267 gossip_network C false true , 4294967267 0 0 +4294967268 gossip_liveness C false true , 4294967268 0 0 +4294967269 gossip_alerts C false true , 4294967269 0 0 +4294967270 gossip_nodes C false true , 4294967270 0 0 +4294967271 kv_node_liveness C false true , 4294967271 0 0 +4294967272 forward_dependencies C false true , 4294967272 0 0 +4294967273 feature_usage C false true , 4294967273 0 0 +4294967274 databases C false true , 4294967274 0 0 +4294967275 create_type_statements C false true , 4294967275 0 0 +4294967276 create_statements C false true , 4294967276 0 0 +4294967277 create_schema_statements C false true , 4294967277 0 0 +4294967278 create_function_statements C false true , 4294967278 0 0 +4294967279 cluster_transaction_statistics C false true , 4294967279 0 0 +4294967280 cluster_statement_statistics C false true , 4294967280 0 0 +4294967281 cluster_settings C false true , 4294967281 0 0 +4294967282 cluster_sessions C false true , 4294967282 0 0 +4294967283 cluster_transactions C false true , 4294967283 0 0 +4294967284 cluster_queries C false true , 4294967284 0 0 +4294967285 cluster_locks C false true , 4294967285 0 0 +4294967286 cluster_execution_insights C false true , 4294967286 0 0 4294967287 cluster_distsql_flows C false true , 4294967287 0 0 4294967288 cluster_contention_events C false true , 4294967288 0 0 4294967289 cluster_contended_tables C false true , 4294967289 0 0 @@ -2483,287 +2485,288 @@ oid typname typinput typoutput 100132 _newtype1 array_in array_out array_recv array_send 0 0 0 100133 newtype2 enum_in enum_out enum_recv enum_send 0 0 0 100134 _newtype2 array_in array_out array_recv array_send 0 0 0 -4294967003 spatial_ref_sys record_in record_out record_recv record_send 0 0 0 -4294967004 geometry_columns record_in record_out record_recv record_send 0 0 0 -4294967005 geography_columns record_in record_out record_recv record_send 0 0 0 -4294967007 pg_views record_in record_out record_recv record_send 0 0 0 -4294967008 pg_user record_in record_out record_recv record_send 0 0 0 -4294967009 pg_user_mappings record_in record_out record_recv record_send 0 0 0 -4294967010 pg_user_mapping record_in record_out record_recv record_send 0 0 0 -4294967011 pg_type record_in record_out record_recv record_send 0 0 0 -4294967012 pg_ts_template record_in record_out record_recv record_send 0 0 0 -4294967013 pg_ts_parser record_in record_out record_recv record_send 0 0 0 -4294967014 pg_ts_dict record_in record_out record_recv record_send 0 0 0 -4294967015 pg_ts_config record_in record_out record_recv record_send 0 0 0 -4294967016 pg_ts_config_map record_in record_out record_recv record_send 0 0 0 -4294967017 pg_trigger record_in record_out record_recv record_send 0 0 0 -4294967018 pg_transform record_in record_out record_recv record_send 0 0 0 -4294967019 pg_timezone_names record_in record_out record_recv record_send 0 0 0 -4294967020 pg_timezone_abbrevs record_in record_out record_recv record_send 0 0 0 -4294967021 pg_tablespace record_in record_out record_recv record_send 0 0 0 -4294967022 pg_tables record_in record_out record_recv record_send 0 0 0 -4294967023 pg_subscription record_in record_out record_recv record_send 0 0 0 -4294967024 pg_subscription_rel record_in record_out record_recv record_send 0 0 0 -4294967025 pg_stats record_in record_out record_recv record_send 0 0 0 -4294967026 pg_stats_ext record_in record_out record_recv record_send 0 0 0 -4294967027 pg_statistic record_in record_out record_recv record_send 0 0 0 -4294967028 pg_statistic_ext record_in record_out record_recv record_send 0 0 0 -4294967029 pg_statistic_ext_data record_in record_out record_recv record_send 0 0 0 -4294967030 pg_statio_user_tables record_in record_out record_recv record_send 0 0 0 -4294967031 pg_statio_user_sequences record_in record_out record_recv record_send 0 0 0 -4294967032 pg_statio_user_indexes record_in record_out record_recv record_send 0 0 0 -4294967033 pg_statio_sys_tables record_in record_out record_recv record_send 0 0 0 -4294967034 pg_statio_sys_sequences record_in record_out record_recv record_send 0 0 0 -4294967035 pg_statio_sys_indexes record_in record_out record_recv record_send 0 0 0 -4294967036 pg_statio_all_tables record_in record_out record_recv record_send 0 0 0 -4294967037 pg_statio_all_sequences record_in record_out record_recv record_send 0 0 0 -4294967038 pg_statio_all_indexes record_in record_out record_recv record_send 0 0 0 -4294967039 pg_stat_xact_user_tables record_in record_out record_recv record_send 0 0 0 -4294967040 pg_stat_xact_user_functions record_in record_out record_recv record_send 0 0 0 -4294967041 pg_stat_xact_sys_tables record_in record_out record_recv record_send 0 0 0 -4294967042 pg_stat_xact_all_tables record_in record_out record_recv record_send 0 0 0 -4294967043 pg_stat_wal_receiver record_in record_out record_recv record_send 0 0 0 -4294967044 pg_stat_user_tables record_in record_out record_recv record_send 0 0 0 -4294967045 pg_stat_user_indexes record_in record_out record_recv record_send 0 0 0 -4294967046 pg_stat_user_functions record_in record_out record_recv record_send 0 0 0 -4294967047 pg_stat_sys_tables record_in record_out record_recv record_send 0 0 0 -4294967048 pg_stat_sys_indexes record_in record_out record_recv record_send 0 0 0 -4294967049 pg_stat_subscription record_in record_out record_recv record_send 0 0 0 -4294967050 pg_stat_ssl record_in record_out record_recv record_send 0 0 0 -4294967051 pg_stat_slru record_in record_out record_recv record_send 0 0 0 -4294967052 pg_stat_replication record_in record_out record_recv record_send 0 0 0 -4294967053 pg_stat_progress_vacuum record_in record_out record_recv record_send 0 0 0 -4294967054 pg_stat_progress_create_index record_in record_out record_recv record_send 0 0 0 -4294967055 pg_stat_progress_cluster record_in record_out record_recv record_send 0 0 0 -4294967056 pg_stat_progress_basebackup record_in record_out record_recv record_send 0 0 0 -4294967057 pg_stat_progress_analyze record_in record_out record_recv record_send 0 0 0 -4294967058 pg_stat_gssapi record_in record_out record_recv record_send 0 0 0 -4294967059 pg_stat_database record_in record_out record_recv record_send 0 0 0 -4294967060 pg_stat_database_conflicts record_in record_out record_recv record_send 0 0 0 -4294967061 pg_stat_bgwriter record_in record_out record_recv record_send 0 0 0 -4294967062 pg_stat_archiver record_in record_out record_recv record_send 0 0 0 -4294967063 pg_stat_all_tables record_in record_out record_recv record_send 0 0 0 -4294967064 pg_stat_all_indexes record_in record_out record_recv record_send 0 0 0 -4294967065 pg_stat_activity record_in record_out record_recv record_send 0 0 0 -4294967066 pg_shmem_allocations record_in record_out record_recv record_send 0 0 0 -4294967067 pg_shdepend record_in record_out record_recv record_send 0 0 0 -4294967068 pg_shseclabel record_in record_out record_recv record_send 0 0 0 -4294967069 pg_shdescription record_in record_out record_recv record_send 0 0 0 -4294967070 pg_shadow record_in record_out record_recv record_send 0 0 0 -4294967071 pg_settings record_in record_out record_recv record_send 0 0 0 -4294967072 pg_sequences record_in record_out record_recv record_send 0 0 0 -4294967073 pg_sequence record_in record_out record_recv record_send 0 0 0 -4294967074 pg_seclabel record_in record_out record_recv record_send 0 0 0 -4294967075 pg_seclabels record_in record_out record_recv record_send 0 0 0 -4294967076 pg_rules record_in record_out record_recv record_send 0 0 0 -4294967077 pg_roles record_in record_out record_recv record_send 0 0 0 -4294967078 pg_rewrite record_in record_out record_recv record_send 0 0 0 -4294967079 pg_replication_slots record_in record_out record_recv record_send 0 0 0 -4294967080 pg_replication_origin record_in record_out record_recv record_send 0 0 0 -4294967081 pg_replication_origin_status record_in record_out record_recv record_send 0 0 0 -4294967082 pg_range record_in record_out record_recv record_send 0 0 0 -4294967083 pg_publication_tables record_in record_out record_recv record_send 0 0 0 -4294967084 pg_publication record_in record_out record_recv record_send 0 0 0 -4294967085 pg_publication_rel record_in record_out record_recv record_send 0 0 0 -4294967086 pg_proc record_in record_out record_recv record_send 0 0 0 -4294967087 pg_prepared_xacts record_in record_out record_recv record_send 0 0 0 -4294967088 pg_prepared_statements record_in record_out record_recv record_send 0 0 0 -4294967089 pg_policy record_in record_out record_recv record_send 0 0 0 -4294967090 pg_policies record_in record_out record_recv record_send 0 0 0 -4294967091 pg_partitioned_table record_in record_out record_recv record_send 0 0 0 -4294967092 pg_opfamily record_in record_out record_recv record_send 0 0 0 -4294967093 pg_operator record_in record_out record_recv record_send 0 0 0 -4294967094 pg_opclass record_in record_out record_recv record_send 0 0 0 -4294967095 pg_namespace record_in record_out record_recv record_send 0 0 0 -4294967096 pg_matviews record_in record_out record_recv record_send 0 0 0 -4294967097 pg_locks record_in record_out record_recv record_send 0 0 0 -4294967098 pg_largeobject record_in record_out record_recv record_send 0 0 0 -4294967099 pg_largeobject_metadata record_in record_out record_recv record_send 0 0 0 -4294967100 pg_language record_in record_out record_recv record_send 0 0 0 -4294967101 pg_init_privs record_in record_out record_recv record_send 0 0 0 -4294967102 pg_inherits record_in record_out record_recv record_send 0 0 0 -4294967103 pg_indexes record_in record_out record_recv record_send 0 0 0 -4294967104 pg_index record_in record_out record_recv record_send 0 0 0 -4294967105 pg_hba_file_rules record_in record_out record_recv record_send 0 0 0 -4294967106 pg_group record_in record_out record_recv record_send 0 0 0 -4294967107 pg_foreign_table record_in record_out record_recv record_send 0 0 0 -4294967108 pg_foreign_server record_in record_out record_recv record_send 0 0 0 -4294967109 pg_foreign_data_wrapper record_in record_out record_recv record_send 0 0 0 -4294967110 pg_file_settings record_in record_out record_recv record_send 0 0 0 -4294967111 pg_extension record_in record_out record_recv record_send 0 0 0 -4294967112 pg_event_trigger record_in record_out record_recv record_send 0 0 0 -4294967113 pg_enum record_in record_out record_recv record_send 0 0 0 -4294967114 pg_description record_in record_out record_recv record_send 0 0 0 -4294967115 pg_depend record_in record_out record_recv record_send 0 0 0 -4294967116 pg_default_acl record_in record_out record_recv record_send 0 0 0 -4294967117 pg_db_role_setting record_in record_out record_recv record_send 0 0 0 -4294967118 pg_database record_in record_out record_recv record_send 0 0 0 -4294967119 pg_cursors record_in record_out record_recv record_send 0 0 0 -4294967120 pg_conversion record_in record_out record_recv record_send 0 0 0 -4294967121 pg_constraint record_in record_out record_recv record_send 0 0 0 -4294967122 pg_config record_in record_out record_recv record_send 0 0 0 -4294967123 pg_collation record_in record_out record_recv record_send 0 0 0 -4294967124 pg_class record_in record_out record_recv record_send 0 0 0 -4294967125 pg_cast record_in record_out record_recv record_send 0 0 0 -4294967126 pg_available_extensions record_in record_out record_recv record_send 0 0 0 -4294967127 pg_available_extension_versions record_in record_out record_recv record_send 0 0 0 -4294967128 pg_auth_members record_in record_out record_recv record_send 0 0 0 -4294967129 pg_authid record_in record_out record_recv record_send 0 0 0 -4294967130 pg_attribute record_in record_out record_recv record_send 0 0 0 -4294967131 pg_attrdef record_in record_out record_recv record_send 0 0 0 -4294967132 pg_amproc record_in record_out record_recv record_send 0 0 0 -4294967133 pg_amop record_in record_out record_recv record_send 0 0 0 -4294967134 pg_am record_in record_out record_recv record_send 0 0 0 -4294967135 pg_aggregate record_in record_out record_recv record_send 0 0 0 -4294967137 views record_in record_out record_recv record_send 0 0 0 -4294967138 view_table_usage record_in record_out record_recv record_send 0 0 0 -4294967139 view_routine_usage record_in record_out record_recv record_send 0 0 0 -4294967140 view_column_usage record_in record_out record_recv record_send 0 0 0 -4294967141 user_privileges record_in record_out record_recv record_send 0 0 0 -4294967142 user_mappings record_in record_out record_recv record_send 0 0 0 -4294967143 user_mapping_options record_in record_out record_recv record_send 0 0 0 -4294967144 user_defined_types record_in record_out record_recv record_send 0 0 0 -4294967145 user_attributes record_in record_out record_recv record_send 0 0 0 -4294967146 usage_privileges record_in record_out record_recv record_send 0 0 0 -4294967147 udt_privileges record_in record_out record_recv record_send 0 0 0 -4294967148 type_privileges record_in record_out record_recv record_send 0 0 0 -4294967149 triggers record_in record_out record_recv record_send 0 0 0 -4294967150 triggered_update_columns record_in record_out record_recv record_send 0 0 0 -4294967151 transforms record_in record_out record_recv record_send 0 0 0 -4294967152 tablespaces record_in record_out record_recv record_send 0 0 0 -4294967153 tablespaces_extensions record_in record_out record_recv record_send 0 0 0 -4294967154 tables record_in record_out record_recv record_send 0 0 0 -4294967155 tables_extensions record_in record_out record_recv record_send 0 0 0 -4294967156 table_privileges record_in record_out record_recv record_send 0 0 0 -4294967157 table_constraints_extensions record_in record_out record_recv record_send 0 0 0 -4294967158 table_constraints record_in record_out record_recv record_send 0 0 0 -4294967159 statistics record_in record_out record_recv record_send 0 0 0 -4294967160 st_units_of_measure record_in record_out record_recv record_send 0 0 0 -4294967161 st_spatial_reference_systems record_in record_out record_recv record_send 0 0 0 -4294967162 st_geometry_columns record_in record_out record_recv record_send 0 0 0 -4294967163 session_variables record_in record_out record_recv record_send 0 0 0 -4294967164 sequences record_in record_out record_recv record_send 0 0 0 -4294967165 schema_privileges record_in record_out record_recv record_send 0 0 0 -4294967166 schemata record_in record_out record_recv record_send 0 0 0 -4294967167 schemata_extensions record_in record_out record_recv record_send 0 0 0 -4294967168 sql_sizing record_in record_out record_recv record_send 0 0 0 -4294967169 sql_parts record_in record_out record_recv record_send 0 0 0 -4294967170 sql_implementation_info record_in record_out record_recv record_send 0 0 0 -4294967171 sql_features record_in record_out record_recv record_send 0 0 0 -4294967172 routines record_in record_out record_recv record_send 0 0 0 -4294967173 routine_privileges record_in record_out record_recv record_send 0 0 0 -4294967174 role_usage_grants record_in record_out record_recv record_send 0 0 0 -4294967175 role_udt_grants record_in record_out record_recv record_send 0 0 0 -4294967176 role_table_grants record_in record_out record_recv record_send 0 0 0 -4294967177 role_routine_grants record_in record_out record_recv record_send 0 0 0 -4294967178 role_column_grants record_in record_out record_recv record_send 0 0 0 -4294967179 resource_groups record_in record_out record_recv record_send 0 0 0 -4294967180 referential_constraints record_in record_out record_recv record_send 0 0 0 -4294967181 profiling record_in record_out record_recv record_send 0 0 0 -4294967182 processlist record_in record_out record_recv record_send 0 0 0 -4294967183 plugins record_in record_out record_recv record_send 0 0 0 -4294967184 partitions record_in record_out record_recv record_send 0 0 0 -4294967185 parameters record_in record_out record_recv record_send 0 0 0 -4294967186 optimizer_trace record_in record_out record_recv record_send 0 0 0 -4294967187 keywords record_in record_out record_recv record_send 0 0 0 -4294967188 key_column_usage record_in record_out record_recv record_send 0 0 0 -4294967189 information_schema_catalog_name record_in record_out record_recv record_send 0 0 0 -4294967190 foreign_tables record_in record_out record_recv record_send 0 0 0 -4294967191 foreign_table_options record_in record_out record_recv record_send 0 0 0 -4294967192 foreign_servers record_in record_out record_recv record_send 0 0 0 -4294967193 foreign_server_options record_in record_out record_recv record_send 0 0 0 -4294967194 foreign_data_wrappers record_in record_out record_recv record_send 0 0 0 -4294967195 foreign_data_wrapper_options record_in record_out record_recv record_send 0 0 0 -4294967196 files record_in record_out record_recv record_send 0 0 0 -4294967197 events record_in record_out record_recv record_send 0 0 0 -4294967198 engines record_in record_out record_recv record_send 0 0 0 -4294967199 enabled_roles record_in record_out record_recv record_send 0 0 0 -4294967200 element_types record_in record_out record_recv record_send 0 0 0 -4294967201 domains record_in record_out record_recv record_send 0 0 0 -4294967202 domain_udt_usage record_in record_out record_recv record_send 0 0 0 -4294967203 domain_constraints record_in record_out record_recv record_send 0 0 0 -4294967204 data_type_privileges record_in record_out record_recv record_send 0 0 0 -4294967205 constraint_table_usage record_in record_out record_recv record_send 0 0 0 -4294967206 constraint_column_usage record_in record_out record_recv record_send 0 0 0 -4294967207 columns record_in record_out record_recv record_send 0 0 0 -4294967208 columns_extensions record_in record_out record_recv record_send 0 0 0 -4294967209 column_udt_usage record_in record_out record_recv record_send 0 0 0 -4294967210 column_statistics record_in record_out record_recv record_send 0 0 0 -4294967211 column_privileges record_in record_out record_recv record_send 0 0 0 -4294967212 column_options record_in record_out record_recv record_send 0 0 0 -4294967213 column_domain_usage record_in record_out record_recv record_send 0 0 0 -4294967214 column_column_usage record_in record_out record_recv record_send 0 0 0 -4294967215 collations record_in record_out record_recv record_send 0 0 0 -4294967216 collation_character_set_applicability record_in record_out record_recv record_send 0 0 0 -4294967217 check_constraints record_in record_out record_recv record_send 0 0 0 -4294967218 check_constraint_routine_usage record_in record_out record_recv record_send 0 0 0 -4294967219 character_sets record_in record_out record_recv record_send 0 0 0 -4294967220 attributes record_in record_out record_recv record_send 0 0 0 -4294967221 applicable_roles record_in record_out record_recv record_send 0 0 0 -4294967222 administrable_role_authorizations record_in record_out record_recv record_send 0 0 0 -4294967224 super_regions record_in record_out record_recv record_send 0 0 0 -4294967225 pg_catalog_table_is_implemented record_in record_out record_recv record_send 0 0 0 -4294967226 tenant_usage_details record_in record_out record_recv record_send 0 0 0 -4294967227 active_range_feeds record_in record_out record_recv record_send 0 0 0 -4294967228 default_privileges record_in record_out record_recv record_send 0 0 0 -4294967229 regions record_in record_out record_recv record_send 0 0 0 -4294967230 cluster_inflight_traces record_in record_out record_recv record_send 0 0 0 -4294967231 lost_descriptors_with_data record_in record_out record_recv record_send 0 0 0 -4294967232 cross_db_references record_in record_out record_recv record_send 0 0 0 -4294967233 cluster_database_privileges record_in record_out record_recv record_send 0 0 0 -4294967234 invalid_objects record_in record_out record_recv record_send 0 0 0 -4294967235 zones record_in record_out record_recv record_send 0 0 0 -4294967236 transaction_statistics record_in record_out record_recv record_send 0 0 0 -4294967237 node_transaction_statistics record_in record_out record_recv record_send 0 0 0 -4294967238 table_row_statistics record_in record_out record_recv record_send 0 0 0 -4294967239 tables record_in record_out record_recv record_send 0 0 0 -4294967240 table_indexes record_in record_out record_recv record_send 0 0 0 -4294967241 table_columns record_in record_out record_recv record_send 0 0 0 -4294967242 statement_statistics record_in record_out record_recv record_send 0 0 0 -4294967243 session_variables record_in record_out record_recv record_send 0 0 0 -4294967244 session_trace record_in record_out record_recv record_send 0 0 0 -4294967245 schema_changes record_in record_out record_recv record_send 0 0 0 -4294967246 node_runtime_info record_in record_out record_recv record_send 0 0 0 -4294967247 ranges record_in record_out record_recv record_send 0 0 0 -4294967248 ranges_no_leases record_in record_out record_recv record_send 0 0 0 -4294967249 predefined_comments record_in record_out record_recv record_send 0 0 0 -4294967250 partitions record_in record_out record_recv record_send 0 0 0 -4294967251 node_txn_stats record_in record_out record_recv record_send 0 0 0 -4294967252 node_statement_statistics record_in record_out record_recv record_send 0 0 0 -4294967253 node_metrics record_in record_out record_recv record_send 0 0 0 -4294967254 node_sessions record_in record_out record_recv record_send 0 0 0 -4294967255 node_transactions record_in record_out record_recv record_send 0 0 0 -4294967256 node_queries record_in record_out record_recv record_send 0 0 0 -4294967257 node_execution_insights record_in record_out record_recv record_send 0 0 0 -4294967258 node_distsql_flows record_in record_out record_recv record_send 0 0 0 -4294967259 node_contention_events record_in record_out record_recv record_send 0 0 0 -4294967260 leases record_in record_out record_recv record_send 0 0 0 -4294967261 kv_store_status record_in record_out record_recv record_send 0 0 0 -4294967262 kv_node_status record_in record_out record_recv record_send 0 0 0 -4294967263 jobs record_in record_out record_recv record_send 0 0 0 -4294967264 node_inflight_trace_spans record_in record_out record_recv record_send 0 0 0 -4294967265 index_usage_statistics record_in record_out record_recv record_send 0 0 0 -4294967266 index_columns record_in record_out record_recv record_send 0 0 0 -4294967267 transaction_contention_events record_in record_out record_recv record_send 0 0 0 -4294967268 gossip_network record_in record_out record_recv record_send 0 0 0 -4294967269 gossip_liveness record_in record_out record_recv record_send 0 0 0 -4294967270 gossip_alerts record_in record_out record_recv record_send 0 0 0 -4294967271 gossip_nodes record_in record_out record_recv record_send 0 0 0 -4294967272 kv_node_liveness record_in record_out record_recv record_send 0 0 0 -4294967273 forward_dependencies record_in record_out record_recv record_send 0 0 0 -4294967274 feature_usage record_in record_out record_recv record_send 0 0 0 -4294967275 databases record_in record_out record_recv record_send 0 0 0 -4294967276 create_type_statements record_in record_out record_recv record_send 0 0 0 -4294967277 create_statements record_in record_out record_recv record_send 0 0 0 -4294967278 create_schema_statements record_in record_out record_recv record_send 0 0 0 -4294967279 create_function_statements record_in record_out record_recv record_send 0 0 0 -4294967280 cluster_transaction_statistics record_in record_out record_recv record_send 0 0 0 -4294967281 cluster_statement_statistics record_in record_out record_recv record_send 0 0 0 -4294967282 cluster_settings record_in record_out record_recv record_send 0 0 0 -4294967283 cluster_sessions record_in record_out record_recv record_send 0 0 0 -4294967284 cluster_transactions record_in record_out record_recv record_send 0 0 0 -4294967285 cluster_queries record_in record_out record_recv record_send 0 0 0 -4294967286 cluster_locks record_in record_out record_recv record_send 0 0 0 +4294967002 spatial_ref_sys record_in record_out record_recv record_send 0 0 0 +4294967003 geometry_columns record_in record_out record_recv record_send 0 0 0 +4294967004 geography_columns record_in record_out record_recv record_send 0 0 0 +4294967006 pg_views record_in record_out record_recv record_send 0 0 0 +4294967007 pg_user record_in record_out record_recv record_send 0 0 0 +4294967008 pg_user_mappings record_in record_out record_recv record_send 0 0 0 +4294967009 pg_user_mapping record_in record_out record_recv record_send 0 0 0 +4294967010 pg_type record_in record_out record_recv record_send 0 0 0 +4294967011 pg_ts_template record_in record_out record_recv record_send 0 0 0 +4294967012 pg_ts_parser record_in record_out record_recv record_send 0 0 0 +4294967013 pg_ts_dict record_in record_out record_recv record_send 0 0 0 +4294967014 pg_ts_config record_in record_out record_recv record_send 0 0 0 +4294967015 pg_ts_config_map record_in record_out record_recv record_send 0 0 0 +4294967016 pg_trigger record_in record_out record_recv record_send 0 0 0 +4294967017 pg_transform record_in record_out record_recv record_send 0 0 0 +4294967018 pg_timezone_names record_in record_out record_recv record_send 0 0 0 +4294967019 pg_timezone_abbrevs record_in record_out record_recv record_send 0 0 0 +4294967020 pg_tablespace record_in record_out record_recv record_send 0 0 0 +4294967021 pg_tables record_in record_out record_recv record_send 0 0 0 +4294967022 pg_subscription record_in record_out record_recv record_send 0 0 0 +4294967023 pg_subscription_rel record_in record_out record_recv record_send 0 0 0 +4294967024 pg_stats record_in record_out record_recv record_send 0 0 0 +4294967025 pg_stats_ext record_in record_out record_recv record_send 0 0 0 +4294967026 pg_statistic record_in record_out record_recv record_send 0 0 0 +4294967027 pg_statistic_ext record_in record_out record_recv record_send 0 0 0 +4294967028 pg_statistic_ext_data record_in record_out record_recv record_send 0 0 0 +4294967029 pg_statio_user_tables record_in record_out record_recv record_send 0 0 0 +4294967030 pg_statio_user_sequences record_in record_out record_recv record_send 0 0 0 +4294967031 pg_statio_user_indexes record_in record_out record_recv record_send 0 0 0 +4294967032 pg_statio_sys_tables record_in record_out record_recv record_send 0 0 0 +4294967033 pg_statio_sys_sequences record_in record_out record_recv record_send 0 0 0 +4294967034 pg_statio_sys_indexes record_in record_out record_recv record_send 0 0 0 +4294967035 pg_statio_all_tables record_in record_out record_recv record_send 0 0 0 +4294967036 pg_statio_all_sequences record_in record_out record_recv record_send 0 0 0 +4294967037 pg_statio_all_indexes record_in record_out record_recv record_send 0 0 0 +4294967038 pg_stat_xact_user_tables record_in record_out record_recv record_send 0 0 0 +4294967039 pg_stat_xact_user_functions record_in record_out record_recv record_send 0 0 0 +4294967040 pg_stat_xact_sys_tables record_in record_out record_recv record_send 0 0 0 +4294967041 pg_stat_xact_all_tables record_in record_out record_recv record_send 0 0 0 +4294967042 pg_stat_wal_receiver record_in record_out record_recv record_send 0 0 0 +4294967043 pg_stat_user_tables record_in record_out record_recv record_send 0 0 0 +4294967044 pg_stat_user_indexes record_in record_out record_recv record_send 0 0 0 +4294967045 pg_stat_user_functions record_in record_out record_recv record_send 0 0 0 +4294967046 pg_stat_sys_tables record_in record_out record_recv record_send 0 0 0 +4294967047 pg_stat_sys_indexes record_in record_out record_recv record_send 0 0 0 +4294967048 pg_stat_subscription record_in record_out record_recv record_send 0 0 0 +4294967049 pg_stat_ssl record_in record_out record_recv record_send 0 0 0 +4294967050 pg_stat_slru record_in record_out record_recv record_send 0 0 0 +4294967051 pg_stat_replication record_in record_out record_recv record_send 0 0 0 +4294967052 pg_stat_progress_vacuum record_in record_out record_recv record_send 0 0 0 +4294967053 pg_stat_progress_create_index record_in record_out record_recv record_send 0 0 0 +4294967054 pg_stat_progress_cluster record_in record_out record_recv record_send 0 0 0 +4294967055 pg_stat_progress_basebackup record_in record_out record_recv record_send 0 0 0 +4294967056 pg_stat_progress_analyze record_in record_out record_recv record_send 0 0 0 +4294967057 pg_stat_gssapi record_in record_out record_recv record_send 0 0 0 +4294967058 pg_stat_database record_in record_out record_recv record_send 0 0 0 +4294967059 pg_stat_database_conflicts record_in record_out record_recv record_send 0 0 0 +4294967060 pg_stat_bgwriter record_in record_out record_recv record_send 0 0 0 +4294967061 pg_stat_archiver record_in record_out record_recv record_send 0 0 0 +4294967062 pg_stat_all_tables record_in record_out record_recv record_send 0 0 0 +4294967063 pg_stat_all_indexes record_in record_out record_recv record_send 0 0 0 +4294967064 pg_stat_activity record_in record_out record_recv record_send 0 0 0 +4294967065 pg_shmem_allocations record_in record_out record_recv record_send 0 0 0 +4294967066 pg_shdepend record_in record_out record_recv record_send 0 0 0 +4294967067 pg_shseclabel record_in record_out record_recv record_send 0 0 0 +4294967068 pg_shdescription record_in record_out record_recv record_send 0 0 0 +4294967069 pg_shadow record_in record_out record_recv record_send 0 0 0 +4294967070 pg_settings record_in record_out record_recv record_send 0 0 0 +4294967071 pg_sequences record_in record_out record_recv record_send 0 0 0 +4294967072 pg_sequence record_in record_out record_recv record_send 0 0 0 +4294967073 pg_seclabel record_in record_out record_recv record_send 0 0 0 +4294967074 pg_seclabels record_in record_out record_recv record_send 0 0 0 +4294967075 pg_rules record_in record_out record_recv record_send 0 0 0 +4294967076 pg_roles record_in record_out record_recv record_send 0 0 0 +4294967077 pg_rewrite record_in record_out record_recv record_send 0 0 0 +4294967078 pg_replication_slots record_in record_out record_recv record_send 0 0 0 +4294967079 pg_replication_origin record_in record_out record_recv record_send 0 0 0 +4294967080 pg_replication_origin_status record_in record_out record_recv record_send 0 0 0 +4294967081 pg_range record_in record_out record_recv record_send 0 0 0 +4294967082 pg_publication_tables record_in record_out record_recv record_send 0 0 0 +4294967083 pg_publication record_in record_out record_recv record_send 0 0 0 +4294967084 pg_publication_rel record_in record_out record_recv record_send 0 0 0 +4294967085 pg_proc record_in record_out record_recv record_send 0 0 0 +4294967086 pg_prepared_xacts record_in record_out record_recv record_send 0 0 0 +4294967087 pg_prepared_statements record_in record_out record_recv record_send 0 0 0 +4294967088 pg_policy record_in record_out record_recv record_send 0 0 0 +4294967089 pg_policies record_in record_out record_recv record_send 0 0 0 +4294967090 pg_partitioned_table record_in record_out record_recv record_send 0 0 0 +4294967091 pg_opfamily record_in record_out record_recv record_send 0 0 0 +4294967092 pg_operator record_in record_out record_recv record_send 0 0 0 +4294967093 pg_opclass record_in record_out record_recv record_send 0 0 0 +4294967094 pg_namespace record_in record_out record_recv record_send 0 0 0 +4294967095 pg_matviews record_in record_out record_recv record_send 0 0 0 +4294967096 pg_locks record_in record_out record_recv record_send 0 0 0 +4294967097 pg_largeobject record_in record_out record_recv record_send 0 0 0 +4294967098 pg_largeobject_metadata record_in record_out record_recv record_send 0 0 0 +4294967099 pg_language record_in record_out record_recv record_send 0 0 0 +4294967100 pg_init_privs record_in record_out record_recv record_send 0 0 0 +4294967101 pg_inherits record_in record_out record_recv record_send 0 0 0 +4294967102 pg_indexes record_in record_out record_recv record_send 0 0 0 +4294967103 pg_index record_in record_out record_recv record_send 0 0 0 +4294967104 pg_hba_file_rules record_in record_out record_recv record_send 0 0 0 +4294967105 pg_group record_in record_out record_recv record_send 0 0 0 +4294967106 pg_foreign_table record_in record_out record_recv record_send 0 0 0 +4294967107 pg_foreign_server record_in record_out record_recv record_send 0 0 0 +4294967108 pg_foreign_data_wrapper record_in record_out record_recv record_send 0 0 0 +4294967109 pg_file_settings record_in record_out record_recv record_send 0 0 0 +4294967110 pg_extension record_in record_out record_recv record_send 0 0 0 +4294967111 pg_event_trigger record_in record_out record_recv record_send 0 0 0 +4294967112 pg_enum record_in record_out record_recv record_send 0 0 0 +4294967113 pg_description record_in record_out record_recv record_send 0 0 0 +4294967114 pg_depend record_in record_out record_recv record_send 0 0 0 +4294967115 pg_default_acl record_in record_out record_recv record_send 0 0 0 +4294967116 pg_db_role_setting record_in record_out record_recv record_send 0 0 0 +4294967117 pg_database record_in record_out record_recv record_send 0 0 0 +4294967118 pg_cursors record_in record_out record_recv record_send 0 0 0 +4294967119 pg_conversion record_in record_out record_recv record_send 0 0 0 +4294967120 pg_constraint record_in record_out record_recv record_send 0 0 0 +4294967121 pg_config record_in record_out record_recv record_send 0 0 0 +4294967122 pg_collation record_in record_out record_recv record_send 0 0 0 +4294967123 pg_class record_in record_out record_recv record_send 0 0 0 +4294967124 pg_cast record_in record_out record_recv record_send 0 0 0 +4294967125 pg_available_extensions record_in record_out record_recv record_send 0 0 0 +4294967126 pg_available_extension_versions record_in record_out record_recv record_send 0 0 0 +4294967127 pg_auth_members record_in record_out record_recv record_send 0 0 0 +4294967128 pg_authid record_in record_out record_recv record_send 0 0 0 +4294967129 pg_attribute record_in record_out record_recv record_send 0 0 0 +4294967130 pg_attrdef record_in record_out record_recv record_send 0 0 0 +4294967131 pg_amproc record_in record_out record_recv record_send 0 0 0 +4294967132 pg_amop record_in record_out record_recv record_send 0 0 0 +4294967133 pg_am record_in record_out record_recv record_send 0 0 0 +4294967134 pg_aggregate record_in record_out record_recv record_send 0 0 0 +4294967136 views record_in record_out record_recv record_send 0 0 0 +4294967137 view_table_usage record_in record_out record_recv record_send 0 0 0 +4294967138 view_routine_usage record_in record_out record_recv record_send 0 0 0 +4294967139 view_column_usage record_in record_out record_recv record_send 0 0 0 +4294967140 user_privileges record_in record_out record_recv record_send 0 0 0 +4294967141 user_mappings record_in record_out record_recv record_send 0 0 0 +4294967142 user_mapping_options record_in record_out record_recv record_send 0 0 0 +4294967143 user_defined_types record_in record_out record_recv record_send 0 0 0 +4294967144 user_attributes record_in record_out record_recv record_send 0 0 0 +4294967145 usage_privileges record_in record_out record_recv record_send 0 0 0 +4294967146 udt_privileges record_in record_out record_recv record_send 0 0 0 +4294967147 type_privileges record_in record_out record_recv record_send 0 0 0 +4294967148 triggers record_in record_out record_recv record_send 0 0 0 +4294967149 triggered_update_columns record_in record_out record_recv record_send 0 0 0 +4294967150 transforms record_in record_out record_recv record_send 0 0 0 +4294967151 tablespaces record_in record_out record_recv record_send 0 0 0 +4294967152 tablespaces_extensions record_in record_out record_recv record_send 0 0 0 +4294967153 tables record_in record_out record_recv record_send 0 0 0 +4294967154 tables_extensions record_in record_out record_recv record_send 0 0 0 +4294967155 table_privileges record_in record_out record_recv record_send 0 0 0 +4294967156 table_constraints_extensions record_in record_out record_recv record_send 0 0 0 +4294967157 table_constraints record_in record_out record_recv record_send 0 0 0 +4294967158 statistics record_in record_out record_recv record_send 0 0 0 +4294967159 st_units_of_measure record_in record_out record_recv record_send 0 0 0 +4294967160 st_spatial_reference_systems record_in record_out record_recv record_send 0 0 0 +4294967161 st_geometry_columns record_in record_out record_recv record_send 0 0 0 +4294967162 session_variables record_in record_out record_recv record_send 0 0 0 +4294967163 sequences record_in record_out record_recv record_send 0 0 0 +4294967164 schema_privileges record_in record_out record_recv record_send 0 0 0 +4294967165 schemata record_in record_out record_recv record_send 0 0 0 +4294967166 schemata_extensions record_in record_out record_recv record_send 0 0 0 +4294967167 sql_sizing record_in record_out record_recv record_send 0 0 0 +4294967168 sql_parts record_in record_out record_recv record_send 0 0 0 +4294967169 sql_implementation_info record_in record_out record_recv record_send 0 0 0 +4294967170 sql_features record_in record_out record_recv record_send 0 0 0 +4294967171 routines record_in record_out record_recv record_send 0 0 0 +4294967172 routine_privileges record_in record_out record_recv record_send 0 0 0 +4294967173 role_usage_grants record_in record_out record_recv record_send 0 0 0 +4294967174 role_udt_grants record_in record_out record_recv record_send 0 0 0 +4294967175 role_table_grants record_in record_out record_recv record_send 0 0 0 +4294967176 role_routine_grants record_in record_out record_recv record_send 0 0 0 +4294967177 role_column_grants record_in record_out record_recv record_send 0 0 0 +4294967178 resource_groups record_in record_out record_recv record_send 0 0 0 +4294967179 referential_constraints record_in record_out record_recv record_send 0 0 0 +4294967180 profiling record_in record_out record_recv record_send 0 0 0 +4294967181 processlist record_in record_out record_recv record_send 0 0 0 +4294967182 plugins record_in record_out record_recv record_send 0 0 0 +4294967183 partitions record_in record_out record_recv record_send 0 0 0 +4294967184 parameters record_in record_out record_recv record_send 0 0 0 +4294967185 optimizer_trace record_in record_out record_recv record_send 0 0 0 +4294967186 keywords record_in record_out record_recv record_send 0 0 0 +4294967187 key_column_usage record_in record_out record_recv record_send 0 0 0 +4294967188 information_schema_catalog_name record_in record_out record_recv record_send 0 0 0 +4294967189 foreign_tables record_in record_out record_recv record_send 0 0 0 +4294967190 foreign_table_options record_in record_out record_recv record_send 0 0 0 +4294967191 foreign_servers record_in record_out record_recv record_send 0 0 0 +4294967192 foreign_server_options record_in record_out record_recv record_send 0 0 0 +4294967193 foreign_data_wrappers record_in record_out record_recv record_send 0 0 0 +4294967194 foreign_data_wrapper_options record_in record_out record_recv record_send 0 0 0 +4294967195 files record_in record_out record_recv record_send 0 0 0 +4294967196 events record_in record_out record_recv record_send 0 0 0 +4294967197 engines record_in record_out record_recv record_send 0 0 0 +4294967198 enabled_roles record_in record_out record_recv record_send 0 0 0 +4294967199 element_types record_in record_out record_recv record_send 0 0 0 +4294967200 domains record_in record_out record_recv record_send 0 0 0 +4294967201 domain_udt_usage record_in record_out record_recv record_send 0 0 0 +4294967202 domain_constraints record_in record_out record_recv record_send 0 0 0 +4294967203 data_type_privileges record_in record_out record_recv record_send 0 0 0 +4294967204 constraint_table_usage record_in record_out record_recv record_send 0 0 0 +4294967205 constraint_column_usage record_in record_out record_recv record_send 0 0 0 +4294967206 columns record_in record_out record_recv record_send 0 0 0 +4294967207 columns_extensions record_in record_out record_recv record_send 0 0 0 +4294967208 column_udt_usage record_in record_out record_recv record_send 0 0 0 +4294967209 column_statistics record_in record_out record_recv record_send 0 0 0 +4294967210 column_privileges record_in record_out record_recv record_send 0 0 0 +4294967211 column_options record_in record_out record_recv record_send 0 0 0 +4294967212 column_domain_usage record_in record_out record_recv record_send 0 0 0 +4294967213 column_column_usage record_in record_out record_recv record_send 0 0 0 +4294967214 collations record_in record_out record_recv record_send 0 0 0 +4294967215 collation_character_set_applicability record_in record_out record_recv record_send 0 0 0 +4294967216 check_constraints record_in record_out record_recv record_send 0 0 0 +4294967217 check_constraint_routine_usage record_in record_out record_recv record_send 0 0 0 +4294967218 character_sets record_in record_out record_recv record_send 0 0 0 +4294967219 attributes record_in record_out record_recv record_send 0 0 0 +4294967220 applicable_roles record_in record_out record_recv record_send 0 0 0 +4294967221 administrable_role_authorizations record_in record_out record_recv record_send 0 0 0 +4294967223 super_regions record_in record_out record_recv record_send 0 0 0 +4294967224 pg_catalog_table_is_implemented record_in record_out record_recv record_send 0 0 0 +4294967225 tenant_usage_details record_in record_out record_recv record_send 0 0 0 +4294967226 active_range_feeds record_in record_out record_recv record_send 0 0 0 +4294967227 default_privileges record_in record_out record_recv record_send 0 0 0 +4294967228 regions record_in record_out record_recv record_send 0 0 0 +4294967229 cluster_inflight_traces record_in record_out record_recv record_send 0 0 0 +4294967230 lost_descriptors_with_data record_in record_out record_recv record_send 0 0 0 +4294967231 cross_db_references record_in record_out record_recv record_send 0 0 0 +4294967232 cluster_database_privileges record_in record_out record_recv record_send 0 0 0 +4294967233 invalid_objects record_in record_out record_recv record_send 0 0 0 +4294967234 zones record_in record_out record_recv record_send 0 0 0 +4294967235 transaction_statistics record_in record_out record_recv record_send 0 0 0 +4294967236 node_transaction_statistics record_in record_out record_recv record_send 0 0 0 +4294967237 table_row_statistics record_in record_out record_recv record_send 0 0 0 +4294967238 tables record_in record_out record_recv record_send 0 0 0 +4294967239 table_indexes record_in record_out record_recv record_send 0 0 0 +4294967240 table_columns record_in record_out record_recv record_send 0 0 0 +4294967241 statement_statistics record_in record_out record_recv record_send 0 0 0 +4294967242 session_variables record_in record_out record_recv record_send 0 0 0 +4294967243 session_trace record_in record_out record_recv record_send 0 0 0 +4294967244 schema_changes record_in record_out record_recv record_send 0 0 0 +4294967245 node_runtime_info record_in record_out record_recv record_send 0 0 0 +4294967246 ranges record_in record_out record_recv record_send 0 0 0 +4294967247 ranges_no_leases record_in record_out record_recv record_send 0 0 0 +4294967248 predefined_comments record_in record_out record_recv record_send 0 0 0 +4294967249 partitions record_in record_out record_recv record_send 0 0 0 +4294967250 node_txn_stats record_in record_out record_recv record_send 0 0 0 +4294967251 node_statement_statistics record_in record_out record_recv record_send 0 0 0 +4294967252 node_metrics record_in record_out record_recv record_send 0 0 0 +4294967253 node_sessions record_in record_out record_recv record_send 0 0 0 +4294967254 node_transactions record_in record_out record_recv record_send 0 0 0 +4294967255 node_queries record_in record_out record_recv record_send 0 0 0 +4294967256 node_execution_insights record_in record_out record_recv record_send 0 0 0 +4294967257 node_distsql_flows record_in record_out record_recv record_send 0 0 0 +4294967258 node_contention_events record_in record_out record_recv record_send 0 0 0 +4294967259 leases record_in record_out record_recv record_send 0 0 0 +4294967260 kv_store_status record_in record_out record_recv record_send 0 0 0 +4294967261 kv_node_status record_in record_out record_recv record_send 0 0 0 +4294967262 jobs record_in record_out record_recv record_send 0 0 0 +4294967263 node_inflight_trace_spans record_in record_out record_recv record_send 0 0 0 +4294967264 index_usage_statistics record_in record_out record_recv record_send 0 0 0 +4294967265 index_columns record_in record_out record_recv record_send 0 0 0 +4294967266 transaction_contention_events record_in record_out record_recv record_send 0 0 0 +4294967267 gossip_network record_in record_out record_recv record_send 0 0 0 +4294967268 gossip_liveness record_in record_out record_recv record_send 0 0 0 +4294967269 gossip_alerts record_in record_out record_recv record_send 0 0 0 +4294967270 gossip_nodes record_in record_out record_recv record_send 0 0 0 +4294967271 kv_node_liveness record_in record_out record_recv record_send 0 0 0 +4294967272 forward_dependencies record_in record_out record_recv record_send 0 0 0 +4294967273 feature_usage record_in record_out record_recv record_send 0 0 0 +4294967274 databases record_in record_out record_recv record_send 0 0 0 +4294967275 create_type_statements record_in record_out record_recv record_send 0 0 0 +4294967276 create_statements record_in record_out record_recv record_send 0 0 0 +4294967277 create_schema_statements record_in record_out record_recv record_send 0 0 0 +4294967278 create_function_statements record_in record_out record_recv record_send 0 0 0 +4294967279 cluster_transaction_statistics record_in record_out record_recv record_send 0 0 0 +4294967280 cluster_statement_statistics record_in record_out record_recv record_send 0 0 0 +4294967281 cluster_settings record_in record_out record_recv record_send 0 0 0 +4294967282 cluster_sessions record_in record_out record_recv record_send 0 0 0 +4294967283 cluster_transactions record_in record_out record_recv record_send 0 0 0 +4294967284 cluster_queries record_in record_out record_recv record_send 0 0 0 +4294967285 cluster_locks record_in record_out record_recv record_send 0 0 0 +4294967286 cluster_execution_insights record_in record_out record_recv record_send 0 0 0 4294967287 cluster_distsql_flows record_in record_out record_recv record_send 0 0 0 4294967288 cluster_contention_events record_in record_out record_recv record_send 0 0 0 4294967289 cluster_contended_tables record_in record_out record_recv record_send 0 0 0 @@ -2876,287 +2879,288 @@ oid typname typalign typstorage typnotn 100132 _newtype1 NULL NULL false 0 -1 100133 newtype2 NULL NULL false 0 -1 100134 _newtype2 NULL NULL false 0 -1 -4294967003 spatial_ref_sys NULL NULL false 0 -1 -4294967004 geometry_columns NULL NULL false 0 -1 -4294967005 geography_columns NULL NULL false 0 -1 -4294967007 pg_views NULL NULL false 0 -1 -4294967008 pg_user NULL NULL false 0 -1 -4294967009 pg_user_mappings NULL NULL false 0 -1 -4294967010 pg_user_mapping NULL NULL false 0 -1 -4294967011 pg_type NULL NULL false 0 -1 -4294967012 pg_ts_template NULL NULL false 0 -1 -4294967013 pg_ts_parser NULL NULL false 0 -1 -4294967014 pg_ts_dict NULL NULL false 0 -1 -4294967015 pg_ts_config NULL NULL false 0 -1 -4294967016 pg_ts_config_map NULL NULL false 0 -1 -4294967017 pg_trigger NULL NULL false 0 -1 -4294967018 pg_transform NULL NULL false 0 -1 -4294967019 pg_timezone_names NULL NULL false 0 -1 -4294967020 pg_timezone_abbrevs NULL NULL false 0 -1 -4294967021 pg_tablespace NULL NULL false 0 -1 -4294967022 pg_tables NULL NULL false 0 -1 -4294967023 pg_subscription NULL NULL false 0 -1 -4294967024 pg_subscription_rel NULL NULL false 0 -1 -4294967025 pg_stats NULL NULL false 0 -1 -4294967026 pg_stats_ext NULL NULL false 0 -1 -4294967027 pg_statistic NULL NULL false 0 -1 -4294967028 pg_statistic_ext NULL NULL false 0 -1 -4294967029 pg_statistic_ext_data NULL NULL false 0 -1 -4294967030 pg_statio_user_tables NULL NULL false 0 -1 -4294967031 pg_statio_user_sequences NULL NULL false 0 -1 -4294967032 pg_statio_user_indexes NULL NULL false 0 -1 -4294967033 pg_statio_sys_tables NULL NULL false 0 -1 -4294967034 pg_statio_sys_sequences NULL NULL false 0 -1 -4294967035 pg_statio_sys_indexes NULL NULL false 0 -1 -4294967036 pg_statio_all_tables NULL NULL false 0 -1 -4294967037 pg_statio_all_sequences NULL NULL false 0 -1 -4294967038 pg_statio_all_indexes NULL NULL false 0 -1 -4294967039 pg_stat_xact_user_tables NULL NULL false 0 -1 -4294967040 pg_stat_xact_user_functions NULL NULL false 0 -1 -4294967041 pg_stat_xact_sys_tables NULL NULL false 0 -1 -4294967042 pg_stat_xact_all_tables NULL NULL false 0 -1 -4294967043 pg_stat_wal_receiver NULL NULL false 0 -1 -4294967044 pg_stat_user_tables NULL NULL false 0 -1 -4294967045 pg_stat_user_indexes NULL NULL false 0 -1 -4294967046 pg_stat_user_functions NULL NULL false 0 -1 -4294967047 pg_stat_sys_tables NULL NULL false 0 -1 -4294967048 pg_stat_sys_indexes NULL NULL false 0 -1 -4294967049 pg_stat_subscription NULL NULL false 0 -1 -4294967050 pg_stat_ssl NULL NULL false 0 -1 -4294967051 pg_stat_slru NULL NULL false 0 -1 -4294967052 pg_stat_replication NULL NULL false 0 -1 -4294967053 pg_stat_progress_vacuum NULL NULL false 0 -1 -4294967054 pg_stat_progress_create_index NULL NULL false 0 -1 -4294967055 pg_stat_progress_cluster NULL NULL false 0 -1 -4294967056 pg_stat_progress_basebackup NULL NULL false 0 -1 -4294967057 pg_stat_progress_analyze NULL NULL false 0 -1 -4294967058 pg_stat_gssapi NULL NULL false 0 -1 -4294967059 pg_stat_database NULL NULL false 0 -1 -4294967060 pg_stat_database_conflicts NULL NULL false 0 -1 -4294967061 pg_stat_bgwriter NULL NULL false 0 -1 -4294967062 pg_stat_archiver NULL NULL false 0 -1 -4294967063 pg_stat_all_tables NULL NULL false 0 -1 -4294967064 pg_stat_all_indexes NULL NULL false 0 -1 -4294967065 pg_stat_activity NULL NULL false 0 -1 -4294967066 pg_shmem_allocations NULL NULL false 0 -1 -4294967067 pg_shdepend NULL NULL false 0 -1 -4294967068 pg_shseclabel NULL NULL false 0 -1 -4294967069 pg_shdescription NULL NULL false 0 -1 -4294967070 pg_shadow NULL NULL false 0 -1 -4294967071 pg_settings NULL NULL false 0 -1 -4294967072 pg_sequences NULL NULL false 0 -1 -4294967073 pg_sequence NULL NULL false 0 -1 -4294967074 pg_seclabel NULL NULL false 0 -1 -4294967075 pg_seclabels NULL NULL false 0 -1 -4294967076 pg_rules NULL NULL false 0 -1 -4294967077 pg_roles NULL NULL false 0 -1 -4294967078 pg_rewrite NULL NULL false 0 -1 -4294967079 pg_replication_slots NULL NULL false 0 -1 -4294967080 pg_replication_origin NULL NULL false 0 -1 -4294967081 pg_replication_origin_status NULL NULL false 0 -1 -4294967082 pg_range NULL NULL false 0 -1 -4294967083 pg_publication_tables NULL NULL false 0 -1 -4294967084 pg_publication NULL NULL false 0 -1 -4294967085 pg_publication_rel NULL NULL false 0 -1 -4294967086 pg_proc NULL NULL false 0 -1 -4294967087 pg_prepared_xacts NULL NULL false 0 -1 -4294967088 pg_prepared_statements NULL NULL false 0 -1 -4294967089 pg_policy NULL NULL false 0 -1 -4294967090 pg_policies NULL NULL false 0 -1 -4294967091 pg_partitioned_table NULL NULL false 0 -1 -4294967092 pg_opfamily NULL NULL false 0 -1 -4294967093 pg_operator NULL NULL false 0 -1 -4294967094 pg_opclass NULL NULL false 0 -1 -4294967095 pg_namespace NULL NULL false 0 -1 -4294967096 pg_matviews NULL NULL false 0 -1 -4294967097 pg_locks NULL NULL false 0 -1 -4294967098 pg_largeobject NULL NULL false 0 -1 -4294967099 pg_largeobject_metadata NULL NULL false 0 -1 -4294967100 pg_language NULL NULL false 0 -1 -4294967101 pg_init_privs NULL NULL false 0 -1 -4294967102 pg_inherits NULL NULL false 0 -1 -4294967103 pg_indexes NULL NULL false 0 -1 -4294967104 pg_index NULL NULL false 0 -1 -4294967105 pg_hba_file_rules NULL NULL false 0 -1 -4294967106 pg_group NULL NULL false 0 -1 -4294967107 pg_foreign_table NULL NULL false 0 -1 -4294967108 pg_foreign_server NULL NULL false 0 -1 -4294967109 pg_foreign_data_wrapper NULL NULL false 0 -1 -4294967110 pg_file_settings NULL NULL false 0 -1 -4294967111 pg_extension NULL NULL false 0 -1 -4294967112 pg_event_trigger NULL NULL false 0 -1 -4294967113 pg_enum NULL NULL false 0 -1 -4294967114 pg_description NULL NULL false 0 -1 -4294967115 pg_depend NULL NULL false 0 -1 -4294967116 pg_default_acl NULL NULL false 0 -1 -4294967117 pg_db_role_setting NULL NULL false 0 -1 -4294967118 pg_database NULL NULL false 0 -1 -4294967119 pg_cursors NULL NULL false 0 -1 -4294967120 pg_conversion NULL NULL false 0 -1 -4294967121 pg_constraint NULL NULL false 0 -1 -4294967122 pg_config NULL NULL false 0 -1 -4294967123 pg_collation NULL NULL false 0 -1 -4294967124 pg_class NULL NULL false 0 -1 -4294967125 pg_cast NULL NULL false 0 -1 -4294967126 pg_available_extensions NULL NULL false 0 -1 -4294967127 pg_available_extension_versions NULL NULL false 0 -1 -4294967128 pg_auth_members NULL NULL false 0 -1 -4294967129 pg_authid NULL NULL false 0 -1 -4294967130 pg_attribute NULL NULL false 0 -1 -4294967131 pg_attrdef NULL NULL false 0 -1 -4294967132 pg_amproc NULL NULL false 0 -1 -4294967133 pg_amop NULL NULL false 0 -1 -4294967134 pg_am NULL NULL false 0 -1 -4294967135 pg_aggregate NULL NULL false 0 -1 -4294967137 views NULL NULL false 0 -1 -4294967138 view_table_usage NULL NULL false 0 -1 -4294967139 view_routine_usage NULL NULL false 0 -1 -4294967140 view_column_usage NULL NULL false 0 -1 -4294967141 user_privileges NULL NULL false 0 -1 -4294967142 user_mappings NULL NULL false 0 -1 -4294967143 user_mapping_options NULL NULL false 0 -1 -4294967144 user_defined_types NULL NULL false 0 -1 -4294967145 user_attributes NULL NULL false 0 -1 -4294967146 usage_privileges NULL NULL false 0 -1 -4294967147 udt_privileges NULL NULL false 0 -1 -4294967148 type_privileges NULL NULL false 0 -1 -4294967149 triggers NULL NULL false 0 -1 -4294967150 triggered_update_columns NULL NULL false 0 -1 -4294967151 transforms NULL NULL false 0 -1 -4294967152 tablespaces NULL NULL false 0 -1 -4294967153 tablespaces_extensions NULL NULL false 0 -1 -4294967154 tables NULL NULL false 0 -1 -4294967155 tables_extensions NULL NULL false 0 -1 -4294967156 table_privileges NULL NULL false 0 -1 -4294967157 table_constraints_extensions NULL NULL false 0 -1 -4294967158 table_constraints NULL NULL false 0 -1 -4294967159 statistics NULL NULL false 0 -1 -4294967160 st_units_of_measure NULL NULL false 0 -1 -4294967161 st_spatial_reference_systems NULL NULL false 0 -1 -4294967162 st_geometry_columns NULL NULL false 0 -1 -4294967163 session_variables NULL NULL false 0 -1 -4294967164 sequences NULL NULL false 0 -1 -4294967165 schema_privileges NULL NULL false 0 -1 -4294967166 schemata NULL NULL false 0 -1 -4294967167 schemata_extensions NULL NULL false 0 -1 -4294967168 sql_sizing NULL NULL false 0 -1 -4294967169 sql_parts NULL NULL false 0 -1 -4294967170 sql_implementation_info NULL NULL false 0 -1 -4294967171 sql_features NULL NULL false 0 -1 -4294967172 routines NULL NULL false 0 -1 -4294967173 routine_privileges NULL NULL false 0 -1 -4294967174 role_usage_grants NULL NULL false 0 -1 -4294967175 role_udt_grants NULL NULL false 0 -1 -4294967176 role_table_grants NULL NULL false 0 -1 -4294967177 role_routine_grants NULL NULL false 0 -1 -4294967178 role_column_grants NULL NULL false 0 -1 -4294967179 resource_groups NULL NULL false 0 -1 -4294967180 referential_constraints NULL NULL false 0 -1 -4294967181 profiling NULL NULL false 0 -1 -4294967182 processlist NULL NULL false 0 -1 -4294967183 plugins NULL NULL false 0 -1 -4294967184 partitions NULL NULL false 0 -1 -4294967185 parameters NULL NULL false 0 -1 -4294967186 optimizer_trace NULL NULL false 0 -1 -4294967187 keywords NULL NULL false 0 -1 -4294967188 key_column_usage NULL NULL false 0 -1 -4294967189 information_schema_catalog_name NULL NULL false 0 -1 -4294967190 foreign_tables NULL NULL false 0 -1 -4294967191 foreign_table_options NULL NULL false 0 -1 -4294967192 foreign_servers NULL NULL false 0 -1 -4294967193 foreign_server_options NULL NULL false 0 -1 -4294967194 foreign_data_wrappers NULL NULL false 0 -1 -4294967195 foreign_data_wrapper_options NULL NULL false 0 -1 -4294967196 files NULL NULL false 0 -1 -4294967197 events NULL NULL false 0 -1 -4294967198 engines NULL NULL false 0 -1 -4294967199 enabled_roles NULL NULL false 0 -1 -4294967200 element_types NULL NULL false 0 -1 -4294967201 domains NULL NULL false 0 -1 -4294967202 domain_udt_usage NULL NULL false 0 -1 -4294967203 domain_constraints NULL NULL false 0 -1 -4294967204 data_type_privileges NULL NULL false 0 -1 -4294967205 constraint_table_usage NULL NULL false 0 -1 -4294967206 constraint_column_usage NULL NULL false 0 -1 -4294967207 columns NULL NULL false 0 -1 -4294967208 columns_extensions NULL NULL false 0 -1 -4294967209 column_udt_usage NULL NULL false 0 -1 -4294967210 column_statistics NULL NULL false 0 -1 -4294967211 column_privileges NULL NULL false 0 -1 -4294967212 column_options NULL NULL false 0 -1 -4294967213 column_domain_usage NULL NULL false 0 -1 -4294967214 column_column_usage NULL NULL false 0 -1 -4294967215 collations NULL NULL false 0 -1 -4294967216 collation_character_set_applicability NULL NULL false 0 -1 -4294967217 check_constraints NULL NULL false 0 -1 -4294967218 check_constraint_routine_usage NULL NULL false 0 -1 -4294967219 character_sets NULL NULL false 0 -1 -4294967220 attributes NULL NULL false 0 -1 -4294967221 applicable_roles NULL NULL false 0 -1 -4294967222 administrable_role_authorizations NULL NULL false 0 -1 -4294967224 super_regions NULL NULL false 0 -1 -4294967225 pg_catalog_table_is_implemented NULL NULL false 0 -1 -4294967226 tenant_usage_details NULL NULL false 0 -1 -4294967227 active_range_feeds NULL NULL false 0 -1 -4294967228 default_privileges NULL NULL false 0 -1 -4294967229 regions NULL NULL false 0 -1 -4294967230 cluster_inflight_traces NULL NULL false 0 -1 -4294967231 lost_descriptors_with_data NULL NULL false 0 -1 -4294967232 cross_db_references NULL NULL false 0 -1 -4294967233 cluster_database_privileges NULL NULL false 0 -1 -4294967234 invalid_objects NULL NULL false 0 -1 -4294967235 zones NULL NULL false 0 -1 -4294967236 transaction_statistics NULL NULL false 0 -1 -4294967237 node_transaction_statistics NULL NULL false 0 -1 -4294967238 table_row_statistics NULL NULL false 0 -1 -4294967239 tables NULL NULL false 0 -1 -4294967240 table_indexes NULL NULL false 0 -1 -4294967241 table_columns NULL NULL false 0 -1 -4294967242 statement_statistics NULL NULL false 0 -1 -4294967243 session_variables NULL NULL false 0 -1 -4294967244 session_trace NULL NULL false 0 -1 -4294967245 schema_changes NULL NULL false 0 -1 -4294967246 node_runtime_info NULL NULL false 0 -1 -4294967247 ranges NULL NULL false 0 -1 -4294967248 ranges_no_leases NULL NULL false 0 -1 -4294967249 predefined_comments NULL NULL false 0 -1 -4294967250 partitions NULL NULL false 0 -1 -4294967251 node_txn_stats NULL NULL false 0 -1 -4294967252 node_statement_statistics NULL NULL false 0 -1 -4294967253 node_metrics NULL NULL false 0 -1 -4294967254 node_sessions NULL NULL false 0 -1 -4294967255 node_transactions NULL NULL false 0 -1 -4294967256 node_queries NULL NULL false 0 -1 -4294967257 node_execution_insights NULL NULL false 0 -1 -4294967258 node_distsql_flows NULL NULL false 0 -1 -4294967259 node_contention_events NULL NULL false 0 -1 -4294967260 leases NULL NULL false 0 -1 -4294967261 kv_store_status NULL NULL false 0 -1 -4294967262 kv_node_status NULL NULL false 0 -1 -4294967263 jobs NULL NULL false 0 -1 -4294967264 node_inflight_trace_spans NULL NULL false 0 -1 -4294967265 index_usage_statistics NULL NULL false 0 -1 -4294967266 index_columns NULL NULL false 0 -1 -4294967267 transaction_contention_events NULL NULL false 0 -1 -4294967268 gossip_network NULL NULL false 0 -1 -4294967269 gossip_liveness NULL NULL false 0 -1 -4294967270 gossip_alerts NULL NULL false 0 -1 -4294967271 gossip_nodes NULL NULL false 0 -1 -4294967272 kv_node_liveness NULL NULL false 0 -1 -4294967273 forward_dependencies NULL NULL false 0 -1 -4294967274 feature_usage NULL NULL false 0 -1 -4294967275 databases NULL NULL false 0 -1 -4294967276 create_type_statements NULL NULL false 0 -1 -4294967277 create_statements NULL NULL false 0 -1 -4294967278 create_schema_statements NULL NULL false 0 -1 -4294967279 create_function_statements NULL NULL false 0 -1 -4294967280 cluster_transaction_statistics NULL NULL false 0 -1 -4294967281 cluster_statement_statistics NULL NULL false 0 -1 -4294967282 cluster_settings NULL NULL false 0 -1 -4294967283 cluster_sessions NULL NULL false 0 -1 -4294967284 cluster_transactions NULL NULL false 0 -1 -4294967285 cluster_queries NULL NULL false 0 -1 -4294967286 cluster_locks NULL NULL false 0 -1 +4294967002 spatial_ref_sys NULL NULL false 0 -1 +4294967003 geometry_columns NULL NULL false 0 -1 +4294967004 geography_columns NULL NULL false 0 -1 +4294967006 pg_views NULL NULL false 0 -1 +4294967007 pg_user NULL NULL false 0 -1 +4294967008 pg_user_mappings NULL NULL false 0 -1 +4294967009 pg_user_mapping NULL NULL false 0 -1 +4294967010 pg_type NULL NULL false 0 -1 +4294967011 pg_ts_template NULL NULL false 0 -1 +4294967012 pg_ts_parser NULL NULL false 0 -1 +4294967013 pg_ts_dict NULL NULL false 0 -1 +4294967014 pg_ts_config NULL NULL false 0 -1 +4294967015 pg_ts_config_map NULL NULL false 0 -1 +4294967016 pg_trigger NULL NULL false 0 -1 +4294967017 pg_transform NULL NULL false 0 -1 +4294967018 pg_timezone_names NULL NULL false 0 -1 +4294967019 pg_timezone_abbrevs NULL NULL false 0 -1 +4294967020 pg_tablespace NULL NULL false 0 -1 +4294967021 pg_tables NULL NULL false 0 -1 +4294967022 pg_subscription NULL NULL false 0 -1 +4294967023 pg_subscription_rel NULL NULL false 0 -1 +4294967024 pg_stats NULL NULL false 0 -1 +4294967025 pg_stats_ext NULL NULL false 0 -1 +4294967026 pg_statistic NULL NULL false 0 -1 +4294967027 pg_statistic_ext NULL NULL false 0 -1 +4294967028 pg_statistic_ext_data NULL NULL false 0 -1 +4294967029 pg_statio_user_tables NULL NULL false 0 -1 +4294967030 pg_statio_user_sequences NULL NULL false 0 -1 +4294967031 pg_statio_user_indexes NULL NULL false 0 -1 +4294967032 pg_statio_sys_tables NULL NULL false 0 -1 +4294967033 pg_statio_sys_sequences NULL NULL false 0 -1 +4294967034 pg_statio_sys_indexes NULL NULL false 0 -1 +4294967035 pg_statio_all_tables NULL NULL false 0 -1 +4294967036 pg_statio_all_sequences NULL NULL false 0 -1 +4294967037 pg_statio_all_indexes NULL NULL false 0 -1 +4294967038 pg_stat_xact_user_tables NULL NULL false 0 -1 +4294967039 pg_stat_xact_user_functions NULL NULL false 0 -1 +4294967040 pg_stat_xact_sys_tables NULL NULL false 0 -1 +4294967041 pg_stat_xact_all_tables NULL NULL false 0 -1 +4294967042 pg_stat_wal_receiver NULL NULL false 0 -1 +4294967043 pg_stat_user_tables NULL NULL false 0 -1 +4294967044 pg_stat_user_indexes NULL NULL false 0 -1 +4294967045 pg_stat_user_functions NULL NULL false 0 -1 +4294967046 pg_stat_sys_tables NULL NULL false 0 -1 +4294967047 pg_stat_sys_indexes NULL NULL false 0 -1 +4294967048 pg_stat_subscription NULL NULL false 0 -1 +4294967049 pg_stat_ssl NULL NULL false 0 -1 +4294967050 pg_stat_slru NULL NULL false 0 -1 +4294967051 pg_stat_replication NULL NULL false 0 -1 +4294967052 pg_stat_progress_vacuum NULL NULL false 0 -1 +4294967053 pg_stat_progress_create_index NULL NULL false 0 -1 +4294967054 pg_stat_progress_cluster NULL NULL false 0 -1 +4294967055 pg_stat_progress_basebackup NULL NULL false 0 -1 +4294967056 pg_stat_progress_analyze NULL NULL false 0 -1 +4294967057 pg_stat_gssapi NULL NULL false 0 -1 +4294967058 pg_stat_database NULL NULL false 0 -1 +4294967059 pg_stat_database_conflicts NULL NULL false 0 -1 +4294967060 pg_stat_bgwriter NULL NULL false 0 -1 +4294967061 pg_stat_archiver NULL NULL false 0 -1 +4294967062 pg_stat_all_tables NULL NULL false 0 -1 +4294967063 pg_stat_all_indexes NULL NULL false 0 -1 +4294967064 pg_stat_activity NULL NULL false 0 -1 +4294967065 pg_shmem_allocations NULL NULL false 0 -1 +4294967066 pg_shdepend NULL NULL false 0 -1 +4294967067 pg_shseclabel NULL NULL false 0 -1 +4294967068 pg_shdescription NULL NULL false 0 -1 +4294967069 pg_shadow NULL NULL false 0 -1 +4294967070 pg_settings NULL NULL false 0 -1 +4294967071 pg_sequences NULL NULL false 0 -1 +4294967072 pg_sequence NULL NULL false 0 -1 +4294967073 pg_seclabel NULL NULL false 0 -1 +4294967074 pg_seclabels NULL NULL false 0 -1 +4294967075 pg_rules NULL NULL false 0 -1 +4294967076 pg_roles NULL NULL false 0 -1 +4294967077 pg_rewrite NULL NULL false 0 -1 +4294967078 pg_replication_slots NULL NULL false 0 -1 +4294967079 pg_replication_origin NULL NULL false 0 -1 +4294967080 pg_replication_origin_status NULL NULL false 0 -1 +4294967081 pg_range NULL NULL false 0 -1 +4294967082 pg_publication_tables NULL NULL false 0 -1 +4294967083 pg_publication NULL NULL false 0 -1 +4294967084 pg_publication_rel NULL NULL false 0 -1 +4294967085 pg_proc NULL NULL false 0 -1 +4294967086 pg_prepared_xacts NULL NULL false 0 -1 +4294967087 pg_prepared_statements NULL NULL false 0 -1 +4294967088 pg_policy NULL NULL false 0 -1 +4294967089 pg_policies NULL NULL false 0 -1 +4294967090 pg_partitioned_table NULL NULL false 0 -1 +4294967091 pg_opfamily NULL NULL false 0 -1 +4294967092 pg_operator NULL NULL false 0 -1 +4294967093 pg_opclass NULL NULL false 0 -1 +4294967094 pg_namespace NULL NULL false 0 -1 +4294967095 pg_matviews NULL NULL false 0 -1 +4294967096 pg_locks NULL NULL false 0 -1 +4294967097 pg_largeobject NULL NULL false 0 -1 +4294967098 pg_largeobject_metadata NULL NULL false 0 -1 +4294967099 pg_language NULL NULL false 0 -1 +4294967100 pg_init_privs NULL NULL false 0 -1 +4294967101 pg_inherits NULL NULL false 0 -1 +4294967102 pg_indexes NULL NULL false 0 -1 +4294967103 pg_index NULL NULL false 0 -1 +4294967104 pg_hba_file_rules NULL NULL false 0 -1 +4294967105 pg_group NULL NULL false 0 -1 +4294967106 pg_foreign_table NULL NULL false 0 -1 +4294967107 pg_foreign_server NULL NULL false 0 -1 +4294967108 pg_foreign_data_wrapper NULL NULL false 0 -1 +4294967109 pg_file_settings NULL NULL false 0 -1 +4294967110 pg_extension NULL NULL false 0 -1 +4294967111 pg_event_trigger NULL NULL false 0 -1 +4294967112 pg_enum NULL NULL false 0 -1 +4294967113 pg_description NULL NULL false 0 -1 +4294967114 pg_depend NULL NULL false 0 -1 +4294967115 pg_default_acl NULL NULL false 0 -1 +4294967116 pg_db_role_setting NULL NULL false 0 -1 +4294967117 pg_database NULL NULL false 0 -1 +4294967118 pg_cursors NULL NULL false 0 -1 +4294967119 pg_conversion NULL NULL false 0 -1 +4294967120 pg_constraint NULL NULL false 0 -1 +4294967121 pg_config NULL NULL false 0 -1 +4294967122 pg_collation NULL NULL false 0 -1 +4294967123 pg_class NULL NULL false 0 -1 +4294967124 pg_cast NULL NULL false 0 -1 +4294967125 pg_available_extensions NULL NULL false 0 -1 +4294967126 pg_available_extension_versions NULL NULL false 0 -1 +4294967127 pg_auth_members NULL NULL false 0 -1 +4294967128 pg_authid NULL NULL false 0 -1 +4294967129 pg_attribute NULL NULL false 0 -1 +4294967130 pg_attrdef NULL NULL false 0 -1 +4294967131 pg_amproc NULL NULL false 0 -1 +4294967132 pg_amop NULL NULL false 0 -1 +4294967133 pg_am NULL NULL false 0 -1 +4294967134 pg_aggregate NULL NULL false 0 -1 +4294967136 views NULL NULL false 0 -1 +4294967137 view_table_usage NULL NULL false 0 -1 +4294967138 view_routine_usage NULL NULL false 0 -1 +4294967139 view_column_usage NULL NULL false 0 -1 +4294967140 user_privileges NULL NULL false 0 -1 +4294967141 user_mappings NULL NULL false 0 -1 +4294967142 user_mapping_options NULL NULL false 0 -1 +4294967143 user_defined_types NULL NULL false 0 -1 +4294967144 user_attributes NULL NULL false 0 -1 +4294967145 usage_privileges NULL NULL false 0 -1 +4294967146 udt_privileges NULL NULL false 0 -1 +4294967147 type_privileges NULL NULL false 0 -1 +4294967148 triggers NULL NULL false 0 -1 +4294967149 triggered_update_columns NULL NULL false 0 -1 +4294967150 transforms NULL NULL false 0 -1 +4294967151 tablespaces NULL NULL false 0 -1 +4294967152 tablespaces_extensions NULL NULL false 0 -1 +4294967153 tables NULL NULL false 0 -1 +4294967154 tables_extensions NULL NULL false 0 -1 +4294967155 table_privileges NULL NULL false 0 -1 +4294967156 table_constraints_extensions NULL NULL false 0 -1 +4294967157 table_constraints NULL NULL false 0 -1 +4294967158 statistics NULL NULL false 0 -1 +4294967159 st_units_of_measure NULL NULL false 0 -1 +4294967160 st_spatial_reference_systems NULL NULL false 0 -1 +4294967161 st_geometry_columns NULL NULL false 0 -1 +4294967162 session_variables NULL NULL false 0 -1 +4294967163 sequences NULL NULL false 0 -1 +4294967164 schema_privileges NULL NULL false 0 -1 +4294967165 schemata NULL NULL false 0 -1 +4294967166 schemata_extensions NULL NULL false 0 -1 +4294967167 sql_sizing NULL NULL false 0 -1 +4294967168 sql_parts NULL NULL false 0 -1 +4294967169 sql_implementation_info NULL NULL false 0 -1 +4294967170 sql_features NULL NULL false 0 -1 +4294967171 routines NULL NULL false 0 -1 +4294967172 routine_privileges NULL NULL false 0 -1 +4294967173 role_usage_grants NULL NULL false 0 -1 +4294967174 role_udt_grants NULL NULL false 0 -1 +4294967175 role_table_grants NULL NULL false 0 -1 +4294967176 role_routine_grants NULL NULL false 0 -1 +4294967177 role_column_grants NULL NULL false 0 -1 +4294967178 resource_groups NULL NULL false 0 -1 +4294967179 referential_constraints NULL NULL false 0 -1 +4294967180 profiling NULL NULL false 0 -1 +4294967181 processlist NULL NULL false 0 -1 +4294967182 plugins NULL NULL false 0 -1 +4294967183 partitions NULL NULL false 0 -1 +4294967184 parameters NULL NULL false 0 -1 +4294967185 optimizer_trace NULL NULL false 0 -1 +4294967186 keywords NULL NULL false 0 -1 +4294967187 key_column_usage NULL NULL false 0 -1 +4294967188 information_schema_catalog_name NULL NULL false 0 -1 +4294967189 foreign_tables NULL NULL false 0 -1 +4294967190 foreign_table_options NULL NULL false 0 -1 +4294967191 foreign_servers NULL NULL false 0 -1 +4294967192 foreign_server_options NULL NULL false 0 -1 +4294967193 foreign_data_wrappers NULL NULL false 0 -1 +4294967194 foreign_data_wrapper_options NULL NULL false 0 -1 +4294967195 files NULL NULL false 0 -1 +4294967196 events NULL NULL false 0 -1 +4294967197 engines NULL NULL false 0 -1 +4294967198 enabled_roles NULL NULL false 0 -1 +4294967199 element_types NULL NULL false 0 -1 +4294967200 domains NULL NULL false 0 -1 +4294967201 domain_udt_usage NULL NULL false 0 -1 +4294967202 domain_constraints NULL NULL false 0 -1 +4294967203 data_type_privileges NULL NULL false 0 -1 +4294967204 constraint_table_usage NULL NULL false 0 -1 +4294967205 constraint_column_usage NULL NULL false 0 -1 +4294967206 columns NULL NULL false 0 -1 +4294967207 columns_extensions NULL NULL false 0 -1 +4294967208 column_udt_usage NULL NULL false 0 -1 +4294967209 column_statistics NULL NULL false 0 -1 +4294967210 column_privileges NULL NULL false 0 -1 +4294967211 column_options NULL NULL false 0 -1 +4294967212 column_domain_usage NULL NULL false 0 -1 +4294967213 column_column_usage NULL NULL false 0 -1 +4294967214 collations NULL NULL false 0 -1 +4294967215 collation_character_set_applicability NULL NULL false 0 -1 +4294967216 check_constraints NULL NULL false 0 -1 +4294967217 check_constraint_routine_usage NULL NULL false 0 -1 +4294967218 character_sets NULL NULL false 0 -1 +4294967219 attributes NULL NULL false 0 -1 +4294967220 applicable_roles NULL NULL false 0 -1 +4294967221 administrable_role_authorizations NULL NULL false 0 -1 +4294967223 super_regions NULL NULL false 0 -1 +4294967224 pg_catalog_table_is_implemented NULL NULL false 0 -1 +4294967225 tenant_usage_details NULL NULL false 0 -1 +4294967226 active_range_feeds NULL NULL false 0 -1 +4294967227 default_privileges NULL NULL false 0 -1 +4294967228 regions NULL NULL false 0 -1 +4294967229 cluster_inflight_traces NULL NULL false 0 -1 +4294967230 lost_descriptors_with_data NULL NULL false 0 -1 +4294967231 cross_db_references NULL NULL false 0 -1 +4294967232 cluster_database_privileges NULL NULL false 0 -1 +4294967233 invalid_objects NULL NULL false 0 -1 +4294967234 zones NULL NULL false 0 -1 +4294967235 transaction_statistics NULL NULL false 0 -1 +4294967236 node_transaction_statistics NULL NULL false 0 -1 +4294967237 table_row_statistics NULL NULL false 0 -1 +4294967238 tables NULL NULL false 0 -1 +4294967239 table_indexes NULL NULL false 0 -1 +4294967240 table_columns NULL NULL false 0 -1 +4294967241 statement_statistics NULL NULL false 0 -1 +4294967242 session_variables NULL NULL false 0 -1 +4294967243 session_trace NULL NULL false 0 -1 +4294967244 schema_changes NULL NULL false 0 -1 +4294967245 node_runtime_info NULL NULL false 0 -1 +4294967246 ranges NULL NULL false 0 -1 +4294967247 ranges_no_leases NULL NULL false 0 -1 +4294967248 predefined_comments NULL NULL false 0 -1 +4294967249 partitions NULL NULL false 0 -1 +4294967250 node_txn_stats NULL NULL false 0 -1 +4294967251 node_statement_statistics NULL NULL false 0 -1 +4294967252 node_metrics NULL NULL false 0 -1 +4294967253 node_sessions NULL NULL false 0 -1 +4294967254 node_transactions NULL NULL false 0 -1 +4294967255 node_queries NULL NULL false 0 -1 +4294967256 node_execution_insights NULL NULL false 0 -1 +4294967257 node_distsql_flows NULL NULL false 0 -1 +4294967258 node_contention_events NULL NULL false 0 -1 +4294967259 leases NULL NULL false 0 -1 +4294967260 kv_store_status NULL NULL false 0 -1 +4294967261 kv_node_status NULL NULL false 0 -1 +4294967262 jobs NULL NULL false 0 -1 +4294967263 node_inflight_trace_spans NULL NULL false 0 -1 +4294967264 index_usage_statistics NULL NULL false 0 -1 +4294967265 index_columns NULL NULL false 0 -1 +4294967266 transaction_contention_events NULL NULL false 0 -1 +4294967267 gossip_network NULL NULL false 0 -1 +4294967268 gossip_liveness NULL NULL false 0 -1 +4294967269 gossip_alerts NULL NULL false 0 -1 +4294967270 gossip_nodes NULL NULL false 0 -1 +4294967271 kv_node_liveness NULL NULL false 0 -1 +4294967272 forward_dependencies NULL NULL false 0 -1 +4294967273 feature_usage NULL NULL false 0 -1 +4294967274 databases NULL NULL false 0 -1 +4294967275 create_type_statements NULL NULL false 0 -1 +4294967276 create_statements NULL NULL false 0 -1 +4294967277 create_schema_statements NULL NULL false 0 -1 +4294967278 create_function_statements NULL NULL false 0 -1 +4294967279 cluster_transaction_statistics NULL NULL false 0 -1 +4294967280 cluster_statement_statistics NULL NULL false 0 -1 +4294967281 cluster_settings NULL NULL false 0 -1 +4294967282 cluster_sessions NULL NULL false 0 -1 +4294967283 cluster_transactions NULL NULL false 0 -1 +4294967284 cluster_queries NULL NULL false 0 -1 +4294967285 cluster_locks NULL NULL false 0 -1 +4294967286 cluster_execution_insights NULL NULL false 0 -1 4294967287 cluster_distsql_flows NULL NULL false 0 -1 4294967288 cluster_contention_events NULL NULL false 0 -1 4294967289 cluster_contended_tables NULL NULL false 0 -1 @@ -3269,287 +3273,288 @@ oid typname typndims typcollation typde 100132 _newtype1 0 0 NULL NULL NULL 100133 newtype2 0 0 NULL NULL NULL 100134 _newtype2 0 0 NULL NULL NULL -4294967003 spatial_ref_sys 0 0 NULL NULL NULL -4294967004 geometry_columns 0 0 NULL NULL NULL -4294967005 geography_columns 0 0 NULL NULL NULL -4294967007 pg_views 0 0 NULL NULL NULL -4294967008 pg_user 0 0 NULL NULL NULL -4294967009 pg_user_mappings 0 0 NULL NULL NULL -4294967010 pg_user_mapping 0 0 NULL NULL NULL -4294967011 pg_type 0 0 NULL NULL NULL -4294967012 pg_ts_template 0 0 NULL NULL NULL -4294967013 pg_ts_parser 0 0 NULL NULL NULL -4294967014 pg_ts_dict 0 0 NULL NULL NULL -4294967015 pg_ts_config 0 0 NULL NULL NULL -4294967016 pg_ts_config_map 0 0 NULL NULL NULL -4294967017 pg_trigger 0 0 NULL NULL NULL -4294967018 pg_transform 0 0 NULL NULL NULL -4294967019 pg_timezone_names 0 0 NULL NULL NULL -4294967020 pg_timezone_abbrevs 0 0 NULL NULL NULL -4294967021 pg_tablespace 0 0 NULL NULL NULL -4294967022 pg_tables 0 0 NULL NULL NULL -4294967023 pg_subscription 0 0 NULL NULL NULL -4294967024 pg_subscription_rel 0 0 NULL NULL NULL -4294967025 pg_stats 0 0 NULL NULL NULL -4294967026 pg_stats_ext 0 0 NULL NULL NULL -4294967027 pg_statistic 0 0 NULL NULL NULL -4294967028 pg_statistic_ext 0 0 NULL NULL NULL -4294967029 pg_statistic_ext_data 0 0 NULL NULL NULL -4294967030 pg_statio_user_tables 0 0 NULL NULL NULL -4294967031 pg_statio_user_sequences 0 0 NULL NULL NULL -4294967032 pg_statio_user_indexes 0 0 NULL NULL NULL -4294967033 pg_statio_sys_tables 0 0 NULL NULL NULL -4294967034 pg_statio_sys_sequences 0 0 NULL NULL NULL -4294967035 pg_statio_sys_indexes 0 0 NULL NULL NULL -4294967036 pg_statio_all_tables 0 0 NULL NULL NULL -4294967037 pg_statio_all_sequences 0 0 NULL NULL NULL -4294967038 pg_statio_all_indexes 0 0 NULL NULL NULL -4294967039 pg_stat_xact_user_tables 0 0 NULL NULL NULL -4294967040 pg_stat_xact_user_functions 0 0 NULL NULL NULL -4294967041 pg_stat_xact_sys_tables 0 0 NULL NULL NULL -4294967042 pg_stat_xact_all_tables 0 0 NULL NULL NULL -4294967043 pg_stat_wal_receiver 0 0 NULL NULL NULL -4294967044 pg_stat_user_tables 0 0 NULL NULL NULL -4294967045 pg_stat_user_indexes 0 0 NULL NULL NULL -4294967046 pg_stat_user_functions 0 0 NULL NULL NULL -4294967047 pg_stat_sys_tables 0 0 NULL NULL NULL -4294967048 pg_stat_sys_indexes 0 0 NULL NULL NULL -4294967049 pg_stat_subscription 0 0 NULL NULL NULL -4294967050 pg_stat_ssl 0 0 NULL NULL NULL -4294967051 pg_stat_slru 0 0 NULL NULL NULL -4294967052 pg_stat_replication 0 0 NULL NULL NULL -4294967053 pg_stat_progress_vacuum 0 0 NULL NULL NULL -4294967054 pg_stat_progress_create_index 0 0 NULL NULL NULL -4294967055 pg_stat_progress_cluster 0 0 NULL NULL NULL -4294967056 pg_stat_progress_basebackup 0 0 NULL NULL NULL -4294967057 pg_stat_progress_analyze 0 0 NULL NULL NULL -4294967058 pg_stat_gssapi 0 0 NULL NULL NULL -4294967059 pg_stat_database 0 0 NULL NULL NULL -4294967060 pg_stat_database_conflicts 0 0 NULL NULL NULL -4294967061 pg_stat_bgwriter 0 0 NULL NULL NULL -4294967062 pg_stat_archiver 0 0 NULL NULL NULL -4294967063 pg_stat_all_tables 0 0 NULL NULL NULL -4294967064 pg_stat_all_indexes 0 0 NULL NULL NULL -4294967065 pg_stat_activity 0 0 NULL NULL NULL -4294967066 pg_shmem_allocations 0 0 NULL NULL NULL -4294967067 pg_shdepend 0 0 NULL NULL NULL -4294967068 pg_shseclabel 0 0 NULL NULL NULL -4294967069 pg_shdescription 0 0 NULL NULL NULL -4294967070 pg_shadow 0 0 NULL NULL NULL -4294967071 pg_settings 0 0 NULL NULL NULL -4294967072 pg_sequences 0 0 NULL NULL NULL -4294967073 pg_sequence 0 0 NULL NULL NULL -4294967074 pg_seclabel 0 0 NULL NULL NULL -4294967075 pg_seclabels 0 0 NULL NULL NULL -4294967076 pg_rules 0 0 NULL NULL NULL -4294967077 pg_roles 0 0 NULL NULL NULL -4294967078 pg_rewrite 0 0 NULL NULL NULL -4294967079 pg_replication_slots 0 0 NULL NULL NULL -4294967080 pg_replication_origin 0 0 NULL NULL NULL -4294967081 pg_replication_origin_status 0 0 NULL NULL NULL -4294967082 pg_range 0 0 NULL NULL NULL -4294967083 pg_publication_tables 0 0 NULL NULL NULL -4294967084 pg_publication 0 0 NULL NULL NULL -4294967085 pg_publication_rel 0 0 NULL NULL NULL -4294967086 pg_proc 0 0 NULL NULL NULL -4294967087 pg_prepared_xacts 0 0 NULL NULL NULL -4294967088 pg_prepared_statements 0 0 NULL NULL NULL -4294967089 pg_policy 0 0 NULL NULL NULL -4294967090 pg_policies 0 0 NULL NULL NULL -4294967091 pg_partitioned_table 0 0 NULL NULL NULL -4294967092 pg_opfamily 0 0 NULL NULL NULL -4294967093 pg_operator 0 0 NULL NULL NULL -4294967094 pg_opclass 0 0 NULL NULL NULL -4294967095 pg_namespace 0 0 NULL NULL NULL -4294967096 pg_matviews 0 0 NULL NULL NULL -4294967097 pg_locks 0 0 NULL NULL NULL -4294967098 pg_largeobject 0 0 NULL NULL NULL -4294967099 pg_largeobject_metadata 0 0 NULL NULL NULL -4294967100 pg_language 0 0 NULL NULL NULL -4294967101 pg_init_privs 0 0 NULL NULL NULL -4294967102 pg_inherits 0 0 NULL NULL NULL -4294967103 pg_indexes 0 0 NULL NULL NULL -4294967104 pg_index 0 0 NULL NULL NULL -4294967105 pg_hba_file_rules 0 0 NULL NULL NULL -4294967106 pg_group 0 0 NULL NULL NULL -4294967107 pg_foreign_table 0 0 NULL NULL NULL -4294967108 pg_foreign_server 0 0 NULL NULL NULL -4294967109 pg_foreign_data_wrapper 0 0 NULL NULL NULL -4294967110 pg_file_settings 0 0 NULL NULL NULL -4294967111 pg_extension 0 0 NULL NULL NULL -4294967112 pg_event_trigger 0 0 NULL NULL NULL -4294967113 pg_enum 0 0 NULL NULL NULL -4294967114 pg_description 0 0 NULL NULL NULL -4294967115 pg_depend 0 0 NULL NULL NULL -4294967116 pg_default_acl 0 0 NULL NULL NULL -4294967117 pg_db_role_setting 0 0 NULL NULL NULL -4294967118 pg_database 0 0 NULL NULL NULL -4294967119 pg_cursors 0 0 NULL NULL NULL -4294967120 pg_conversion 0 0 NULL NULL NULL -4294967121 pg_constraint 0 0 NULL NULL NULL -4294967122 pg_config 0 0 NULL NULL NULL -4294967123 pg_collation 0 0 NULL NULL NULL -4294967124 pg_class 0 0 NULL NULL NULL -4294967125 pg_cast 0 0 NULL NULL NULL -4294967126 pg_available_extensions 0 0 NULL NULL NULL -4294967127 pg_available_extension_versions 0 0 NULL NULL NULL -4294967128 pg_auth_members 0 0 NULL NULL NULL -4294967129 pg_authid 0 0 NULL NULL NULL -4294967130 pg_attribute 0 0 NULL NULL NULL -4294967131 pg_attrdef 0 0 NULL NULL NULL -4294967132 pg_amproc 0 0 NULL NULL NULL -4294967133 pg_amop 0 0 NULL NULL NULL -4294967134 pg_am 0 0 NULL NULL NULL -4294967135 pg_aggregate 0 0 NULL NULL NULL -4294967137 views 0 0 NULL NULL NULL -4294967138 view_table_usage 0 0 NULL NULL NULL -4294967139 view_routine_usage 0 0 NULL NULL NULL -4294967140 view_column_usage 0 0 NULL NULL NULL -4294967141 user_privileges 0 0 NULL NULL NULL -4294967142 user_mappings 0 0 NULL NULL NULL -4294967143 user_mapping_options 0 0 NULL NULL NULL -4294967144 user_defined_types 0 0 NULL NULL NULL -4294967145 user_attributes 0 0 NULL NULL NULL -4294967146 usage_privileges 0 0 NULL NULL NULL -4294967147 udt_privileges 0 0 NULL NULL NULL -4294967148 type_privileges 0 0 NULL NULL NULL -4294967149 triggers 0 0 NULL NULL NULL -4294967150 triggered_update_columns 0 0 NULL NULL NULL -4294967151 transforms 0 0 NULL NULL NULL -4294967152 tablespaces 0 0 NULL NULL NULL -4294967153 tablespaces_extensions 0 0 NULL NULL NULL -4294967154 tables 0 0 NULL NULL NULL -4294967155 tables_extensions 0 0 NULL NULL NULL -4294967156 table_privileges 0 0 NULL NULL NULL -4294967157 table_constraints_extensions 0 0 NULL NULL NULL -4294967158 table_constraints 0 0 NULL NULL NULL -4294967159 statistics 0 0 NULL NULL NULL -4294967160 st_units_of_measure 0 0 NULL NULL NULL -4294967161 st_spatial_reference_systems 0 0 NULL NULL NULL -4294967162 st_geometry_columns 0 0 NULL NULL NULL -4294967163 session_variables 0 0 NULL NULL NULL -4294967164 sequences 0 0 NULL NULL NULL -4294967165 schema_privileges 0 0 NULL NULL NULL -4294967166 schemata 0 0 NULL NULL NULL -4294967167 schemata_extensions 0 0 NULL NULL NULL -4294967168 sql_sizing 0 0 NULL NULL NULL -4294967169 sql_parts 0 0 NULL NULL NULL -4294967170 sql_implementation_info 0 0 NULL NULL NULL -4294967171 sql_features 0 0 NULL NULL NULL -4294967172 routines 0 0 NULL NULL NULL -4294967173 routine_privileges 0 0 NULL NULL NULL -4294967174 role_usage_grants 0 0 NULL NULL NULL -4294967175 role_udt_grants 0 0 NULL NULL NULL -4294967176 role_table_grants 0 0 NULL NULL NULL -4294967177 role_routine_grants 0 0 NULL NULL NULL -4294967178 role_column_grants 0 0 NULL NULL NULL -4294967179 resource_groups 0 0 NULL NULL NULL -4294967180 referential_constraints 0 0 NULL NULL NULL -4294967181 profiling 0 0 NULL NULL NULL -4294967182 processlist 0 0 NULL NULL NULL -4294967183 plugins 0 0 NULL NULL NULL -4294967184 partitions 0 0 NULL NULL NULL -4294967185 parameters 0 0 NULL NULL NULL -4294967186 optimizer_trace 0 0 NULL NULL NULL -4294967187 keywords 0 0 NULL NULL NULL -4294967188 key_column_usage 0 0 NULL NULL NULL -4294967189 information_schema_catalog_name 0 0 NULL NULL NULL -4294967190 foreign_tables 0 0 NULL NULL NULL -4294967191 foreign_table_options 0 0 NULL NULL NULL -4294967192 foreign_servers 0 0 NULL NULL NULL -4294967193 foreign_server_options 0 0 NULL NULL NULL -4294967194 foreign_data_wrappers 0 0 NULL NULL NULL -4294967195 foreign_data_wrapper_options 0 0 NULL NULL NULL -4294967196 files 0 0 NULL NULL NULL -4294967197 events 0 0 NULL NULL NULL -4294967198 engines 0 0 NULL NULL NULL -4294967199 enabled_roles 0 0 NULL NULL NULL -4294967200 element_types 0 0 NULL NULL NULL -4294967201 domains 0 0 NULL NULL NULL -4294967202 domain_udt_usage 0 0 NULL NULL NULL -4294967203 domain_constraints 0 0 NULL NULL NULL -4294967204 data_type_privileges 0 0 NULL NULL NULL -4294967205 constraint_table_usage 0 0 NULL NULL NULL -4294967206 constraint_column_usage 0 0 NULL NULL NULL -4294967207 columns 0 0 NULL NULL NULL -4294967208 columns_extensions 0 0 NULL NULL NULL -4294967209 column_udt_usage 0 0 NULL NULL NULL -4294967210 column_statistics 0 0 NULL NULL NULL -4294967211 column_privileges 0 0 NULL NULL NULL -4294967212 column_options 0 0 NULL NULL NULL -4294967213 column_domain_usage 0 0 NULL NULL NULL -4294967214 column_column_usage 0 0 NULL NULL NULL -4294967215 collations 0 0 NULL NULL NULL -4294967216 collation_character_set_applicability 0 0 NULL NULL NULL -4294967217 check_constraints 0 0 NULL NULL NULL -4294967218 check_constraint_routine_usage 0 0 NULL NULL NULL -4294967219 character_sets 0 0 NULL NULL NULL -4294967220 attributes 0 0 NULL NULL NULL -4294967221 applicable_roles 0 0 NULL NULL NULL -4294967222 administrable_role_authorizations 0 0 NULL NULL NULL -4294967224 super_regions 0 0 NULL NULL NULL -4294967225 pg_catalog_table_is_implemented 0 0 NULL NULL NULL -4294967226 tenant_usage_details 0 0 NULL NULL NULL -4294967227 active_range_feeds 0 0 NULL NULL NULL -4294967228 default_privileges 0 0 NULL NULL NULL -4294967229 regions 0 0 NULL NULL NULL -4294967230 cluster_inflight_traces 0 0 NULL NULL NULL -4294967231 lost_descriptors_with_data 0 0 NULL NULL NULL -4294967232 cross_db_references 0 0 NULL NULL NULL -4294967233 cluster_database_privileges 0 0 NULL NULL NULL -4294967234 invalid_objects 0 0 NULL NULL NULL -4294967235 zones 0 0 NULL NULL NULL -4294967236 transaction_statistics 0 0 NULL NULL NULL -4294967237 node_transaction_statistics 0 0 NULL NULL NULL -4294967238 table_row_statistics 0 0 NULL NULL NULL -4294967239 tables 0 0 NULL NULL NULL -4294967240 table_indexes 0 0 NULL NULL NULL -4294967241 table_columns 0 0 NULL NULL NULL -4294967242 statement_statistics 0 0 NULL NULL NULL -4294967243 session_variables 0 0 NULL NULL NULL -4294967244 session_trace 0 0 NULL NULL NULL -4294967245 schema_changes 0 0 NULL NULL NULL -4294967246 node_runtime_info 0 0 NULL NULL NULL -4294967247 ranges 0 0 NULL NULL NULL -4294967248 ranges_no_leases 0 0 NULL NULL NULL -4294967249 predefined_comments 0 0 NULL NULL NULL -4294967250 partitions 0 0 NULL NULL NULL -4294967251 node_txn_stats 0 0 NULL NULL NULL -4294967252 node_statement_statistics 0 0 NULL NULL NULL -4294967253 node_metrics 0 0 NULL NULL NULL -4294967254 node_sessions 0 0 NULL NULL NULL -4294967255 node_transactions 0 0 NULL NULL NULL -4294967256 node_queries 0 0 NULL NULL NULL -4294967257 node_execution_insights 0 0 NULL NULL NULL -4294967258 node_distsql_flows 0 0 NULL NULL NULL -4294967259 node_contention_events 0 0 NULL NULL NULL -4294967260 leases 0 0 NULL NULL NULL -4294967261 kv_store_status 0 0 NULL NULL NULL -4294967262 kv_node_status 0 0 NULL NULL NULL -4294967263 jobs 0 0 NULL NULL NULL -4294967264 node_inflight_trace_spans 0 0 NULL NULL NULL -4294967265 index_usage_statistics 0 0 NULL NULL NULL -4294967266 index_columns 0 0 NULL NULL NULL -4294967267 transaction_contention_events 0 0 NULL NULL NULL -4294967268 gossip_network 0 0 NULL NULL NULL -4294967269 gossip_liveness 0 0 NULL NULL NULL -4294967270 gossip_alerts 0 0 NULL NULL NULL -4294967271 gossip_nodes 0 0 NULL NULL NULL -4294967272 kv_node_liveness 0 0 NULL NULL NULL -4294967273 forward_dependencies 0 0 NULL NULL NULL -4294967274 feature_usage 0 0 NULL NULL NULL -4294967275 databases 0 0 NULL NULL NULL -4294967276 create_type_statements 0 0 NULL NULL NULL -4294967277 create_statements 0 0 NULL NULL NULL -4294967278 create_schema_statements 0 0 NULL NULL NULL -4294967279 create_function_statements 0 0 NULL NULL NULL -4294967280 cluster_transaction_statistics 0 0 NULL NULL NULL -4294967281 cluster_statement_statistics 0 0 NULL NULL NULL -4294967282 cluster_settings 0 0 NULL NULL NULL -4294967283 cluster_sessions 0 0 NULL NULL NULL -4294967284 cluster_transactions 0 0 NULL NULL NULL -4294967285 cluster_queries 0 0 NULL NULL NULL -4294967286 cluster_locks 0 0 NULL NULL NULL +4294967002 spatial_ref_sys 0 0 NULL NULL NULL +4294967003 geometry_columns 0 0 NULL NULL NULL +4294967004 geography_columns 0 0 NULL NULL NULL +4294967006 pg_views 0 0 NULL NULL NULL +4294967007 pg_user 0 0 NULL NULL NULL +4294967008 pg_user_mappings 0 0 NULL NULL NULL +4294967009 pg_user_mapping 0 0 NULL NULL NULL +4294967010 pg_type 0 0 NULL NULL NULL +4294967011 pg_ts_template 0 0 NULL NULL NULL +4294967012 pg_ts_parser 0 0 NULL NULL NULL +4294967013 pg_ts_dict 0 0 NULL NULL NULL +4294967014 pg_ts_config 0 0 NULL NULL NULL +4294967015 pg_ts_config_map 0 0 NULL NULL NULL +4294967016 pg_trigger 0 0 NULL NULL NULL +4294967017 pg_transform 0 0 NULL NULL NULL +4294967018 pg_timezone_names 0 0 NULL NULL NULL +4294967019 pg_timezone_abbrevs 0 0 NULL NULL NULL +4294967020 pg_tablespace 0 0 NULL NULL NULL +4294967021 pg_tables 0 0 NULL NULL NULL +4294967022 pg_subscription 0 0 NULL NULL NULL +4294967023 pg_subscription_rel 0 0 NULL NULL NULL +4294967024 pg_stats 0 0 NULL NULL NULL +4294967025 pg_stats_ext 0 0 NULL NULL NULL +4294967026 pg_statistic 0 0 NULL NULL NULL +4294967027 pg_statistic_ext 0 0 NULL NULL NULL +4294967028 pg_statistic_ext_data 0 0 NULL NULL NULL +4294967029 pg_statio_user_tables 0 0 NULL NULL NULL +4294967030 pg_statio_user_sequences 0 0 NULL NULL NULL +4294967031 pg_statio_user_indexes 0 0 NULL NULL NULL +4294967032 pg_statio_sys_tables 0 0 NULL NULL NULL +4294967033 pg_statio_sys_sequences 0 0 NULL NULL NULL +4294967034 pg_statio_sys_indexes 0 0 NULL NULL NULL +4294967035 pg_statio_all_tables 0 0 NULL NULL NULL +4294967036 pg_statio_all_sequences 0 0 NULL NULL NULL +4294967037 pg_statio_all_indexes 0 0 NULL NULL NULL +4294967038 pg_stat_xact_user_tables 0 0 NULL NULL NULL +4294967039 pg_stat_xact_user_functions 0 0 NULL NULL NULL +4294967040 pg_stat_xact_sys_tables 0 0 NULL NULL NULL +4294967041 pg_stat_xact_all_tables 0 0 NULL NULL NULL +4294967042 pg_stat_wal_receiver 0 0 NULL NULL NULL +4294967043 pg_stat_user_tables 0 0 NULL NULL NULL +4294967044 pg_stat_user_indexes 0 0 NULL NULL NULL +4294967045 pg_stat_user_functions 0 0 NULL NULL NULL +4294967046 pg_stat_sys_tables 0 0 NULL NULL NULL +4294967047 pg_stat_sys_indexes 0 0 NULL NULL NULL +4294967048 pg_stat_subscription 0 0 NULL NULL NULL +4294967049 pg_stat_ssl 0 0 NULL NULL NULL +4294967050 pg_stat_slru 0 0 NULL NULL NULL +4294967051 pg_stat_replication 0 0 NULL NULL NULL +4294967052 pg_stat_progress_vacuum 0 0 NULL NULL NULL +4294967053 pg_stat_progress_create_index 0 0 NULL NULL NULL +4294967054 pg_stat_progress_cluster 0 0 NULL NULL NULL +4294967055 pg_stat_progress_basebackup 0 0 NULL NULL NULL +4294967056 pg_stat_progress_analyze 0 0 NULL NULL NULL +4294967057 pg_stat_gssapi 0 0 NULL NULL NULL +4294967058 pg_stat_database 0 0 NULL NULL NULL +4294967059 pg_stat_database_conflicts 0 0 NULL NULL NULL +4294967060 pg_stat_bgwriter 0 0 NULL NULL NULL +4294967061 pg_stat_archiver 0 0 NULL NULL NULL +4294967062 pg_stat_all_tables 0 0 NULL NULL NULL +4294967063 pg_stat_all_indexes 0 0 NULL NULL NULL +4294967064 pg_stat_activity 0 0 NULL NULL NULL +4294967065 pg_shmem_allocations 0 0 NULL NULL NULL +4294967066 pg_shdepend 0 0 NULL NULL NULL +4294967067 pg_shseclabel 0 0 NULL NULL NULL +4294967068 pg_shdescription 0 0 NULL NULL NULL +4294967069 pg_shadow 0 0 NULL NULL NULL +4294967070 pg_settings 0 0 NULL NULL NULL +4294967071 pg_sequences 0 0 NULL NULL NULL +4294967072 pg_sequence 0 0 NULL NULL NULL +4294967073 pg_seclabel 0 0 NULL NULL NULL +4294967074 pg_seclabels 0 0 NULL NULL NULL +4294967075 pg_rules 0 0 NULL NULL NULL +4294967076 pg_roles 0 0 NULL NULL NULL +4294967077 pg_rewrite 0 0 NULL NULL NULL +4294967078 pg_replication_slots 0 0 NULL NULL NULL +4294967079 pg_replication_origin 0 0 NULL NULL NULL +4294967080 pg_replication_origin_status 0 0 NULL NULL NULL +4294967081 pg_range 0 0 NULL NULL NULL +4294967082 pg_publication_tables 0 0 NULL NULL NULL +4294967083 pg_publication 0 0 NULL NULL NULL +4294967084 pg_publication_rel 0 0 NULL NULL NULL +4294967085 pg_proc 0 0 NULL NULL NULL +4294967086 pg_prepared_xacts 0 0 NULL NULL NULL +4294967087 pg_prepared_statements 0 0 NULL NULL NULL +4294967088 pg_policy 0 0 NULL NULL NULL +4294967089 pg_policies 0 0 NULL NULL NULL +4294967090 pg_partitioned_table 0 0 NULL NULL NULL +4294967091 pg_opfamily 0 0 NULL NULL NULL +4294967092 pg_operator 0 0 NULL NULL NULL +4294967093 pg_opclass 0 0 NULL NULL NULL +4294967094 pg_namespace 0 0 NULL NULL NULL +4294967095 pg_matviews 0 0 NULL NULL NULL +4294967096 pg_locks 0 0 NULL NULL NULL +4294967097 pg_largeobject 0 0 NULL NULL NULL +4294967098 pg_largeobject_metadata 0 0 NULL NULL NULL +4294967099 pg_language 0 0 NULL NULL NULL +4294967100 pg_init_privs 0 0 NULL NULL NULL +4294967101 pg_inherits 0 0 NULL NULL NULL +4294967102 pg_indexes 0 0 NULL NULL NULL +4294967103 pg_index 0 0 NULL NULL NULL +4294967104 pg_hba_file_rules 0 0 NULL NULL NULL +4294967105 pg_group 0 0 NULL NULL NULL +4294967106 pg_foreign_table 0 0 NULL NULL NULL +4294967107 pg_foreign_server 0 0 NULL NULL NULL +4294967108 pg_foreign_data_wrapper 0 0 NULL NULL NULL +4294967109 pg_file_settings 0 0 NULL NULL NULL +4294967110 pg_extension 0 0 NULL NULL NULL +4294967111 pg_event_trigger 0 0 NULL NULL NULL +4294967112 pg_enum 0 0 NULL NULL NULL +4294967113 pg_description 0 0 NULL NULL NULL +4294967114 pg_depend 0 0 NULL NULL NULL +4294967115 pg_default_acl 0 0 NULL NULL NULL +4294967116 pg_db_role_setting 0 0 NULL NULL NULL +4294967117 pg_database 0 0 NULL NULL NULL +4294967118 pg_cursors 0 0 NULL NULL NULL +4294967119 pg_conversion 0 0 NULL NULL NULL +4294967120 pg_constraint 0 0 NULL NULL NULL +4294967121 pg_config 0 0 NULL NULL NULL +4294967122 pg_collation 0 0 NULL NULL NULL +4294967123 pg_class 0 0 NULL NULL NULL +4294967124 pg_cast 0 0 NULL NULL NULL +4294967125 pg_available_extensions 0 0 NULL NULL NULL +4294967126 pg_available_extension_versions 0 0 NULL NULL NULL +4294967127 pg_auth_members 0 0 NULL NULL NULL +4294967128 pg_authid 0 0 NULL NULL NULL +4294967129 pg_attribute 0 0 NULL NULL NULL +4294967130 pg_attrdef 0 0 NULL NULL NULL +4294967131 pg_amproc 0 0 NULL NULL NULL +4294967132 pg_amop 0 0 NULL NULL NULL +4294967133 pg_am 0 0 NULL NULL NULL +4294967134 pg_aggregate 0 0 NULL NULL NULL +4294967136 views 0 0 NULL NULL NULL +4294967137 view_table_usage 0 0 NULL NULL NULL +4294967138 view_routine_usage 0 0 NULL NULL NULL +4294967139 view_column_usage 0 0 NULL NULL NULL +4294967140 user_privileges 0 0 NULL NULL NULL +4294967141 user_mappings 0 0 NULL NULL NULL +4294967142 user_mapping_options 0 0 NULL NULL NULL +4294967143 user_defined_types 0 0 NULL NULL NULL +4294967144 user_attributes 0 0 NULL NULL NULL +4294967145 usage_privileges 0 0 NULL NULL NULL +4294967146 udt_privileges 0 0 NULL NULL NULL +4294967147 type_privileges 0 0 NULL NULL NULL +4294967148 triggers 0 0 NULL NULL NULL +4294967149 triggered_update_columns 0 0 NULL NULL NULL +4294967150 transforms 0 0 NULL NULL NULL +4294967151 tablespaces 0 0 NULL NULL NULL +4294967152 tablespaces_extensions 0 0 NULL NULL NULL +4294967153 tables 0 0 NULL NULL NULL +4294967154 tables_extensions 0 0 NULL NULL NULL +4294967155 table_privileges 0 0 NULL NULL NULL +4294967156 table_constraints_extensions 0 0 NULL NULL NULL +4294967157 table_constraints 0 0 NULL NULL NULL +4294967158 statistics 0 0 NULL NULL NULL +4294967159 st_units_of_measure 0 0 NULL NULL NULL +4294967160 st_spatial_reference_systems 0 0 NULL NULL NULL +4294967161 st_geometry_columns 0 0 NULL NULL NULL +4294967162 session_variables 0 0 NULL NULL NULL +4294967163 sequences 0 0 NULL NULL NULL +4294967164 schema_privileges 0 0 NULL NULL NULL +4294967165 schemata 0 0 NULL NULL NULL +4294967166 schemata_extensions 0 0 NULL NULL NULL +4294967167 sql_sizing 0 0 NULL NULL NULL +4294967168 sql_parts 0 0 NULL NULL NULL +4294967169 sql_implementation_info 0 0 NULL NULL NULL +4294967170 sql_features 0 0 NULL NULL NULL +4294967171 routines 0 0 NULL NULL NULL +4294967172 routine_privileges 0 0 NULL NULL NULL +4294967173 role_usage_grants 0 0 NULL NULL NULL +4294967174 role_udt_grants 0 0 NULL NULL NULL +4294967175 role_table_grants 0 0 NULL NULL NULL +4294967176 role_routine_grants 0 0 NULL NULL NULL +4294967177 role_column_grants 0 0 NULL NULL NULL +4294967178 resource_groups 0 0 NULL NULL NULL +4294967179 referential_constraints 0 0 NULL NULL NULL +4294967180 profiling 0 0 NULL NULL NULL +4294967181 processlist 0 0 NULL NULL NULL +4294967182 plugins 0 0 NULL NULL NULL +4294967183 partitions 0 0 NULL NULL NULL +4294967184 parameters 0 0 NULL NULL NULL +4294967185 optimizer_trace 0 0 NULL NULL NULL +4294967186 keywords 0 0 NULL NULL NULL +4294967187 key_column_usage 0 0 NULL NULL NULL +4294967188 information_schema_catalog_name 0 0 NULL NULL NULL +4294967189 foreign_tables 0 0 NULL NULL NULL +4294967190 foreign_table_options 0 0 NULL NULL NULL +4294967191 foreign_servers 0 0 NULL NULL NULL +4294967192 foreign_server_options 0 0 NULL NULL NULL +4294967193 foreign_data_wrappers 0 0 NULL NULL NULL +4294967194 foreign_data_wrapper_options 0 0 NULL NULL NULL +4294967195 files 0 0 NULL NULL NULL +4294967196 events 0 0 NULL NULL NULL +4294967197 engines 0 0 NULL NULL NULL +4294967198 enabled_roles 0 0 NULL NULL NULL +4294967199 element_types 0 0 NULL NULL NULL +4294967200 domains 0 0 NULL NULL NULL +4294967201 domain_udt_usage 0 0 NULL NULL NULL +4294967202 domain_constraints 0 0 NULL NULL NULL +4294967203 data_type_privileges 0 0 NULL NULL NULL +4294967204 constraint_table_usage 0 0 NULL NULL NULL +4294967205 constraint_column_usage 0 0 NULL NULL NULL +4294967206 columns 0 0 NULL NULL NULL +4294967207 columns_extensions 0 0 NULL NULL NULL +4294967208 column_udt_usage 0 0 NULL NULL NULL +4294967209 column_statistics 0 0 NULL NULL NULL +4294967210 column_privileges 0 0 NULL NULL NULL +4294967211 column_options 0 0 NULL NULL NULL +4294967212 column_domain_usage 0 0 NULL NULL NULL +4294967213 column_column_usage 0 0 NULL NULL NULL +4294967214 collations 0 0 NULL NULL NULL +4294967215 collation_character_set_applicability 0 0 NULL NULL NULL +4294967216 check_constraints 0 0 NULL NULL NULL +4294967217 check_constraint_routine_usage 0 0 NULL NULL NULL +4294967218 character_sets 0 0 NULL NULL NULL +4294967219 attributes 0 0 NULL NULL NULL +4294967220 applicable_roles 0 0 NULL NULL NULL +4294967221 administrable_role_authorizations 0 0 NULL NULL NULL +4294967223 super_regions 0 0 NULL NULL NULL +4294967224 pg_catalog_table_is_implemented 0 0 NULL NULL NULL +4294967225 tenant_usage_details 0 0 NULL NULL NULL +4294967226 active_range_feeds 0 0 NULL NULL NULL +4294967227 default_privileges 0 0 NULL NULL NULL +4294967228 regions 0 0 NULL NULL NULL +4294967229 cluster_inflight_traces 0 0 NULL NULL NULL +4294967230 lost_descriptors_with_data 0 0 NULL NULL NULL +4294967231 cross_db_references 0 0 NULL NULL NULL +4294967232 cluster_database_privileges 0 0 NULL NULL NULL +4294967233 invalid_objects 0 0 NULL NULL NULL +4294967234 zones 0 0 NULL NULL NULL +4294967235 transaction_statistics 0 0 NULL NULL NULL +4294967236 node_transaction_statistics 0 0 NULL NULL NULL +4294967237 table_row_statistics 0 0 NULL NULL NULL +4294967238 tables 0 0 NULL NULL NULL +4294967239 table_indexes 0 0 NULL NULL NULL +4294967240 table_columns 0 0 NULL NULL NULL +4294967241 statement_statistics 0 0 NULL NULL NULL +4294967242 session_variables 0 0 NULL NULL NULL +4294967243 session_trace 0 0 NULL NULL NULL +4294967244 schema_changes 0 0 NULL NULL NULL +4294967245 node_runtime_info 0 0 NULL NULL NULL +4294967246 ranges 0 0 NULL NULL NULL +4294967247 ranges_no_leases 0 0 NULL NULL NULL +4294967248 predefined_comments 0 0 NULL NULL NULL +4294967249 partitions 0 0 NULL NULL NULL +4294967250 node_txn_stats 0 0 NULL NULL NULL +4294967251 node_statement_statistics 0 0 NULL NULL NULL +4294967252 node_metrics 0 0 NULL NULL NULL +4294967253 node_sessions 0 0 NULL NULL NULL +4294967254 node_transactions 0 0 NULL NULL NULL +4294967255 node_queries 0 0 NULL NULL NULL +4294967256 node_execution_insights 0 0 NULL NULL NULL +4294967257 node_distsql_flows 0 0 NULL NULL NULL +4294967258 node_contention_events 0 0 NULL NULL NULL +4294967259 leases 0 0 NULL NULL NULL +4294967260 kv_store_status 0 0 NULL NULL NULL +4294967261 kv_node_status 0 0 NULL NULL NULL +4294967262 jobs 0 0 NULL NULL NULL +4294967263 node_inflight_trace_spans 0 0 NULL NULL NULL +4294967264 index_usage_statistics 0 0 NULL NULL NULL +4294967265 index_columns 0 0 NULL NULL NULL +4294967266 transaction_contention_events 0 0 NULL NULL NULL +4294967267 gossip_network 0 0 NULL NULL NULL +4294967268 gossip_liveness 0 0 NULL NULL NULL +4294967269 gossip_alerts 0 0 NULL NULL NULL +4294967270 gossip_nodes 0 0 NULL NULL NULL +4294967271 kv_node_liveness 0 0 NULL NULL NULL +4294967272 forward_dependencies 0 0 NULL NULL NULL +4294967273 feature_usage 0 0 NULL NULL NULL +4294967274 databases 0 0 NULL NULL NULL +4294967275 create_type_statements 0 0 NULL NULL NULL +4294967276 create_statements 0 0 NULL NULL NULL +4294967277 create_schema_statements 0 0 NULL NULL NULL +4294967278 create_function_statements 0 0 NULL NULL NULL +4294967279 cluster_transaction_statistics 0 0 NULL NULL NULL +4294967280 cluster_statement_statistics 0 0 NULL NULL NULL +4294967281 cluster_settings 0 0 NULL NULL NULL +4294967282 cluster_sessions 0 0 NULL NULL NULL +4294967283 cluster_transactions 0 0 NULL NULL NULL +4294967284 cluster_queries 0 0 NULL NULL NULL +4294967285 cluster_locks 0 0 NULL NULL NULL +4294967286 cluster_execution_insights 0 0 NULL NULL NULL 4294967287 cluster_distsql_flows 0 0 NULL NULL NULL 4294967288 cluster_contention_events 0 0 NULL NULL NULL 4294967289 cluster_contended_tables 0 0 NULL NULL NULL @@ -3793,287 +3798,287 @@ SELECT objoid, classoid, objsubid, regexp_replace(description, e'\n.*', '') AS d FROM pg_catalog.pg_description ---- objoid classoid objsubid description -4294967227 4294967124 0 node-level table listing all currently running range feeds -4294967294 4294967124 0 backward inter-descriptor dependencies starting from tables accessible by current user in current database (KV scan) -4294967292 4294967124 0 built-in functions (RAM/static) -4294967288 4294967124 0 contention information (cluster RPC; expensive!) -4294967233 4294967124 0 virtual table with database privileges -4294967287 4294967124 0 DistSQL remote flows information (cluster RPC; expensive!) -4294967230 4294967124 0 traces for in-flight spans across all nodes in the cluster (cluster RPC; expensive!) -4294967286 4294967124 0 cluster-wide locks held in lock tables. Querying this table is an -4294967285 4294967124 0 running queries visible by current user (cluster RPC; expensive!) -4294967283 4294967124 0 running sessions visible to current user (cluster RPC; expensive!) -4294967282 4294967124 0 cluster settings (RAM) -4294967281 4294967124 0 cluster-wide statement statistics that have not yet been flushed to system tables. Querying this table is a somewhat expensive operation since it creates a cluster-wide RPC-fanout. -4294967280 4294967124 0 cluster-wide transaction statistics that have not yet been flushed to system tables. Querying this table is a somewhat expensive operation since it creates a cluster-wide RPC-fanout. -4294967284 4294967124 0 running user transactions visible by the current user (cluster RPC; expensive!) -4294967279 4294967124 0 CREATE statements for all user-defined functions -4294967278 4294967124 0 CREATE statements for all user defined schemas accessible by the current user in current database (KV scan) -4294967277 4294967124 0 CREATE and ALTER statements for all tables accessible by current user in current database (KV scan) -4294967276 4294967124 0 CREATE statements for all user defined types accessible by the current user in current database (KV scan) -4294967232 4294967124 0 virtual table with cross db references -4294967275 4294967124 0 databases accessible by the current user (KV scan) -4294967228 4294967124 0 virtual table with default privileges -4294967274 4294967124 0 telemetry counters (RAM; local node only) -4294967273 4294967124 0 forward inter-descriptor dependencies starting from tables accessible by current user in current database (KV scan) -4294967270 4294967124 0 locally known gossiped health alerts (RAM; local node only) -4294967269 4294967124 0 locally known gossiped node liveness (RAM; local node only) -4294967268 4294967124 0 locally known edges in the gossip network (RAM; local node only) -4294967271 4294967124 0 locally known gossiped node details (RAM; local node only) -4294967266 4294967124 0 index columns for all indexes accessible by current user in current database (KV scan) -4294967265 4294967124 0 cluster-wide index usage statistics (in-memory, not durable).Querying this table is an expensive operation since it creates acluster-wide RPC fanout. -4294967234 4294967124 0 virtual table to validate descriptors -4294967263 4294967124 0 decoded job metadata from system.jobs (KV scan) -4294967272 4294967124 0 node liveness status, as seen by kv -4294967262 4294967124 0 node details across the entire cluster (cluster RPC; expensive!) -4294967261 4294967124 0 store details and status (cluster RPC; expensive!) -4294967260 4294967124 0 acquired table leases (RAM; local node only) -4294967231 4294967124 0 virtual table with table descriptors that still have data -4294967293 4294967124 0 detailed identification strings (RAM, local node only) -4294967259 4294967124 0 contention information (RAM; local node only) -4294967258 4294967124 0 DistSQL remote flows information (RAM; local node only) -4294967264 4294967124 0 in-flight spans (RAM; local node only) -4294967253 4294967124 0 current values for metrics (RAM; local node only) -4294967256 4294967124 0 running queries visible by current user (RAM; local node only) -4294967246 4294967124 0 server parameters, useful to construct connection URLs (RAM, local node only) -4294967254 4294967124 0 running sessions visible by current user (RAM; local node only) -4294967252 4294967124 0 statement statistics. The contents of this table are flushed to the system.statement_statistics table at the interval set by the cluster setting sql.stats.flush.interval (by default, 10m). -4294967237 4294967124 0 finer-grained transaction statistics. The contents of this table are flushed to the system.transaction_statistics table at the interval set by the cluster setting sql.stats.flush.interval (by default, 10m). -4294967255 4294967124 0 running user transactions visible by the current user (RAM; local node only) -4294967251 4294967124 0 per-application transaction statistics (in-memory, not durable; local node only). This table is wiped periodically (by default, at least every two hours) -4294967250 4294967124 0 defined partitions for all tables/indexes accessible by the current user in the current database (KV scan) -4294967225 4294967124 0 table descriptors accessible by current user, including non-public and virtual (KV scan; expensive!) -4294967249 4294967124 0 comments for predefined virtual tables (RAM/static) -4294967248 4294967124 0 range metadata without leaseholder details (KV join; expensive!) -4294967229 4294967124 0 available regions for the cluster -4294967245 4294967124 0 ongoing schema changes, across all descriptors accessible by current user (KV scan; expensive!) -4294967244 4294967124 0 session trace accumulated so far (RAM) -4294967243 4294967124 0 session variables (RAM) -4294967224 4294967124 0 list super regions of databases visible to the current user -4294967241 4294967124 0 details for all columns accessible by current user in current database (KV scan) -4294967240 4294967124 0 indexes accessible by current user in current database (KV scan) -4294967238 4294967124 0 stats for all tables accessible by current user in current database as of 10s ago -4294967239 4294967124 0 table descriptors accessible by current user, including non-public and virtual (KV scan; expensive!) -4294967267 4294967124 0 cluster-wide transaction contention events. Querying this table is an -4294967235 4294967124 0 decoded zone configurations from system.zones (KV scan) -4294967222 4294967124 0 roles for which the current user has admin option -4294967221 4294967124 0 roles available to the current user -4294967220 4294967124 0 attributes was created for compatibility and is currently unimplemented -4294967219 4294967124 0 character sets available in the current database -4294967218 4294967124 0 check_constraint_routine_usage was created for compatibility and is currently unimplemented -4294967217 4294967124 0 check constraints -4294967216 4294967124 0 identifies which character set the available collations are -4294967215 4294967124 0 shows the collations available in the current database -4294967214 4294967124 0 column_column_usage was created for compatibility and is currently unimplemented -4294967213 4294967124 0 column_domain_usage was created for compatibility and is currently unimplemented -4294967212 4294967124 0 column_options was created for compatibility and is currently unimplemented -4294967211 4294967124 0 column privilege grants (incomplete) -4294967210 4294967124 0 column_statistics was created for compatibility and is currently unimplemented -4294967209 4294967124 0 columns with user defined types -4294967207 4294967124 0 table and view columns (incomplete) -4294967208 4294967124 0 columns_extensions was created for compatibility and is currently unimplemented -4294967206 4294967124 0 columns usage by constraints -4294967205 4294967124 0 constraint_table_usage was created for compatibility and is currently unimplemented -4294967204 4294967124 0 data_type_privileges was created for compatibility and is currently unimplemented -4294967203 4294967124 0 domain_constraints was created for compatibility and is currently unimplemented -4294967202 4294967124 0 domain_udt_usage was created for compatibility and is currently unimplemented -4294967201 4294967124 0 domains was created for compatibility and is currently unimplemented -4294967200 4294967124 0 element_types was created for compatibility and is currently unimplemented -4294967199 4294967124 0 roles for the current user -4294967198 4294967124 0 engines was created for compatibility and is currently unimplemented -4294967197 4294967124 0 events was created for compatibility and is currently unimplemented -4294967196 4294967124 0 files was created for compatibility and is currently unimplemented -4294967195 4294967124 0 foreign_data_wrapper_options was created for compatibility and is currently unimplemented -4294967194 4294967124 0 foreign_data_wrappers was created for compatibility and is currently unimplemented -4294967193 4294967124 0 foreign_server_options was created for compatibility and is currently unimplemented -4294967192 4294967124 0 foreign_servers was created for compatibility and is currently unimplemented -4294967191 4294967124 0 foreign_table_options was created for compatibility and is currently unimplemented -4294967190 4294967124 0 foreign_tables was created for compatibility and is currently unimplemented -4294967189 4294967124 0 information_schema_catalog_name was created for compatibility and is currently unimplemented -4294967188 4294967124 0 column usage by indexes and key constraints -4294967187 4294967124 0 keywords was created for compatibility and is currently unimplemented -4294967186 4294967124 0 optimizer_trace was created for compatibility and is currently unimplemented -4294967185 4294967124 0 built-in function parameters (empty - introspection not yet supported) -4294967184 4294967124 0 partitions was created for compatibility and is currently unimplemented -4294967183 4294967124 0 plugins was created for compatibility and is currently unimplemented -4294967182 4294967124 0 processlist was created for compatibility and is currently unimplemented -4294967181 4294967124 0 profiling was created for compatibility and is currently unimplemented -4294967180 4294967124 0 foreign key constraints -4294967179 4294967124 0 resource_groups was created for compatibility and is currently unimplemented -4294967178 4294967124 0 role_column_grants was created for compatibility and is currently unimplemented -4294967177 4294967124 0 role_routine_grants was created for compatibility and is currently unimplemented -4294967176 4294967124 0 privileges granted on table or views (incomplete; see also information_schema.table_privileges; may contain excess users or roles) -4294967175 4294967124 0 role_udt_grants was created for compatibility and is currently unimplemented -4294967174 4294967124 0 role_usage_grants was created for compatibility and is currently unimplemented -4294967173 4294967124 0 routine_privileges was created for compatibility and is currently unimplemented -4294967172 4294967124 0 built-in functions (empty - introspection not yet supported) -4294967165 4294967124 0 schema privileges (incomplete; may contain excess users or roles) -4294967166 4294967124 0 database schemas (may contain schemata without permission) -4294967167 4294967124 0 schemata_extensions was created for compatibility and is currently unimplemented -4294967164 4294967124 0 sequences -4294967163 4294967124 0 exposes the session variables. -4294967171 4294967124 0 sql_features was created for compatibility and is currently unimplemented -4294967170 4294967124 0 sql_implementation_info was created for compatibility and is currently unimplemented -4294967169 4294967124 0 sql_parts was created for compatibility and is currently unimplemented -4294967168 4294967124 0 sql_sizing was created for compatibility and is currently unimplemented -4294967162 4294967124 0 st_geometry_columns was created for compatibility and is currently unimplemented -4294967161 4294967124 0 st_spatial_reference_systems was created for compatibility and is currently unimplemented -4294967160 4294967124 0 st_units_of_measure was created for compatibility and is currently unimplemented -4294967159 4294967124 0 index metadata and statistics (incomplete) -4294967158 4294967124 0 table constraints -4294967157 4294967124 0 table_constraints_extensions was created for compatibility and is currently unimplemented -4294967156 4294967124 0 privileges granted on table or views (incomplete; may contain excess users or roles) -4294967154 4294967124 0 tables and views -4294967155 4294967124 0 tables_extensions was created for compatibility and is currently unimplemented -4294967152 4294967124 0 tablespaces was created for compatibility and is currently unimplemented -4294967153 4294967124 0 tablespaces_extensions was created for compatibility and is currently unimplemented -4294967151 4294967124 0 transforms was created for compatibility and is currently unimplemented -4294967150 4294967124 0 triggered_update_columns was created for compatibility and is currently unimplemented -4294967149 4294967124 0 triggers was created for compatibility and is currently unimplemented -4294967148 4294967124 0 type privileges (incomplete; may contain excess users or roles) -4294967147 4294967124 0 udt_privileges was created for compatibility and is currently unimplemented -4294967146 4294967124 0 usage_privileges was created for compatibility and is currently unimplemented -4294967145 4294967124 0 user_attributes was created for compatibility and is currently unimplemented -4294967144 4294967124 0 user_defined_types was created for compatibility and is currently unimplemented -4294967143 4294967124 0 user_mapping_options was created for compatibility and is currently unimplemented -4294967142 4294967124 0 user_mappings was created for compatibility and is currently unimplemented -4294967141 4294967124 0 grantable privileges (incomplete) -4294967140 4294967124 0 view_column_usage was created for compatibility and is currently unimplemented -4294967139 4294967124 0 view_routine_usage was created for compatibility and is currently unimplemented -4294967138 4294967124 0 view_table_usage was created for compatibility and is currently unimplemented -4294967137 4294967124 0 views (incomplete) -4294967135 4294967124 0 aggregated built-in functions (incomplete) -4294967134 4294967124 0 index access methods (incomplete) -4294967133 4294967124 0 pg_amop was created for compatibility and is currently unimplemented -4294967132 4294967124 0 pg_amproc was created for compatibility and is currently unimplemented -4294967131 4294967124 0 column default values -4294967130 4294967124 0 table columns (incomplete - see also information_schema.columns) -4294967128 4294967124 0 role membership -4294967129 4294967124 0 authorization identifiers - differs from postgres as we do not display passwords, -4294967127 4294967124 0 pg_available_extension_versions was created for compatibility and is currently unimplemented -4294967126 4294967124 0 available extensions -4294967125 4294967124 0 casts (empty - needs filling out) -4294967124 4294967124 0 tables and relation-like objects (incomplete - see also information_schema.tables/sequences/views) -4294967123 4294967124 0 available collations (incomplete) -4294967122 4294967124 0 pg_config was created for compatibility and is currently unimplemented -4294967121 4294967124 0 table constraints (incomplete - see also information_schema.table_constraints) -4294967120 4294967124 0 encoding conversions (empty - unimplemented) -4294967119 4294967124 0 contains currently active SQL cursors created with DECLARE -4294967118 4294967124 0 available databases (incomplete) -4294967117 4294967124 0 contains the default values that have been configured for session variables -4294967116 4294967124 0 default ACLs; these are the privileges that will be assigned to newly created objects -4294967115 4294967124 0 dependency relationships (incomplete) -4294967114 4294967124 0 object comments -4294967113 4294967124 0 enum types and labels (empty - feature does not exist) -4294967112 4294967124 0 event triggers (empty - feature does not exist) -4294967111 4294967124 0 installed extensions (empty - feature does not exist) -4294967110 4294967124 0 pg_file_settings was created for compatibility and is currently unimplemented -4294967109 4294967124 0 foreign data wrappers (empty - feature does not exist) -4294967108 4294967124 0 foreign servers (empty - feature does not exist) -4294967107 4294967124 0 foreign tables (empty - feature does not exist) -4294967106 4294967124 0 pg_group was created for compatibility and is currently unimplemented -4294967105 4294967124 0 pg_hba_file_rules was created for compatibility and is currently unimplemented -4294967104 4294967124 0 indexes (incomplete) -4294967103 4294967124 0 index creation statements -4294967102 4294967124 0 table inheritance hierarchy (empty - feature does not exist) -4294967101 4294967124 0 pg_init_privs was created for compatibility and is currently unimplemented -4294967100 4294967124 0 available languages (empty - feature does not exist) -4294967098 4294967124 0 pg_largeobject was created for compatibility and is currently unimplemented -4294967099 4294967124 0 pg_largeobject_metadata was created for compatibility and is currently unimplemented -4294967097 4294967124 0 locks held by active processes (empty - feature does not exist) -4294967096 4294967124 0 available materialized views (empty - feature does not exist) -4294967095 4294967124 0 available namespaces (incomplete; namespaces and databases are congruent in CockroachDB) -4294967094 4294967124 0 opclass (empty - Operator classes not supported yet) -4294967093 4294967124 0 operators (incomplete) -4294967092 4294967124 0 pg_opfamily was created for compatibility and is currently unimplemented -4294967091 4294967124 0 pg_partitioned_table was created for compatibility and is currently unimplemented -4294967090 4294967124 0 pg_policies was created for compatibility and is currently unimplemented -4294967089 4294967124 0 pg_policy was created for compatibility and is currently unimplemented -4294967088 4294967124 0 prepared statements -4294967087 4294967124 0 prepared transactions (empty - feature does not exist) -4294967086 4294967124 0 built-in functions (incomplete) -4294967084 4294967124 0 pg_publication was created for compatibility and is currently unimplemented -4294967085 4294967124 0 pg_publication_rel was created for compatibility and is currently unimplemented -4294967083 4294967124 0 pg_publication_tables was created for compatibility and is currently unimplemented -4294967082 4294967124 0 range types (empty - feature does not exist) -4294967080 4294967124 0 pg_replication_origin was created for compatibility and is currently unimplemented -4294967081 4294967124 0 pg_replication_origin_status was created for compatibility and is currently unimplemented -4294967079 4294967124 0 pg_replication_slots was created for compatibility and is currently unimplemented -4294967078 4294967124 0 rewrite rules (only for referencing on pg_depend for table-view dependencies) -4294967077 4294967124 0 database roles -4294967076 4294967124 0 pg_rules was created for compatibility and is currently unimplemented -4294967074 4294967124 0 security labels (empty - feature does not exist) -4294967075 4294967124 0 security labels (empty) -4294967073 4294967124 0 sequences (see also information_schema.sequences) -4294967072 4294967124 0 pg_sequences is very similar as pg_sequence. -4294967071 4294967124 0 session variables (incomplete) -4294967070 4294967124 0 pg_shadow lists properties for roles that are marked as rolcanlogin in pg_authid -4294967067 4294967124 0 Shared Dependencies (Roles depending on objects). -4294967069 4294967124 0 shared object comments -4294967066 4294967124 0 pg_shmem_allocations was created for compatibility and is currently unimplemented -4294967068 4294967124 0 shared security labels (empty - feature not supported) -4294967065 4294967124 0 backend access statistics (empty - monitoring works differently in CockroachDB) -4294967064 4294967124 0 pg_stat_all_indexes was created for compatibility and is currently unimplemented -4294967063 4294967124 0 pg_stat_all_tables was created for compatibility and is currently unimplemented -4294967062 4294967124 0 pg_stat_archiver was created for compatibility and is currently unimplemented -4294967061 4294967124 0 pg_stat_bgwriter was created for compatibility and is currently unimplemented -4294967059 4294967124 0 pg_stat_database was created for compatibility and is currently unimplemented -4294967060 4294967124 0 pg_stat_database_conflicts was created for compatibility and is currently unimplemented -4294967058 4294967124 0 pg_stat_gssapi was created for compatibility and is currently unimplemented -4294967057 4294967124 0 pg_stat_progress_analyze was created for compatibility and is currently unimplemented -4294967056 4294967124 0 pg_stat_progress_basebackup was created for compatibility and is currently unimplemented -4294967055 4294967124 0 pg_stat_progress_cluster was created for compatibility and is currently unimplemented -4294967054 4294967124 0 pg_stat_progress_create_index was created for compatibility and is currently unimplemented -4294967053 4294967124 0 pg_stat_progress_vacuum was created for compatibility and is currently unimplemented -4294967052 4294967124 0 pg_stat_replication was created for compatibility and is currently unimplemented -4294967051 4294967124 0 pg_stat_slru was created for compatibility and is currently unimplemented -4294967050 4294967124 0 pg_stat_ssl was created for compatibility and is currently unimplemented -4294967049 4294967124 0 pg_stat_subscription was created for compatibility and is currently unimplemented -4294967048 4294967124 0 pg_stat_sys_indexes was created for compatibility and is currently unimplemented -4294967047 4294967124 0 pg_stat_sys_tables was created for compatibility and is currently unimplemented -4294967046 4294967124 0 pg_stat_user_functions was created for compatibility and is currently unimplemented -4294967045 4294967124 0 pg_stat_user_indexes was created for compatibility and is currently unimplemented -4294967044 4294967124 0 pg_stat_user_tables was created for compatibility and is currently unimplemented -4294967043 4294967124 0 pg_stat_wal_receiver was created for compatibility and is currently unimplemented -4294967042 4294967124 0 pg_stat_xact_all_tables was created for compatibility and is currently unimplemented -4294967041 4294967124 0 pg_stat_xact_sys_tables was created for compatibility and is currently unimplemented -4294967040 4294967124 0 pg_stat_xact_user_functions was created for compatibility and is currently unimplemented -4294967039 4294967124 0 pg_stat_xact_user_tables was created for compatibility and is currently unimplemented -4294967038 4294967124 0 pg_statio_all_indexes was created for compatibility and is currently unimplemented -4294967037 4294967124 0 pg_statio_all_sequences was created for compatibility and is currently unimplemented -4294967036 4294967124 0 pg_statio_all_tables was created for compatibility and is currently unimplemented -4294967035 4294967124 0 pg_statio_sys_indexes was created for compatibility and is currently unimplemented -4294967034 4294967124 0 pg_statio_sys_sequences was created for compatibility and is currently unimplemented -4294967033 4294967124 0 pg_statio_sys_tables was created for compatibility and is currently unimplemented -4294967032 4294967124 0 pg_statio_user_indexes was created for compatibility and is currently unimplemented -4294967031 4294967124 0 pg_statio_user_sequences was created for compatibility and is currently unimplemented -4294967030 4294967124 0 pg_statio_user_tables was created for compatibility and is currently unimplemented -4294967027 4294967124 0 pg_statistic was created for compatibility and is currently unimplemented -4294967028 4294967124 0 pg_statistic_ext has the statistics objects created with CREATE STATISTICS -4294967029 4294967124 0 pg_statistic_ext_data was created for compatibility and is currently unimplemented -4294967025 4294967124 0 pg_stats was created for compatibility and is currently unimplemented -4294967026 4294967124 0 pg_stats_ext was created for compatibility and is currently unimplemented -4294967023 4294967124 0 pg_subscription was created for compatibility and is currently unimplemented -4294967024 4294967124 0 pg_subscription_rel was created for compatibility and is currently unimplemented -4294967022 4294967124 0 tables summary (see also information_schema.tables, pg_catalog.pg_class) -4294967021 4294967124 0 available tablespaces (incomplete; concept inapplicable to CockroachDB) -4294967020 4294967124 0 pg_timezone_abbrevs was created for compatibility and is currently unimplemented -4294967019 4294967124 0 pg_timezone_names was created for compatibility and is currently unimplemented -4294967018 4294967124 0 pg_transform was created for compatibility and is currently unimplemented -4294967017 4294967124 0 triggers (empty - feature does not exist) -4294967015 4294967124 0 pg_ts_config was created for compatibility and is currently unimplemented -4294967016 4294967124 0 pg_ts_config_map was created for compatibility and is currently unimplemented -4294967014 4294967124 0 pg_ts_dict was created for compatibility and is currently unimplemented -4294967013 4294967124 0 pg_ts_parser was created for compatibility and is currently unimplemented -4294967012 4294967124 0 pg_ts_template was created for compatibility and is currently unimplemented -4294967011 4294967124 0 scalar types (incomplete) -4294967008 4294967124 0 database users -4294967010 4294967124 0 local to remote user mapping (empty - feature does not exist) -4294967009 4294967124 0 pg_user_mappings was created for compatibility and is currently unimplemented -4294967007 4294967124 0 view definitions (incomplete - see also information_schema.views) -4294967005 4294967124 0 Shows all defined geography columns. Matches PostGIS' geography_columns functionality. -4294967004 4294967124 0 Shows all defined geometry columns. Matches PostGIS' geometry_columns functionality. -4294967003 4294967124 0 Shows all defined Spatial Reference Identifiers (SRIDs). Matches PostGIS' spatial_ref_sys table. +4294967226 4294967123 0 node-level table listing all currently running range feeds +4294967294 4294967123 0 backward inter-descriptor dependencies starting from tables accessible by current user in current database (KV scan) +4294967292 4294967123 0 built-in functions (RAM/static) +4294967288 4294967123 0 contention information (cluster RPC; expensive!) +4294967232 4294967123 0 virtual table with database privileges +4294967287 4294967123 0 DistSQL remote flows information (cluster RPC; expensive!) +4294967229 4294967123 0 traces for in-flight spans across all nodes in the cluster (cluster RPC; expensive!) +4294967285 4294967123 0 cluster-wide locks held in lock tables. Querying this table is an +4294967284 4294967123 0 running queries visible by current user (cluster RPC; expensive!) +4294967282 4294967123 0 running sessions visible to current user (cluster RPC; expensive!) +4294967281 4294967123 0 cluster settings (RAM) +4294967280 4294967123 0 cluster-wide statement statistics that have not yet been flushed to system tables. Querying this table is a somewhat expensive operation since it creates a cluster-wide RPC-fanout. +4294967279 4294967123 0 cluster-wide transaction statistics that have not yet been flushed to system tables. Querying this table is a somewhat expensive operation since it creates a cluster-wide RPC-fanout. +4294967283 4294967123 0 running user transactions visible by the current user (cluster RPC; expensive!) +4294967278 4294967123 0 CREATE statements for all user-defined functions +4294967277 4294967123 0 CREATE statements for all user defined schemas accessible by the current user in current database (KV scan) +4294967276 4294967123 0 CREATE and ALTER statements for all tables accessible by current user in current database (KV scan) +4294967275 4294967123 0 CREATE statements for all user defined types accessible by the current user in current database (KV scan) +4294967231 4294967123 0 virtual table with cross db references +4294967274 4294967123 0 databases accessible by the current user (KV scan) +4294967227 4294967123 0 virtual table with default privileges +4294967273 4294967123 0 telemetry counters (RAM; local node only) +4294967272 4294967123 0 forward inter-descriptor dependencies starting from tables accessible by current user in current database (KV scan) +4294967269 4294967123 0 locally known gossiped health alerts (RAM; local node only) +4294967268 4294967123 0 locally known gossiped node liveness (RAM; local node only) +4294967267 4294967123 0 locally known edges in the gossip network (RAM; local node only) +4294967270 4294967123 0 locally known gossiped node details (RAM; local node only) +4294967265 4294967123 0 index columns for all indexes accessible by current user in current database (KV scan) +4294967264 4294967123 0 cluster-wide index usage statistics (in-memory, not durable).Querying this table is an expensive operation since it creates acluster-wide RPC fanout. +4294967233 4294967123 0 virtual table to validate descriptors +4294967262 4294967123 0 decoded job metadata from system.jobs (KV scan) +4294967271 4294967123 0 node liveness status, as seen by kv +4294967261 4294967123 0 node details across the entire cluster (cluster RPC; expensive!) +4294967260 4294967123 0 store details and status (cluster RPC; expensive!) +4294967259 4294967123 0 acquired table leases (RAM; local node only) +4294967230 4294967123 0 virtual table with table descriptors that still have data +4294967293 4294967123 0 detailed identification strings (RAM, local node only) +4294967258 4294967123 0 contention information (RAM; local node only) +4294967257 4294967123 0 DistSQL remote flows information (RAM; local node only) +4294967263 4294967123 0 in-flight spans (RAM; local node only) +4294967252 4294967123 0 current values for metrics (RAM; local node only) +4294967255 4294967123 0 running queries visible by current user (RAM; local node only) +4294967245 4294967123 0 server parameters, useful to construct connection URLs (RAM, local node only) +4294967253 4294967123 0 running sessions visible by current user (RAM; local node only) +4294967251 4294967123 0 statement statistics. The contents of this table are flushed to the system.statement_statistics table at the interval set by the cluster setting sql.stats.flush.interval (by default, 10m). +4294967236 4294967123 0 finer-grained transaction statistics. The contents of this table are flushed to the system.transaction_statistics table at the interval set by the cluster setting sql.stats.flush.interval (by default, 10m). +4294967254 4294967123 0 running user transactions visible by the current user (RAM; local node only) +4294967250 4294967123 0 per-application transaction statistics (in-memory, not durable; local node only). This table is wiped periodically (by default, at least every two hours) +4294967249 4294967123 0 defined partitions for all tables/indexes accessible by the current user in the current database (KV scan) +4294967224 4294967123 0 table descriptors accessible by current user, including non-public and virtual (KV scan; expensive!) +4294967248 4294967123 0 comments for predefined virtual tables (RAM/static) +4294967247 4294967123 0 range metadata without leaseholder details (KV join; expensive!) +4294967228 4294967123 0 available regions for the cluster +4294967244 4294967123 0 ongoing schema changes, across all descriptors accessible by current user (KV scan; expensive!) +4294967243 4294967123 0 session trace accumulated so far (RAM) +4294967242 4294967123 0 session variables (RAM) +4294967223 4294967123 0 list super regions of databases visible to the current user +4294967240 4294967123 0 details for all columns accessible by current user in current database (KV scan) +4294967239 4294967123 0 indexes accessible by current user in current database (KV scan) +4294967237 4294967123 0 stats for all tables accessible by current user in current database as of 10s ago +4294967238 4294967123 0 table descriptors accessible by current user, including non-public and virtual (KV scan; expensive!) +4294967266 4294967123 0 cluster-wide transaction contention events. Querying this table is an +4294967234 4294967123 0 decoded zone configurations from system.zones (KV scan) +4294967221 4294967123 0 roles for which the current user has admin option +4294967220 4294967123 0 roles available to the current user +4294967219 4294967123 0 attributes was created for compatibility and is currently unimplemented +4294967218 4294967123 0 character sets available in the current database +4294967217 4294967123 0 check_constraint_routine_usage was created for compatibility and is currently unimplemented +4294967216 4294967123 0 check constraints +4294967215 4294967123 0 identifies which character set the available collations are +4294967214 4294967123 0 shows the collations available in the current database +4294967213 4294967123 0 column_column_usage was created for compatibility and is currently unimplemented +4294967212 4294967123 0 column_domain_usage was created for compatibility and is currently unimplemented +4294967211 4294967123 0 column_options was created for compatibility and is currently unimplemented +4294967210 4294967123 0 column privilege grants (incomplete) +4294967209 4294967123 0 column_statistics was created for compatibility and is currently unimplemented +4294967208 4294967123 0 columns with user defined types +4294967206 4294967123 0 table and view columns (incomplete) +4294967207 4294967123 0 columns_extensions was created for compatibility and is currently unimplemented +4294967205 4294967123 0 columns usage by constraints +4294967204 4294967123 0 constraint_table_usage was created for compatibility and is currently unimplemented +4294967203 4294967123 0 data_type_privileges was created for compatibility and is currently unimplemented +4294967202 4294967123 0 domain_constraints was created for compatibility and is currently unimplemented +4294967201 4294967123 0 domain_udt_usage was created for compatibility and is currently unimplemented +4294967200 4294967123 0 domains was created for compatibility and is currently unimplemented +4294967199 4294967123 0 element_types was created for compatibility and is currently unimplemented +4294967198 4294967123 0 roles for the current user +4294967197 4294967123 0 engines was created for compatibility and is currently unimplemented +4294967196 4294967123 0 events was created for compatibility and is currently unimplemented +4294967195 4294967123 0 files was created for compatibility and is currently unimplemented +4294967194 4294967123 0 foreign_data_wrapper_options was created for compatibility and is currently unimplemented +4294967193 4294967123 0 foreign_data_wrappers was created for compatibility and is currently unimplemented +4294967192 4294967123 0 foreign_server_options was created for compatibility and is currently unimplemented +4294967191 4294967123 0 foreign_servers was created for compatibility and is currently unimplemented +4294967190 4294967123 0 foreign_table_options was created for compatibility and is currently unimplemented +4294967189 4294967123 0 foreign_tables was created for compatibility and is currently unimplemented +4294967188 4294967123 0 information_schema_catalog_name was created for compatibility and is currently unimplemented +4294967187 4294967123 0 column usage by indexes and key constraints +4294967186 4294967123 0 keywords was created for compatibility and is currently unimplemented +4294967185 4294967123 0 optimizer_trace was created for compatibility and is currently unimplemented +4294967184 4294967123 0 built-in function parameters (empty - introspection not yet supported) +4294967183 4294967123 0 partitions was created for compatibility and is currently unimplemented +4294967182 4294967123 0 plugins was created for compatibility and is currently unimplemented +4294967181 4294967123 0 processlist was created for compatibility and is currently unimplemented +4294967180 4294967123 0 profiling was created for compatibility and is currently unimplemented +4294967179 4294967123 0 foreign key constraints +4294967178 4294967123 0 resource_groups was created for compatibility and is currently unimplemented +4294967177 4294967123 0 role_column_grants was created for compatibility and is currently unimplemented +4294967176 4294967123 0 role_routine_grants was created for compatibility and is currently unimplemented +4294967175 4294967123 0 privileges granted on table or views (incomplete; see also information_schema.table_privileges; may contain excess users or roles) +4294967174 4294967123 0 role_udt_grants was created for compatibility and is currently unimplemented +4294967173 4294967123 0 role_usage_grants was created for compatibility and is currently unimplemented +4294967172 4294967123 0 routine_privileges was created for compatibility and is currently unimplemented +4294967171 4294967123 0 built-in functions (empty - introspection not yet supported) +4294967164 4294967123 0 schema privileges (incomplete; may contain excess users or roles) +4294967165 4294967123 0 database schemas (may contain schemata without permission) +4294967166 4294967123 0 schemata_extensions was created for compatibility and is currently unimplemented +4294967163 4294967123 0 sequences +4294967162 4294967123 0 exposes the session variables. +4294967170 4294967123 0 sql_features was created for compatibility and is currently unimplemented +4294967169 4294967123 0 sql_implementation_info was created for compatibility and is currently unimplemented +4294967168 4294967123 0 sql_parts was created for compatibility and is currently unimplemented +4294967167 4294967123 0 sql_sizing was created for compatibility and is currently unimplemented +4294967161 4294967123 0 st_geometry_columns was created for compatibility and is currently unimplemented +4294967160 4294967123 0 st_spatial_reference_systems was created for compatibility and is currently unimplemented +4294967159 4294967123 0 st_units_of_measure was created for compatibility and is currently unimplemented +4294967158 4294967123 0 index metadata and statistics (incomplete) +4294967157 4294967123 0 table constraints +4294967156 4294967123 0 table_constraints_extensions was created for compatibility and is currently unimplemented +4294967155 4294967123 0 privileges granted on table or views (incomplete; may contain excess users or roles) +4294967153 4294967123 0 tables and views +4294967154 4294967123 0 tables_extensions was created for compatibility and is currently unimplemented +4294967151 4294967123 0 tablespaces was created for compatibility and is currently unimplemented +4294967152 4294967123 0 tablespaces_extensions was created for compatibility and is currently unimplemented +4294967150 4294967123 0 transforms was created for compatibility and is currently unimplemented +4294967149 4294967123 0 triggered_update_columns was created for compatibility and is currently unimplemented +4294967148 4294967123 0 triggers was created for compatibility and is currently unimplemented +4294967147 4294967123 0 type privileges (incomplete; may contain excess users or roles) +4294967146 4294967123 0 udt_privileges was created for compatibility and is currently unimplemented +4294967145 4294967123 0 usage_privileges was created for compatibility and is currently unimplemented +4294967144 4294967123 0 user_attributes was created for compatibility and is currently unimplemented +4294967143 4294967123 0 user_defined_types was created for compatibility and is currently unimplemented +4294967142 4294967123 0 user_mapping_options was created for compatibility and is currently unimplemented +4294967141 4294967123 0 user_mappings was created for compatibility and is currently unimplemented +4294967140 4294967123 0 grantable privileges (incomplete) +4294967139 4294967123 0 view_column_usage was created for compatibility and is currently unimplemented +4294967138 4294967123 0 view_routine_usage was created for compatibility and is currently unimplemented +4294967137 4294967123 0 view_table_usage was created for compatibility and is currently unimplemented +4294967136 4294967123 0 views (incomplete) +4294967134 4294967123 0 aggregated built-in functions (incomplete) +4294967133 4294967123 0 index access methods (incomplete) +4294967132 4294967123 0 pg_amop was created for compatibility and is currently unimplemented +4294967131 4294967123 0 pg_amproc was created for compatibility and is currently unimplemented +4294967130 4294967123 0 column default values +4294967129 4294967123 0 table columns (incomplete - see also information_schema.columns) +4294967127 4294967123 0 role membership +4294967128 4294967123 0 authorization identifiers - differs from postgres as we do not display passwords, +4294967126 4294967123 0 pg_available_extension_versions was created for compatibility and is currently unimplemented +4294967125 4294967123 0 available extensions +4294967124 4294967123 0 casts (empty - needs filling out) +4294967123 4294967123 0 tables and relation-like objects (incomplete - see also information_schema.tables/sequences/views) +4294967122 4294967123 0 available collations (incomplete) +4294967121 4294967123 0 pg_config was created for compatibility and is currently unimplemented +4294967120 4294967123 0 table constraints (incomplete - see also information_schema.table_constraints) +4294967119 4294967123 0 encoding conversions (empty - unimplemented) +4294967118 4294967123 0 contains currently active SQL cursors created with DECLARE +4294967117 4294967123 0 available databases (incomplete) +4294967116 4294967123 0 contains the default values that have been configured for session variables +4294967115 4294967123 0 default ACLs; these are the privileges that will be assigned to newly created objects +4294967114 4294967123 0 dependency relationships (incomplete) +4294967113 4294967123 0 object comments +4294967112 4294967123 0 enum types and labels (empty - feature does not exist) +4294967111 4294967123 0 event triggers (empty - feature does not exist) +4294967110 4294967123 0 installed extensions (empty - feature does not exist) +4294967109 4294967123 0 pg_file_settings was created for compatibility and is currently unimplemented +4294967108 4294967123 0 foreign data wrappers (empty - feature does not exist) +4294967107 4294967123 0 foreign servers (empty - feature does not exist) +4294967106 4294967123 0 foreign tables (empty - feature does not exist) +4294967105 4294967123 0 pg_group was created for compatibility and is currently unimplemented +4294967104 4294967123 0 pg_hba_file_rules was created for compatibility and is currently unimplemented +4294967103 4294967123 0 indexes (incomplete) +4294967102 4294967123 0 index creation statements +4294967101 4294967123 0 table inheritance hierarchy (empty - feature does not exist) +4294967100 4294967123 0 pg_init_privs was created for compatibility and is currently unimplemented +4294967099 4294967123 0 available languages (empty - feature does not exist) +4294967097 4294967123 0 pg_largeobject was created for compatibility and is currently unimplemented +4294967098 4294967123 0 pg_largeobject_metadata was created for compatibility and is currently unimplemented +4294967096 4294967123 0 locks held by active processes (empty - feature does not exist) +4294967095 4294967123 0 available materialized views (empty - feature does not exist) +4294967094 4294967123 0 available namespaces (incomplete; namespaces and databases are congruent in CockroachDB) +4294967093 4294967123 0 opclass (empty - Operator classes not supported yet) +4294967092 4294967123 0 operators (incomplete) +4294967091 4294967123 0 pg_opfamily was created for compatibility and is currently unimplemented +4294967090 4294967123 0 pg_partitioned_table was created for compatibility and is currently unimplemented +4294967089 4294967123 0 pg_policies was created for compatibility and is currently unimplemented +4294967088 4294967123 0 pg_policy was created for compatibility and is currently unimplemented +4294967087 4294967123 0 prepared statements +4294967086 4294967123 0 prepared transactions (empty - feature does not exist) +4294967085 4294967123 0 built-in functions (incomplete) +4294967083 4294967123 0 pg_publication was created for compatibility and is currently unimplemented +4294967084 4294967123 0 pg_publication_rel was created for compatibility and is currently unimplemented +4294967082 4294967123 0 pg_publication_tables was created for compatibility and is currently unimplemented +4294967081 4294967123 0 range types (empty - feature does not exist) +4294967079 4294967123 0 pg_replication_origin was created for compatibility and is currently unimplemented +4294967080 4294967123 0 pg_replication_origin_status was created for compatibility and is currently unimplemented +4294967078 4294967123 0 pg_replication_slots was created for compatibility and is currently unimplemented +4294967077 4294967123 0 rewrite rules (only for referencing on pg_depend for table-view dependencies) +4294967076 4294967123 0 database roles +4294967075 4294967123 0 pg_rules was created for compatibility and is currently unimplemented +4294967073 4294967123 0 security labels (empty - feature does not exist) +4294967074 4294967123 0 security labels (empty) +4294967072 4294967123 0 sequences (see also information_schema.sequences) +4294967071 4294967123 0 pg_sequences is very similar as pg_sequence. +4294967070 4294967123 0 session variables (incomplete) +4294967069 4294967123 0 pg_shadow lists properties for roles that are marked as rolcanlogin in pg_authid +4294967066 4294967123 0 Shared Dependencies (Roles depending on objects). +4294967068 4294967123 0 shared object comments +4294967065 4294967123 0 pg_shmem_allocations was created for compatibility and is currently unimplemented +4294967067 4294967123 0 shared security labels (empty - feature not supported) +4294967064 4294967123 0 backend access statistics (empty - monitoring works differently in CockroachDB) +4294967063 4294967123 0 pg_stat_all_indexes was created for compatibility and is currently unimplemented +4294967062 4294967123 0 pg_stat_all_tables was created for compatibility and is currently unimplemented +4294967061 4294967123 0 pg_stat_archiver was created for compatibility and is currently unimplemented +4294967060 4294967123 0 pg_stat_bgwriter was created for compatibility and is currently unimplemented +4294967058 4294967123 0 pg_stat_database was created for compatibility and is currently unimplemented +4294967059 4294967123 0 pg_stat_database_conflicts was created for compatibility and is currently unimplemented +4294967057 4294967123 0 pg_stat_gssapi was created for compatibility and is currently unimplemented +4294967056 4294967123 0 pg_stat_progress_analyze was created for compatibility and is currently unimplemented +4294967055 4294967123 0 pg_stat_progress_basebackup was created for compatibility and is currently unimplemented +4294967054 4294967123 0 pg_stat_progress_cluster was created for compatibility and is currently unimplemented +4294967053 4294967123 0 pg_stat_progress_create_index was created for compatibility and is currently unimplemented +4294967052 4294967123 0 pg_stat_progress_vacuum was created for compatibility and is currently unimplemented +4294967051 4294967123 0 pg_stat_replication was created for compatibility and is currently unimplemented +4294967050 4294967123 0 pg_stat_slru was created for compatibility and is currently unimplemented +4294967049 4294967123 0 pg_stat_ssl was created for compatibility and is currently unimplemented +4294967048 4294967123 0 pg_stat_subscription was created for compatibility and is currently unimplemented +4294967047 4294967123 0 pg_stat_sys_indexes was created for compatibility and is currently unimplemented +4294967046 4294967123 0 pg_stat_sys_tables was created for compatibility and is currently unimplemented +4294967045 4294967123 0 pg_stat_user_functions was created for compatibility and is currently unimplemented +4294967044 4294967123 0 pg_stat_user_indexes was created for compatibility and is currently unimplemented +4294967043 4294967123 0 pg_stat_user_tables was created for compatibility and is currently unimplemented +4294967042 4294967123 0 pg_stat_wal_receiver was created for compatibility and is currently unimplemented +4294967041 4294967123 0 pg_stat_xact_all_tables was created for compatibility and is currently unimplemented +4294967040 4294967123 0 pg_stat_xact_sys_tables was created for compatibility and is currently unimplemented +4294967039 4294967123 0 pg_stat_xact_user_functions was created for compatibility and is currently unimplemented +4294967038 4294967123 0 pg_stat_xact_user_tables was created for compatibility and is currently unimplemented +4294967037 4294967123 0 pg_statio_all_indexes was created for compatibility and is currently unimplemented +4294967036 4294967123 0 pg_statio_all_sequences was created for compatibility and is currently unimplemented +4294967035 4294967123 0 pg_statio_all_tables was created for compatibility and is currently unimplemented +4294967034 4294967123 0 pg_statio_sys_indexes was created for compatibility and is currently unimplemented +4294967033 4294967123 0 pg_statio_sys_sequences was created for compatibility and is currently unimplemented +4294967032 4294967123 0 pg_statio_sys_tables was created for compatibility and is currently unimplemented +4294967031 4294967123 0 pg_statio_user_indexes was created for compatibility and is currently unimplemented +4294967030 4294967123 0 pg_statio_user_sequences was created for compatibility and is currently unimplemented +4294967029 4294967123 0 pg_statio_user_tables was created for compatibility and is currently unimplemented +4294967026 4294967123 0 pg_statistic was created for compatibility and is currently unimplemented +4294967027 4294967123 0 pg_statistic_ext has the statistics objects created with CREATE STATISTICS +4294967028 4294967123 0 pg_statistic_ext_data was created for compatibility and is currently unimplemented +4294967024 4294967123 0 pg_stats was created for compatibility and is currently unimplemented +4294967025 4294967123 0 pg_stats_ext was created for compatibility and is currently unimplemented +4294967022 4294967123 0 pg_subscription was created for compatibility and is currently unimplemented +4294967023 4294967123 0 pg_subscription_rel was created for compatibility and is currently unimplemented +4294967021 4294967123 0 tables summary (see also information_schema.tables, pg_catalog.pg_class) +4294967020 4294967123 0 available tablespaces (incomplete; concept inapplicable to CockroachDB) +4294967019 4294967123 0 pg_timezone_abbrevs was created for compatibility and is currently unimplemented +4294967018 4294967123 0 pg_timezone_names was created for compatibility and is currently unimplemented +4294967017 4294967123 0 pg_transform was created for compatibility and is currently unimplemented +4294967016 4294967123 0 triggers (empty - feature does not exist) +4294967014 4294967123 0 pg_ts_config was created for compatibility and is currently unimplemented +4294967015 4294967123 0 pg_ts_config_map was created for compatibility and is currently unimplemented +4294967013 4294967123 0 pg_ts_dict was created for compatibility and is currently unimplemented +4294967012 4294967123 0 pg_ts_parser was created for compatibility and is currently unimplemented +4294967011 4294967123 0 pg_ts_template was created for compatibility and is currently unimplemented +4294967010 4294967123 0 scalar types (incomplete) +4294967007 4294967123 0 database users +4294967009 4294967123 0 local to remote user mapping (empty - feature does not exist) +4294967008 4294967123 0 pg_user_mappings was created for compatibility and is currently unimplemented +4294967006 4294967123 0 view definitions (incomplete - see also information_schema.views) +4294967004 4294967123 0 Shows all defined geography columns. Matches PostGIS' geography_columns functionality. +4294967003 4294967123 0 Shows all defined geometry columns. Matches PostGIS' geometry_columns functionality. +4294967002 4294967123 0 Shows all defined Spatial Reference Identifiers (SRIDs). Matches PostGIS' spatial_ref_sys table. ## pg_catalog.pg_shdescription @@ -5368,7 +5373,7 @@ indoption query TTI SELECT database_name, descriptor_name, descriptor_id from test.crdb_internal.create_statements where descriptor_name = 'pg_views' ---- -test pg_views 4294967007 +test pg_views 4294967006 # Verify INCLUDED columns appear in pg_index. See issue #59563 statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/table b/pkg/sql/logictest/testdata/logic_test/table index d3eada2e2a4c..cf4a86622488 100644 --- a/pkg/sql/logictest/testdata/logic_test/table +++ b/pkg/sql/logictest/testdata/logic_test/table @@ -561,6 +561,7 @@ cluster_contended_tables NULL cluster_contention_events NULL cluster_database_privileges NULL cluster_distsql_flows NULL +cluster_execution_insights NULL cluster_inflight_traces NULL cluster_locks NULL cluster_queries NULL diff --git a/pkg/sql/logictest/testdata/logic_test/udf b/pkg/sql/logictest/testdata/logic_test/udf index ab2912694dd3..ffcd428269e6 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf +++ b/pkg/sql/logictest/testdata/logic_test/udf @@ -295,9 +295,6 @@ WHERE id = $max_desc_id; } } -statement error pq: unimplemented: drop function not supported.* -DROP FUNCTION f - statement error pq: unimplemented: alter function not supported.* ALTER FUNCTION f() IMMUTABLE @@ -548,3 +545,254 @@ query T SELECT 999999::regproc; ---- 999999 + +subtest drop_function + +statement ok +CREATE FUNCTION f_test_drop() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +statement ok +CREATE FUNCTION f_test_drop(int) RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +statement ok +CREATE SCHEMA sc1 + +statement ok +CREATE FUNCTION sc1.f_test_drop(int) RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +statement ok +SET search_path = public,sc1 + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +---- +CREATE FUNCTION public.f_test_drop() + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ +CREATE FUNCTION public.f_test_drop(IN INT8) + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +---- +CREATE FUNCTION sc1.f_test_drop(IN INT8) + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +statement error pq: function name \"f_test_drop\" is not unique +DROP FUNCTION f_test_drop; + +statement ok +DROP FUNCTION IF EXISTS f_not_existing; + +statement error pq: unknown function: f_not_existing\(\): function undefined +DROP FUNCTION f_not_existing; + +# drop a function twice should fail. +statement error pq: function f_test_drop\(\) does not exist: function undefined +BEGIN; +DROP FUNCTION f_test_drop(); +DROP FUNCTION f_test_drop(); +COMMIT; + +statement ok +ROLLBACK; + +statement ok +DROP FUNCTION f_test_drop(); + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +---- +CREATE FUNCTION public.f_test_drop(IN INT8) + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +---- +CREATE FUNCTION sc1.f_test_drop(IN INT8) + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +# Drop with two identical function signatures should be ok. And only first match +# in path should be drop. +statement ok +DROP FUNCTION f_test_drop(INT), f_test_drop(INT); + +statement error pq: function public.f_test_drop does not exist +SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +---- +CREATE FUNCTION sc1.f_test_drop(IN INT8) + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +statement ok +DROP FUNCTION f_test_drop(INT); + +statement error pq: function sc1.f_test_drop does not exist +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; + +# If there are identical function signatures in different schemas, multiple drop +# statements should drop them all. This matches postgres behavior. +statement ok +CREATE FUNCTION public.f_test_drop() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; +CREATE FUNCTION sc1.f_test_drop() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +---- +CREATE FUNCTION public.f_test_drop() + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +---- +CREATE FUNCTION sc1.f_test_drop() + RETURNS INT8 + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT 1; +$$ + +statement ok; +BEGIN; +DROP FUNCTION f_test_drop(); +DROP FUNCTION f_test_drop(); +COMMIT; + +statement error pq: function public.f_test_drop does not exist +SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; + +statement error pq: function sc1.f_test_drop does not exist +SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; + +statement ok +SET search_path = public + +statement ok +DROP SCHEMA sc1; + +subtest disallow_udf_in_table + +statement ok +CREATE FUNCTION test_tbl_f() RETURNS INT IMMUTABLE LANGUAGE SQL AS $$ SELECT 1 $$; + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT DEFAULT (test_tbl_f() + 1)); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT ON UPDATE (test_tbl_f() + 1)); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT AS (test_tbl_f() + 1) STORED); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT CHECK (test_tbl_f() > 0)); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT, INDEX idx_b(test_tbl_f())); + +statement ok +CREATE TABLE test_tbl_t (a INT PRIMARY KEY, b INT); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE INDEX t_idx ON test_tbl_t(test_tbl_f()); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +CREATE INDEX t_idx ON test_tbl_t(b) WHERE test_tbl_f() > 0; + +statement error pq: unimplemented: usage of user-defined function from relations not supported +ALTER TABLE test_tbl_t ADD CONSTRAINT bgt CHECK (test_tbl_f() > 1); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +ALTER TABLE test_tbl_t ADD COLUMN c int CHECK (test_tbl_f() > 0); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +ALTER TABLE test_tbl_t ADD COLUMN c int AS (test_tbl_f()) stored; + +statement error pq: unimplemented: usage of user-defined function from relations not supported +ALTER TABLE test_tbl_t ADD COLUMN c int DEFAULT (test_tbl_f()); + +statement error pq: unimplemented: usage of user-defined function from relations not supported +ALTER TABLE test_tbl_t ADD COLUMN c int ON UPDATE (test_tbl_f()); + +subtest disallow_udf_in_views_and_udf + +statement ok +CREATE FUNCTION test_vf_f() RETURNS STRING LANGUAGE SQL AS $$ SELECT lower('hello') $$; + +statement error pq: unknown function: test_vf_f\(\): function undefined +CREATE FUNCTION test_vf_g() RETURNS STRING LANGUAGE SQL AS $$ SELECT test_vf_f() $$; + +statement ok +CREATE FUNCTION test_vf_g() RETURNS STRING LANGUAGE SQL AS $$ SELECT lower('hello') $$; + +statement error pq: unknown function: test_vf_f\(\): function undefined +CREATE VIEW v AS SELECT test_vf_f(); + +statement ok +CREATE VIEW v AS SELECT lower('hello'); + +query T +SELECT @2 FROM [SHOW CREATE FUNCTION test_vf_f]; +---- +CREATE FUNCTION public.test_vf_f() + RETURNS STRING + VOLATILE + NOT LEAKPROOF + CALLED ON NULL INPUT + LANGUAGE SQL + AS $$ + SELECT lower('hello'); +$$ diff --git a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join index f8b4c1f6262d..c17edc5be6ae 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join +++ b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join @@ -4,10 +4,10 @@ statement ok CREATE TABLE abc (a INT, b INT, c INT, PRIMARY KEY (a, c)) statement ok -CREATE TABLE def (d INT, e INT, f INT, PRIMARY KEY (f, e)) +CREATE TABLE def (d INT, e INT, f INT, PRIMARY KEY (f, e), INDEX desc_idx (f, e DESC) STORING (d)) statement ok -CREATE TABLE def_e_decimal (d INT, e DECIMAL, f INT, PRIMARY KEY (f, e)) +CREATE TABLE def_e_decimal (d INT, e DECIMAL, f INT, PRIMARY KEY (f, e), INDEX desc_idx (f, e DESC) STORING (d)) # Set up the statistics as if the first table is much smaller than the second. # This will make lookup join into the second table be the best plan. @@ -96,9 +96,26 @@ vectorized: true table: abc@abc_pkey spans: /2- -# The filter on 'e' is a contradiction. At the moment, we're handling it as the -# ON expression (the optimizer should be smart enough to avoid execution -# altogether, #80402). +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def@desc_idx ON f = b WHERE a > 1 AND e > 1 +---- +distribution: local +vectorized: true +· +• lookup join (inner) +│ columns: (a, b, c, d, e, f) +│ estimated row count: 33 +│ table: def@desc_idx +│ lookup condition: (b = f) AND (e > 1) +│ +└── • scan + columns: (a, b, c) + estimated row count: 33 (33% of the table; stats collected ago) + table: abc@abc_pkey + spans: /2- + +# The filter on 'e' is a contradiction. The optimizer should be smart enough to +# avoid execution altogether, #80402. query T EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def ON f = b WHERE a > 1 AND e > 9223372036854775807 ---- @@ -109,8 +126,7 @@ vectorized: true │ columns: (a, b, c, d, e, f) │ estimated row count: 33 │ table: def@def_pkey -│ equality: (b) = (f) -│ pred: e > 9223372036854775807 +│ lookup condition: (b = f) AND (e > 9223372036854775807) │ └── • scan columns: (a, b, c) @@ -118,8 +134,8 @@ vectorized: true table: abc@abc_pkey spans: /2- -# Decimals don't support Next / Prev calls, so we handle the filter on 'e' as -# the ON expression. +# Decimals don't support Next / Prev calls, but the index column is ASC so +# we can still use the (e > 1) filter in the lookup condition. query T EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal ON f = b WHERE a > 1 AND e > 1 ---- @@ -130,8 +146,48 @@ vectorized: true │ columns: (a, b, c, d, e, f) │ estimated row count: 33 │ table: def_e_decimal@def_e_decimal_pkey +│ lookup condition: (b = f) AND (e > 1) +│ +└── • scan + columns: (a, b, c) + estimated row count: 33 (33% of the table; stats collected ago) + table: abc@abc_pkey + spans: /2- + +# Decimals don't support Next / Prev calls, but the inequality is inclusive so +# we can still use the (e >= 1) filter in the lookup condition. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal@desc_idx ON f = b WHERE a > 1 AND e >= 1 +---- +distribution: local +vectorized: true +· +• lookup join (inner) +│ columns: (a, b, c, d, e, f) +│ estimated row count: 33 +│ table: def_e_decimal@desc_idx +│ lookup condition: (b = f) AND (e >= 1) +│ +└── • scan + columns: (a, b, c) + estimated row count: 33 (33% of the table; stats collected ago) + table: abc@abc_pkey + spans: /2- + +# Decimals don't support Next / Prev calls and the index column is DESC so +# we handle the (e < 1) filter in the ON expression. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal@desc_idx ON f = b WHERE a > 1 AND e < 1 +---- +distribution: local +vectorized: true +· +• lookup join (inner) +│ columns: (a, b, c, d, e, f) +│ estimated row count: 33 +│ table: def_e_decimal@desc_idx │ equality: (b) = (f) -│ pred: e > 1 +│ pred: e < 1 │ └── • scan columns: (a, b, c) @@ -158,6 +214,7 @@ vectorized: true table: abc@abc_pkey spans: /2- +# Inclusive inequality referencing an input column. query T EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def ON f = b WHERE a >= e ---- @@ -168,8 +225,26 @@ vectorized: true │ columns: (a, b, c, d, e, f) │ estimated row count: 33 │ table: def@def_pkey -│ equality: (b) = (f) -│ pred: a >= e +│ lookup condition: (b = f) AND (a >= e) +│ +└── • scan + columns: (a, b, c) + estimated row count: 100 (100% of the table; stats collected ago) + table: abc@abc_pkey + spans: FULL SCAN + +# Inclusive inequality on a descending index column referencing an input column. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def@desc_idx ON f = b WHERE a >= e +---- +distribution: local +vectorized: true +· +• lookup join (inner) +│ columns: (a, b, c, d, e, f) +│ estimated row count: 33 +│ table: def@desc_idx +│ lookup condition: (b = f) AND (a >= e) │ └── • scan columns: (a, b, c) @@ -177,8 +252,9 @@ vectorized: true table: abc@abc_pkey spans: FULL SCAN +# Exclusive inequality referencing an input column. query T -EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def ON f = b AND a >= e +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def ON f = b AND a > e ---- distribution: local vectorized: true @@ -187,8 +263,26 @@ vectorized: true │ columns: (a, b, c, d, e, f) │ estimated row count: 33 │ table: def@def_pkey -│ equality: (b) = (f) -│ pred: a >= e +│ lookup condition: (b = f) AND (a > e) +│ +└── • scan + columns: (a, b, c) + estimated row count: 100 (100% of the table; stats collected ago) + table: abc@abc_pkey + spans: FULL SCAN + +# Exclusive inequality on a descending index column referencing an input column. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def@desc_idx ON f = b AND a > e +---- +distribution: local +vectorized: true +· +• lookup join (inner) +│ columns: (a, b, c, d, e, f) +│ estimated row count: 33 +│ table: def@desc_idx +│ lookup condition: (b = f) AND (a > e) │ └── • scan columns: (a, b, c) @@ -196,6 +290,66 @@ vectorized: true table: abc@abc_pkey spans: FULL SCAN +# Inequality on a decimal column. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal ON f = b AND a::DECIMAL >= e +---- +distribution: local +vectorized: true +· +• project +│ columns: (a, b, c, d, e, f) +│ +└── • lookup join (inner) + │ columns: (column11, a, b, c, d, e, f) + │ estimated row count: 33 + │ table: def_e_decimal@def_e_decimal_pkey + │ lookup condition: (b = f) AND (column11 >= e) + │ + └── • render + │ columns: (column11, a, b, c) + │ render column11: a::DECIMAL + │ render a: a + │ render b: b + │ render c: c + │ + └── • scan + columns: (a, b, c) + estimated row count: 100 (100% of the table; stats collected ago) + table: abc@abc_pkey + spans: FULL SCAN + +# Inequality on a descending decimal index column. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal@desc_idx ON f = b AND a::DECIMAL >= e +---- +distribution: local +vectorized: true +· +• project +│ columns: (a, b, c, d, e, f) +│ +└── • lookup join (inner) + │ columns: (column11, a, b, c, d, e, f) + │ estimated row count: 33 + │ table: def_e_decimal@desc_idx + │ lookup condition: (b = f) AND (column11 >= e) + │ + └── • render + │ columns: (column11, a, b, c) + │ render column11: a::DECIMAL + │ render a: a + │ render b: b + │ render c: c + │ + └── • scan + columns: (a, b, c) + estimated row count: 100 (100% of the table; stats collected ago) + table: abc@abc_pkey + spans: FULL SCAN + +# The inequality has to be in the ON condition because the columns are +# different types. query T EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal ON f = b AND a >= e ---- @@ -215,6 +369,37 @@ vectorized: true table: abc@abc_pkey spans: FULL SCAN +# The inequality has to be in the ON condition because decimals don't support +# Prev calls. +query T +EXPLAIN (VERBOSE) SELECT * FROM abc JOIN def_e_decimal@desc_idx ON f = b AND a::DECIMAL > e +---- +distribution: local +vectorized: true +· +• project +│ columns: (a, b, c, d, e, f) +│ +└── • lookup join (inner) + │ columns: (column11, a, b, c, d, e, f) + │ estimated row count: 33 + │ table: def_e_decimal@desc_idx + │ equality: (b) = (f) + │ pred: column11 > e + │ + └── • render + │ columns: (column11, a, b, c) + │ render column11: a::DECIMAL + │ render a: a + │ render b: b + │ render c: c + │ + └── • scan + columns: (a, b, c) + estimated row count: 100 (100% of the table; stats collected ago) + table: abc@abc_pkey + spans: FULL SCAN + # Verify a distsql plan. statement ok CREATE TABLE data (a INT, b INT, c INT, d INT, PRIMARY KEY (a, b, c, d)) diff --git a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_spans b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_spans index 7efba77b059f..ab5089d79133 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_spans +++ b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_spans @@ -848,6 +848,201 @@ vectorized: true table: metrics@name_index spans: [/'cpu' - /'cpu'] +# Test NULL values in bounded lookup on input column. +query T +EXPLAIN +SELECT * +FROM metric_values@secondary as v +INNER JOIN metrics as m +ON metric_id=id +WHERE + v.nullable BETWEEN -20 AND m.nullable AND + name='cpu' +ORDER BY value +---- +distribution: local +vectorized: true +· +• sort +│ estimated row count: 33 +│ order: +value +│ +└── • lookup join + │ estimated row count: 33 + │ table: metric_values@metric_values_pkey + │ equality: (metric_id, time) = (metric_id,time) + │ equality cols are key + │ + └── • lookup join + │ estimated row count: 33 + │ table: metric_values@secondary + │ lookup condition: ((id = metric_id) AND (nullable <= nullable)) AND (nullable >= -20) + │ + └── • index join + │ estimated row count: 1 + │ table: metrics@metrics_pkey + │ + └── • scan + estimated row count: 1 (10% of the table; stats collected ago) + table: metrics@name_index + spans: [/'cpu' - /'cpu'] + +# Test NULL values in > unbounded lookup on input column. +query T +EXPLAIN +SELECT * +FROM metric_values@secondary as v +INNER JOIN metrics as m +ON metric_id=id +WHERE + v.nullable > m.nullable AND + name='cpu' +ORDER BY value +---- +distribution: local +vectorized: true +· +• sort +│ estimated row count: 33 +│ order: +value +│ +└── • lookup join + │ estimated row count: 33 + │ table: metric_values@metric_values_pkey + │ equality: (metric_id, time) = (metric_id,time) + │ equality cols are key + │ + └── • lookup join + │ estimated row count: 33 + │ table: metric_values@secondary + │ lookup condition: (id = metric_id) AND (nullable > nullable) + │ + └── • index join + │ estimated row count: 1 + │ table: metrics@metrics_pkey + │ + └── • scan + estimated row count: 1 (10% of the table; stats collected ago) + table: metrics@name_index + spans: [/'cpu' - /'cpu'] + +# Test NULL values in >= unbounded lookup on input column. +query T +EXPLAIN +SELECT * +FROM metric_values@secondary as v +INNER JOIN metrics as m +ON metric_id=id +WHERE + v.nullable >= m.nullable AND + name='cpu' +ORDER BY value +---- +distribution: local +vectorized: true +· +• sort +│ estimated row count: 33 +│ order: +value +│ +└── • lookup join + │ estimated row count: 33 + │ table: metric_values@metric_values_pkey + │ equality: (metric_id, time) = (metric_id,time) + │ equality cols are key + │ + └── • lookup join + │ estimated row count: 33 + │ table: metric_values@secondary + │ lookup condition: (id = metric_id) AND (nullable >= nullable) + │ + └── • index join + │ estimated row count: 1 + │ table: metrics@metrics_pkey + │ + └── • scan + estimated row count: 1 (10% of the table; stats collected ago) + table: metrics@name_index + spans: [/'cpu' - /'cpu'] + + +# Test NULL values in < unbounded lookup on input column. +query T +EXPLAIN +SELECT * +FROM metric_values@secondary as v +INNER JOIN metrics as m +ON metric_id=id +WHERE + v.nullable < m.nullable AND + name='cpu' +ORDER BY value +---- +distribution: local +vectorized: true +· +• sort +│ estimated row count: 33 +│ order: +value +│ +└── • lookup join + │ estimated row count: 33 + │ table: metric_values@metric_values_pkey + │ equality: (metric_id, time) = (metric_id,time) + │ equality cols are key + │ + └── • lookup join + │ estimated row count: 33 + │ table: metric_values@secondary + │ lookup condition: (id = metric_id) AND (nullable < nullable) + │ + └── • index join + │ estimated row count: 1 + │ table: metrics@metrics_pkey + │ + └── • scan + estimated row count: 1 (10% of the table; stats collected ago) + table: metrics@name_index + spans: [/'cpu' - /'cpu'] + +# Test NULL values in <= unbounded lookup on input column. +query T +EXPLAIN +SELECT * +FROM metric_values@secondary as v +INNER JOIN metrics as m +ON metric_id=id +WHERE + v.nullable <= m.nullable AND + name='cpu' +ORDER BY value +---- +distribution: local +vectorized: true +· +• sort +│ estimated row count: 33 +│ order: +value +│ +└── • lookup join + │ estimated row count: 33 + │ table: metric_values@metric_values_pkey + │ equality: (metric_id, time) = (metric_id,time) + │ equality cols are key + │ + └── • lookup join + │ estimated row count: 33 + │ table: metric_values@secondary + │ lookup condition: (id = metric_id) AND (nullable <= nullable) + │ + └── • index join + │ estimated row count: 1 + │ table: metrics@metrics_pkey + │ + └── • scan + estimated row count: 1 (10% of the table; stats collected ago) + table: metrics@name_index + spans: [/'cpu' - /'cpu'] # Regression test for issue #68200. This ensures that we properly construct the # span to account for both ends of the inequality. diff --git a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_trace b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_trace index 7f21b95fdd85..b0725241644d 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_trace +++ b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_trace @@ -149,7 +149,7 @@ SET tracing = off; query T SELECT message FROM [SHOW KV TRACE FOR SESSION] WHERE operation = 'join reader' AND message NOT LIKE 'querying next range%' ---- -Scan /Table/109/1/{1/2020-01-01T00:00:00.000001Z-2}, /Table/109/1/{2/2020-01-01T00:00:00.000001Z-3} +Scan /Table/109/1/{1/2020-01-01T00:00:00.000000001Z-2}, /Table/109/1/{2/2020-01-01T00:00:00.000000001Z-3} fetched: /metric_values/metric_values_pkey/1/'2020-01-01 00:00:01+00:00'/nullable/value -> /1/1 fetched: /metric_values/metric_values_pkey/2/'2020-01-01 00:00:01+00:00'/nullable/value -> /2/3 fetched: /metric_values/metric_values_pkey/2/'2020-01-01 00:01:01+00:00'/nullable/value -> /-11/4 diff --git a/pkg/sql/opt/lookupjoin/BUILD.bazel b/pkg/sql/opt/lookupjoin/BUILD.bazel index eafeaf505e4d..022fb4dd1806 100644 --- a/pkg/sql/opt/lookupjoin/BUILD.bazel +++ b/pkg/sql/opt/lookupjoin/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "//pkg/sql/opt/props", "//pkg/sql/sem/eval", "//pkg/sql/sem/tree", + "//pkg/sql/types", "//pkg/util", "@com_github_cockroachdb_errors//:errors", ], diff --git a/pkg/sql/opt/lookupjoin/constraint_builder.go b/pkg/sql/opt/lookupjoin/constraint_builder.go index 11f972b3e84a..e039c3d7e9ca 100644 --- a/pkg/sql/opt/lookupjoin/constraint_builder.go +++ b/pkg/sql/opt/lookupjoin/constraint_builder.go @@ -20,7 +20,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/opt/norm" "github.com/cockroachdb/cockroach/pkg/sql/opt/props" "github.com/cockroachdb/cockroach/pkg/sql/sem/eval" - "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/errors" ) @@ -107,24 +107,14 @@ type ConstraintBuilder struct { // Init initializes a ConstraintBuilder. Once initialized, a ConstraintBuilder // can be reused to build lookup join constraints for all indexes in the given -// table, as long as the join input and ON condition do not change. If no lookup -// join can be built from the given filters and left/right columns, then -// ok=false is returned. +// table, as long as the join input and ON condition do not change. func (b *ConstraintBuilder) Init( f *norm.Factory, md *opt.Metadata, evalCtx *eval.Context, table opt.TableID, leftCols, rightCols opt.ColSet, - onFilters memo.FiltersExpr, -) (ok bool) { - leftEq, _, _ := memo.ExtractJoinEqualityColumns(leftCols, rightCols, onFilters) - if len(leftEq) == 0 { - // Exploring a lookup join is only beneficial if there is at least one - // pair of equality columns in the join filters. - return false - } - +) { // This initialization pattern ensures that fields are not unwittingly // reused. Field reuse must be explicit. *b = ConstraintBuilder{ @@ -135,14 +125,16 @@ func (b *ConstraintBuilder) Init( leftCols: leftCols, rightCols: rightCols, } - return true } // Build returns a Constraint that constrains a lookup join on the given index. // The constraint returned may be unconstrained if no constraint could be built. +// foundEqualityCols indicates whether any equality conditions were used to +// constrain the index columns; this can be used to decide whether to build a +// lookup join. func (b *ConstraintBuilder) Build( index cat.Index, onFilters, optionalFilters memo.FiltersExpr, -) Constraint { +) (_ Constraint, foundEqualityCols bool) { // Extract the equality columns from onFilters. We cannot use the results of // the extraction in Init because onFilters may be reduced by the caller // after Init due to partial index implication. If the filters are reduced, @@ -152,6 +144,11 @@ func (b *ConstraintBuilder) Build( memo.ExtractJoinEqualityColumns(b.leftCols, b.rightCols, onFilters) rightEqSet := rightEq.ToSet() + // Retrieve the inequality columns from onFilters. + _, rightCmp, inequalityFilterOrds := memo.ExtractJoinConditionColumns( + b.leftCols, b.rightCols, onFilters, true, /* inequality */ + ) + allFilters := append(onFilters, optionalFilters...) // Check if the first column in the index either: @@ -160,6 +157,7 @@ func (b *ConstraintBuilder) Build( // 2. Is a computed column for which an equality constraint can be // generated. // 3. Is constrained to a constant value or values. + // 4. Has an inequality constraint between input and index columns. // // This check doesn't guarantee that we will find lookup join key // columns, but it avoids unnecessary work in most cases. @@ -167,7 +165,9 @@ func (b *ConstraintBuilder) Build( if _, ok := rightEq.Find(firstIdxCol); !ok { if _, ok := b.findComputedColJoinEquality(b.table, firstIdxCol, rightEqSet); !ok { if _, _, ok := FindJoinFilterConstants(allFilters, firstIdxCol, b.evalCtx); !ok { - return Constraint{} + if _, ok := rightCmp.Find(firstIdxCol); !ok { + return Constraint{}, false + } } } } @@ -182,8 +182,9 @@ func (b *ConstraintBuilder) Build( var lookupExpr memo.FiltersExpr var constFilters memo.FiltersExpr var filterOrdsToExclude util.FastIntSet - foundEqualityCols := false + foundLookupCols := false lookupExprRequired := false + remainingFilters := make(memo.FiltersExpr, 0, len(onFilters)) // addEqualityColumns adds the given columns as an equality in keyCols if // lookupExprRequired is false. Otherwise, the equality is added as an @@ -221,10 +222,12 @@ func (b *ConstraintBuilder) Build( // the projected columns created must be created in order. for j := 0; j < numIndexKeyCols; j++ { idxCol := b.table.IndexColumnID(index, j) + idxColIsDesc := index.Column(j).Descending if eqIdx, ok := rightEq.Find(idxCol); ok { addEqualityColumns(leftEq[eqIdx], idxCol) filterOrdsToExclude.Add(eqFilterOrds[eqIdx]) foundEqualityCols = true + foundLookupCols = true continue } @@ -251,6 +254,7 @@ func (b *ConstraintBuilder) Build( inputProjections = append(inputProjections, projection) addEqualityColumns(compEqCol, idxCol) foundEqualityCols = true + foundLookupCols = true continue } @@ -300,16 +304,46 @@ func (b *ConstraintBuilder) Build( continue } - // If constant values were not found, try to find a filter that - // constrains this index column to a range. - if allIdx, foundRange := b.findJoinFilterRange(allFilters, idxCol); foundRange { - // Convert previously collected keyCols and rightSideCols to - // expressions in lookupExpr and clear keyCols. + // If constant equality values were not found, try to find filters that + // constrain this index column to a range on input columns. + startIdx, endIdx, foundStart, foundEnd := b.findJoinVariableRangeFilters( + rightCmp, inequalityFilterOrds, allFilters, idxCol, idxColIsDesc, + ) + if foundStart { + convertToLookupExpr() + lookupExpr = append(lookupExpr, allFilters[startIdx]) + filterOrdsToExclude.Add(startIdx) + foundLookupCols = true + } + if foundEnd { convertToLookupExpr() + lookupExpr = append(lookupExpr, allFilters[endIdx]) + filterOrdsToExclude.Add(endIdx) + foundLookupCols = true + } + if foundStart && foundEnd { + // The column is constrained above and below by an inequality; no further + // expressions can be added to the lookup. + break + } - lookupExpr = append(lookupExpr, allFilters[allIdx]) - constFilters = append(constFilters, allFilters[allIdx]) - filterOrdsToExclude.Add(allIdx) + // If no variable range expressions were found, try to find a filter that + // constrains this index column to a range on constant values. It may be the + // case that only the start or end bound could be constrained with + // an input column; in this case, it still may be possible to use a constant + // to form the other bound. + rangeFilter, remaining, filterIdx := b.findJoinConstantRangeFilter( + allFilters, idxCol, idxColIsDesc, !foundStart, !foundEnd, + ) + if rangeFilter != nil { + // A constant range filter could be found. + convertToLookupExpr() + lookupExpr = append(lookupExpr, *rangeFilter) + constFilters = append(constFilters, *rangeFilter) + filterOrdsToExclude.Add(filterIdx) + if remaining != nil { + remainingFilters = append(remainingFilters, *remaining) + } } // Either a range was found, or the index column cannot be constrained. @@ -318,10 +352,10 @@ func (b *ConstraintBuilder) Build( break } - // Lookup join constraints that contain no equality columns (e.g., a lookup + // Lookup join constraints that contain no lookup columns (e.g., a lookup // expression x=1) are not useful. - if !foundEqualityCols { - return Constraint{} + if !foundLookupCols { + return Constraint{}, false } if len(keyCols) > 0 && len(lookupExpr) > 0 { @@ -337,14 +371,14 @@ func (b *ConstraintBuilder) Build( } // Reduce the remaining filters. - c.RemainingFilters = make(memo.FiltersExpr, 0, len(onFilters)) for i := range onFilters { if !filterOrdsToExclude.Contains(i) { - c.RemainingFilters = append(c.RemainingFilters, onFilters[i]) + remainingFilters = append(remainingFilters, onFilters[i]) } } + c.RemainingFilters = remainingFilters - return c + return c, foundEqualityCols } // findComputedColJoinEquality returns the computed column expression of col and @@ -419,69 +453,155 @@ func (b *ConstraintBuilder) findComputedColJoinEquality( return expr, true } -// findJoinFilterRange tries to find an inequality range for this column. -func (b *ConstraintBuilder) findJoinFilterRange( - filters memo.FiltersExpr, col opt.ColumnID, -) (filterIdx int, ok bool) { - // canAdvance returns whether non-nil, non-NULL datum can be "advanced" - // (i.e. both Next and Prev can be called on it). - canAdvance := func(val tree.Datum) bool { - if val.IsMax(b.evalCtx) { - return false +// findJoinVariableRangeFilters attempts to find inequality constraints for the +// given index column that reference input columns (not constants). If either +// (or both) start and end bounds are found, findJoinVariableInequalityFilter +// returns the corresponding filter indices. +func (b *ConstraintBuilder) findJoinVariableRangeFilters( + rightCmp opt.ColList, + inequalityFilterOrds []int, + filters memo.FiltersExpr, + idxCol opt.ColumnID, + idxColIsDesc bool, +) (startIdx, endIdx int, foundStart, foundEnd bool) { + // Iterate through the extracted variable inequality filters to see if any + // can be used to constrain the index column. + for i := range rightCmp { + if foundStart && foundEnd { + break } - _, ok := val.Next(b.evalCtx) - if !ok { - return false + if rightCmp[i] != idxCol { + continue } - if val.IsMin(b.evalCtx) { - return false + cond := filters[inequalityFilterOrds[i]].Condition + op := cond.Op() + if cond.Child(0).(*memo.VariableExpr).Col != idxCol { + // Normalize the condition so the index column is on the left side. + op = opt.CommuteEqualityOrInequalityOp(op) + } + if idxColIsDesc && op == opt.LtOp { + // We have to ensure that any value from this column can always be + // advanced to the first value that orders immediately before it. This is + // only possible for a subset of types. We have already ensured that both + // sides of the inequality are of identical types, so it doesn't matter + // which one we check here. + typ := cond.Child(0).(*memo.VariableExpr).Typ + switch typ.Family() { + case types.BoolFamily, types.FloatFamily, types.INetFamily, + types.IntFamily, types.OidFamily, types.TimeFamily, types.TimeTZFamily, + types.TimestampFamily, types.TimestampTZFamily, types.UuidFamily: + default: + continue + } + } + isStartBound := op == opt.GtOp || op == opt.GeOp + if !foundStart && isStartBound { + foundStart = true + startIdx = inequalityFilterOrds[i] + } else if !foundEnd && !isStartBound { + foundEnd = true + endIdx = inequalityFilterOrds[i] } - _, ok = val.Prev(b.evalCtx) - return ok } - for filterIdx := range filters { - props := filters[filterIdx].ScalarProps() - if props.TightConstraints && props.Constraints.Length() > 0 { + return startIdx, endIdx, foundStart, foundEnd +} + +// findJoinConstantRangeFilter tries to find a constant inequality range for this +// column. If no such range filter can be found, rangeFilter is nil. If +// remaining is non-nil, it should be appended to the RemainingFilters field of +// the resulting Constraint. filterIdx is the index of the filter used to +// constrain the index column. needStart and needEnd indicate whether the index +// column's start and end bounds are still unconstrained respectively. At least +// one of needStart and needEnd must be true. +func (b *ConstraintBuilder) findJoinConstantRangeFilter( + filters memo.FiltersExpr, col opt.ColumnID, idxColIsDesc, needStart, needEnd bool, +) (rangeFilter, remaining *memo.FiltersItem, filterIdx int) { + for i := range filters { + props := filters[i].ScalarProps() + if props.TightConstraints && props.Constraints.Length() == 1 { constraintObj := props.Constraints.Constraint(0) constraintCol := constraintObj.Columns.Get(0) // Non-canonical filters aren't yet supported for range spans like // they are for const spans so filter those out here (const spans // from non-canonical filters can be turned into a canonical filter, // see makeConstFilter). We only support 1 span in the execution - // engine so check that. + // engine so check that. Additionally, inequality filter constraints + // should be constructed so that the column is ascending + // (see buildSingleColumnConstraint in memo.constraint_builder.go), so we + // can ignore the descending case. if constraintCol.ID() != col || constraintObj.Spans.Count() != 1 || - !isCanonicalFilter(filters[filterIdx]) { + constraintCol.Descending() || !isCanonicalFilter(filters[i]) { continue } span := constraintObj.Spans.Get(0) - // If we have a datum for either end of the span, we have to ensure - // that it can be "advanced" if the corresponding span boundary is - // exclusive. - // - // This limitation comes from the execution that must be able to - // "advance" the start boundary, but since we don't know the - // direction of the index here, we have to check both ends of the - // span. - if !span.StartKey().IsEmpty() && !span.StartKey().IsNull() { - val := span.StartKey().Value(0) - if span.StartBoundary() == constraint.ExcludeBoundary { - if !canAdvance(val) { - continue - } - } + + var canUseFilter bool + if needStart && !span.StartKey().IsEmpty() && !span.StartKey().IsNull() { + canUseFilter = true } - if !span.EndKey().IsEmpty() && !span.EndKey().IsNull() { + if needEnd && !span.EndKey().IsEmpty() && !span.EndKey().IsNull() { val := span.EndKey().Value(0) - if span.EndBoundary() == constraint.ExcludeBoundary { - if !canAdvance(val) { + if span.EndBoundary() == constraint.ExcludeBoundary && idxColIsDesc { + // If we have a datum for the end of a span and the index column is + // DESC, we have to ensure that it can be "advanced" to the immediate + // previous value if the corresponding span boundary is exclusive. + // + // This limitation comes from the execution that must be able to + // "advance" the end boundary to the previous value in order to make + // it inclusive. This operation cannot be directly performed on the + // encoded key, so the Datum.Prev method is necessary here. + if val.IsMin(b.evalCtx) { + continue + } + if _, ok := val.Prev(b.evalCtx); !ok { continue } } + canUseFilter = true + } + if !canUseFilter { + continue + } + if (!needStart || !needEnd) && !span.StartKey().IsEmpty() && !span.EndKey().IsEmpty() && + !span.StartKey().IsNull() && !span.EndKey().IsNull() { + // The filter supplies both start and end bounds, but we only need one + // of them. Construct a new filter to be used in the lookup, and another + // filter with the unused bound to be included in the ON condition. The + // original filter should still be removed from the ON condition. + // + // We've already filtered cases where the column isn't constrained by a + // single span, so we only need to consider start and end bounds. + indexVariable := b.f.ConstructVariable(col) + startDatum, endDatum := span.StartKey().Value(0), span.EndKey().Value(0) + startBound := b.f.ConstructConstVal(startDatum, startDatum.ResolvedType()) + endBound := b.f.ConstructConstVal(endDatum, endDatum.ResolvedType()) + startOp, endOp := opt.GtOp, opt.LtOp + if span.StartBoundary() == constraint.IncludeBoundary { + startOp = opt.GeOp + } + if span.EndBoundary() == constraint.IncludeBoundary { + endOp = opt.LeOp + } + startFilter := b.f.ConstructFiltersItem( + b.f.DynamicConstruct(startOp, indexVariable, startBound).(opt.ScalarExpr), + ) + endFilter := b.f.ConstructFiltersItem( + b.f.DynamicConstruct(endOp, indexVariable, endBound).(opt.ScalarExpr), + ) + if !needStart { + rangeFilter, remaining = &endFilter, &startFilter + } else if !needEnd { + rangeFilter, remaining = &startFilter, &endFilter + } + } else { + // The filter can be used as-is in the lookup expression. No remaining + // filter needs to be added to the ON condition. + rangeFilter = &filters[i] } - return filterIdx, true + return rangeFilter, remaining, i } } - return -1, false + return nil, nil, -1 } // constructColEquality returns a FiltersItem representing equality between the diff --git a/pkg/sql/opt/lookupjoin/constraint_builder_test.go b/pkg/sql/opt/lookupjoin/constraint_builder_test.go index d343559f994f..aa210c05efc9 100644 --- a/pkg/sql/opt/lookupjoin/constraint_builder_test.go +++ b/pkg/sql/opt/lookupjoin/constraint_builder_test.go @@ -141,12 +141,9 @@ func TestLookupConstraints(t *testing.T) { } var cb lookupjoin.ConstraintBuilder - ok := cb.Init(&f, md, f.EvalContext(), rightTable, leftCols, rightCols, filters) - if !ok { - return "lookup join not possible" - } + cb.Init(&f, md, f.EvalContext(), rightTable, leftCols, rightCols) - lookupConstraint := cb.Build(index, filters, optionalFilters) + lookupConstraint, _ := cb.Build(index, filters, optionalFilters) var b strings.Builder if lookupConstraint.IsUnconstrained() { b.WriteString("lookup join not possible") diff --git a/pkg/sql/opt/lookupjoin/testdata/lookup_expr b/pkg/sql/opt/lookupjoin/testdata/lookup_expr index cee65e8f2f81..3d6bd3193aab 100644 --- a/pkg/sql/opt/lookupjoin/testdata/lookup_expr +++ b/pkg/sql/opt/lookupjoin/testdata/lookup_expr @@ -280,3 +280,187 @@ x IN (10, 20, 30, 40) AND y = b AND x > 10 ---- lookup expression: (x IN (20, 30, 40)) AND (b = y) + +# Test for range filters on input columns. + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x >= a +---- +lookup expression: + x >= a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x < a +---- +lookup expression: + x < a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x <= a +---- +lookup expression: + x <= a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x = a AND y > b +---- +lookup expression: + (a = x) AND (y > b) + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x = a AND y >= b +---- +lookup expression: + (a = x) AND (y >= b) + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x = a AND y < b +---- +lookup expression: + (a = x) AND (y < b) + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x, y) +x = a AND y <= b +---- +lookup expression: + (a = x) AND (y <= b) + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x desc, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x desc, y) +x >= a +---- +lookup expression: + x >= a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x desc, y) +x < a +---- +lookup expression: + x < a + +lookup-constraints left=(a int, b int) right=(x int, y int) index=(x desc, y) +x <= a +---- +lookup expression: + x <= a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x, y) +x >= a +---- +lookup expression: + x >= a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x, y) +x < a +---- +lookup expression: + x < a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x, y) +x <= a +---- +lookup expression: + x <= a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x desc, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x desc, y) +x >= a +---- +lookup expression: + x >= a + +# A '<' filter on a descending index column would require a call to Prev, which +# is not possible for DECIMAL values. +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x desc, y) +x < a +---- +lookup join not possible + +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x desc, y) +x <= a +---- +lookup expression: + x <= a + +# A '<' filter on a descending index column would require a call to Prev, which +# is not possible for DECIMAL values. Leave the '<' condition in the remaining +# filters. +lookup-constraints left=(a decimal, b decimal) right=(x decimal, y decimal) index=(x, y desc) +x = a AND y < b +---- +key cols: + x = a +remaining filters: + y < b + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x, y) +x >= a +---- +lookup expression: + x >= a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x, y) +x < a +---- +lookup expression: + x < a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x, y) +x <= a +---- +lookup expression: + x <= a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x desc, y) +x > a +---- +lookup expression: + x > a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x desc, y) +x >= a +---- +lookup expression: + x >= a + +# Similar to integers, floats support Datum.Prev, so a lookup can be performed with +# this filter and index. +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x desc, y) +x < a +---- +lookup expression: + x < a + +lookup-constraints left=(a float, b float) right=(x float, y float) index=(x desc, y) +x <= a +---- +lookup expression: + x <= a diff --git a/pkg/sql/opt/memo/extract.go b/pkg/sql/opt/memo/extract.go index 58aebb6af530..82b5737c8c35 100644 --- a/pkg/sql/opt/memo/extract.go +++ b/pkg/sql/opt/memo/extract.go @@ -163,29 +163,38 @@ func ExtractAggFirstVar(e opt.ScalarExpr) *VariableExpr { func ExtractJoinEqualityColumns( leftCols, rightCols opt.ColSet, on FiltersExpr, ) (leftEq opt.ColList, rightEq opt.ColList, filterOrds []int) { + return ExtractJoinConditionColumns(leftCols, rightCols, on, false /* inequality */) +} + +// ExtractJoinConditionColumns returns pairs of columns (one from the left side, +// one from the right side) which are constrained by an equality or an +// inequality in a join (and have equivalent types). The returned filterOrds +// contains ordinals of the on filters where each column pair was found. +// The inequality argument indicates whether to look for inequality conditions +// rather than equalities. +func ExtractJoinConditionColumns( + leftCols, rightCols opt.ColSet, on FiltersExpr, inequality bool, +) (leftCmp, rightCmp opt.ColList, filterOrds []int) { + var seenCols opt.ColSet for i := range on { condition := on[i].Condition - ok, left, right := ExtractJoinEquality(leftCols, rightCols, condition) + ok, left, right := ExtractJoinCondition(leftCols, rightCols, condition, inequality) if !ok { continue } - // Don't allow any column to show up twice. - // TODO(radu): need to figure out the right thing to do in cases - // like: left.a = right.a AND left.a = right.b - duplicate := false - for i := range leftEq { - if leftEq[i] == left || rightEq[i] == right { - duplicate = true - break - } - } - if !duplicate { - leftEq = append(leftEq, left) - rightEq = append(rightEq, right) - filterOrds = append(filterOrds, i) + if seenCols.Contains(left) || seenCols.Contains(right) { + // Don't allow any column to show up twice. + // TODO(radu): need to figure out the right thing to do in cases + // like: left.a = right.a AND left.a = right.b + continue } + seenCols.Add(left) + seenCols.Add(right) + leftCmp = append(leftCmp, left) + rightCmp = append(rightCmp, right) + filterOrds = append(filterOrds, i) } - return leftEq, rightEq, filterOrds + return leftCmp, rightCmp, filterOrds } // ExtractJoinEqualityFilters returns the filters containing pairs of columns @@ -214,46 +223,42 @@ func ExtractJoinEqualityFilters(leftCols, rightCols opt.ColSet, on FiltersExpr) return on } -// ExtractJoinEqualityFilter returns the filter containing the given pair of -// columns (one from the left side, one from the right side) which are -// constrained to be equal in a join (and have equivalent types). -func ExtractJoinEqualityFilter( - leftCol, rightCol opt.ColumnID, leftCols, rightCols opt.ColSet, on FiltersExpr, -) FiltersItem { - for i := range on { - condition := on[i].Condition - ok, left, right := ExtractJoinEquality(leftCols, rightCols, condition) - if !ok { - continue +func isVarEqualityOrInequality( + condition opt.ScalarExpr, inequality bool, +) (leftVar, rightVar *VariableExpr, ok bool) { + switch condition.Op() { + case opt.EqOp: + if inequality { + return nil, nil, false } - if left == leftCol && right == rightCol { - return on[i] + case opt.LtOp, opt.LeOp, opt.GtOp, opt.GeOp: + if !inequality { + return nil, nil, false } + default: + return nil, nil, false } - panic(errors.AssertionFailedf("could not find equality between columns %d and %d in filters %s", - leftCol, rightCol, on.String(), - )) + leftVar, leftOk := condition.Child(0).(*VariableExpr) + rightVar, rightOk := condition.Child(1).(*VariableExpr) + return leftVar, rightVar, leftOk && rightOk } -func isVarEquality(condition opt.ScalarExpr) (leftVar, rightVar *VariableExpr, ok bool) { - if eq, ok := condition.(*EqExpr); ok { - if leftVar, ok := eq.Left.(*VariableExpr); ok { - if rightVar, ok := eq.Right.(*VariableExpr); ok { - return leftVar, rightVar, true - } - } - } - return nil, nil, false -} - -// ExtractJoinEquality returns true if the given condition is a simple equality -// condition with two variables (e.g. a=b), where one of the variables (returned -// as "left") is in the set of leftCols and the other (returned as "right") is -// in the set of rightCols. +// ExtractJoinEquality restricts ExtractJoinCondition to only allow equalities. func ExtractJoinEquality( leftCols, rightCols opt.ColSet, condition opt.ScalarExpr, ) (ok bool, left, right opt.ColumnID) { - lvar, rvar, ok := isVarEquality(condition) + return ExtractJoinCondition(leftCols, rightCols, condition, false /* inequality */) +} + +// ExtractJoinCondition returns true if the given condition is a simple equality +// or inequality condition with two variables (e.g. a=b), where one of the +// variables (returned as "left") is in the set of leftCols and the other +// (returned as "right") is in the set of rightCols. inequality is used to +// indicate whether the condition should be an inequality (e.g. < or >). +func ExtractJoinCondition( + leftCols, rightCols opt.ColSet, condition opt.ScalarExpr, inequality bool, +) (ok bool, left, right opt.ColumnID) { + lvar, rvar, ok := isVarEqualityOrInequality(condition, inequality) if !ok { return false, 0, 0 } @@ -286,7 +291,7 @@ func ExtractRemainingJoinFilters(on FiltersExpr, leftEq, rightEq opt.ColList) Fi } var newFilters FiltersExpr for i := range on { - leftVar, rightVar, ok := isVarEquality(on[i].Condition) + leftVar, rightVar, ok := isVarEqualityOrInequality(on[i].Condition, false /* inequality */) if ok { a, b := leftVar.Col, rightVar.Col found := false diff --git a/pkg/sql/opt/norm/comp_funcs.go b/pkg/sql/opt/norm/comp_funcs.go index b5a11a8ec42b..3c2bdcec2982 100644 --- a/pkg/sql/opt/norm/comp_funcs.go +++ b/pkg/sql/opt/norm/comp_funcs.go @@ -17,7 +17,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/errors" - "github.com/cockroachdb/redact" ) // CommuteInequality swaps the operands of an inequality comparison expression, @@ -28,17 +27,8 @@ import ( func (c *CustomFuncs) CommuteInequality( op opt.Operator, left, right opt.ScalarExpr, ) opt.ScalarExpr { - switch op { - case opt.GeOp: - return c.f.ConstructLe(right, left) - case opt.GtOp: - return c.f.ConstructLt(right, left) - case opt.LeOp: - return c.f.ConstructGe(right, left) - case opt.LtOp: - return c.f.ConstructGt(right, left) - } - panic(errors.AssertionFailedf("called commuteInequality with operator %s", redact.Safe(op))) + op = opt.CommuteEqualityOrInequalityOp(op) + return c.f.DynamicConstruct(op, right, left).(opt.ScalarExpr) } // NormalizeTupleEquality remaps the elements of two tuples compared for diff --git a/pkg/sql/opt/norm/join_funcs.go b/pkg/sql/opt/norm/join_funcs.go index a6683381d6ef..83bf2e6a609b 100644 --- a/pkg/sql/opt/norm/join_funcs.go +++ b/pkg/sql/opt/norm/join_funcs.go @@ -459,19 +459,20 @@ func (c *CustomFuncs) JoinFiltersMatchAllLeftRows( return multiplicity.JoinFiltersMatchAllLeftRows() } -// CanExtractJoinEquality returns true if: +// CanExtractJoinComparison returns true if: // - one of a, b is bound by the left columns; // - the other is bound by the right columns; // - a and b are not "bare" variables; // - a and b contain no correlated subqueries; // - neither a or b are constants. +// - the comparison is either an equality or an inequality. // -// Such an equality can be converted to a column equality by pushing down +// Such a comparison can be converted to a column comparison by pushing down // expressions as projections. -func (c *CustomFuncs) CanExtractJoinEquality( +func (c *CustomFuncs) CanExtractJoinComparison( a, b opt.ScalarExpr, leftCols, rightCols opt.ColSet, ) bool { - // Disallow simple equality between variables. + // Disallow simple comparison between variables. if a.Op() == opt.VariableOp && b.Op() == opt.VariableOp { return false } @@ -495,18 +496,18 @@ func (c *CustomFuncs) CanExtractJoinEquality( if (leftProps.OuterCols.SubsetOf(leftCols) && rightProps.OuterCols.SubsetOf(rightCols)) || (leftProps.OuterCols.SubsetOf(rightCols) && rightProps.OuterCols.SubsetOf(leftCols)) { - // The equality is of the form: - // expression(leftCols) = expression(rightCols) + // The comparison is of the form: + // expression(leftCols) op expression(rightCols) return true } return false } -// ExtractJoinEquality takes an equality FiltersItem that was identified via a -// call to CanExtractJoinEquality, and converts it to an equality on "bare" -// variables, by pushing down more complicated expressions as projections. See -// the ExtractJoinEqualities rule. -func (c *CustomFuncs) ExtractJoinEquality( +// ExtractJoinComparison takes an equality or inequality FiltersItem that was +// identified via a call to CanExtractJoinComparison, and converts it to an +// equality or inequality on "bare" variables, by pushing down more complicated +// expressions as projections. See the ExtractJoinComparisons rule. +func (c *CustomFuncs) ExtractJoinComparison( joinOp opt.Operator, left, right memo.RelExpr, filters memo.FiltersExpr, @@ -516,13 +517,16 @@ func (c *CustomFuncs) ExtractJoinEquality( leftCols := c.OutputCols(left) rightCols := c.OutputCols(right) - eq := item.Condition.(*memo.EqExpr) - a, b := eq.Left, eq.Right + cmp := item.Condition + condLeft := cmp.Child(0).(opt.ScalarExpr) + a, b := cmp.Child(0).(opt.ScalarExpr), cmp.Child(1).(opt.ScalarExpr) + op := cmp.Op() - var eqLeftProps props.Shared - memo.BuildSharedProps(eq.Left, &eqLeftProps, c.f.evalCtx) - if eqLeftProps.OuterCols.SubsetOf(rightCols) { + var cmpLeftProps props.Shared + memo.BuildSharedProps(condLeft, &cmpLeftProps, c.f.evalCtx) + if cmpLeftProps.OuterCols.SubsetOf(rightCols) { a, b = b, a + op = opt.CommuteEqualityOrInequalityOp(op) } var leftProj, rightProj projectBuilder @@ -537,7 +541,7 @@ func (c *CustomFuncs) ExtractJoinEquality( } newFilters[i] = c.f.ConstructFiltersItem( - c.f.ConstructEq(leftProj.add(a), rightProj.add(b)), + c.f.DynamicConstruct(op, leftProj.add(a), rightProj.add(b)).(opt.ScalarExpr), ) } diff --git a/pkg/sql/opt/norm/rules/join.opt b/pkg/sql/opt/norm/rules/join.opt index 56295db1cfc3..7b92f060387c 100644 --- a/pkg/sql/opt/norm/rules/join.opt +++ b/pkg/sql/opt/norm/rules/join.opt @@ -501,10 +501,11 @@ $left $private ) -# ExtractJoinEqualities finds equality conditions such that one side only -# depends on left columns and the other only on right columns and pushes the -# expressions down into Project operators. The result is a join that has an -# equality constraint, which is much more efficient. For example: +# ExtractJoinComparisons finds equality and inequality conditions such that +# one side only depends on left columns and the other only on right columns +# and pushes the expressions down into Project operators. The result is a +# join that has an equality or inequality constraint, which is much more +# efficient. For example: # # SELECT * FROM abc JOIN xyz ON a=x+1 # @@ -516,15 +517,18 @@ $left # This join can use hash join or lookup on the equality columns. # # Depending on the expressions involved, one or both sides require a projection. -[ExtractJoinEqualities, Normalize] +[ExtractJoinComparisons, Normalize] (JoinNonApply $left:* & ^(HasOuterCols $left) $right:* & ^(HasOuterCols $right) $on:[ ... $item:(FiltersItem - (Eq $a:^(ConstValue) $b:^(ConstValue)) & - (CanExtractJoinEquality + (Eq | Lt | Le | Gt | Ge + $a:^(ConstValue) + $b:^(ConstValue) + ) & + (CanExtractJoinComparison $a $b (OutputCols $left) @@ -536,7 +540,7 @@ $left $private:* ) => -(ExtractJoinEquality (OpName) $left $right $on $item $private) +(ExtractJoinComparison (OpName) $left $right $on $item $private) # SortFiltersInJoin ensures that any filters in an inner join are canonicalized # by sorting them. diff --git a/pkg/sql/opt/norm/testdata/rules/join b/pkg/sql/opt/norm/testdata/rules/join index 22a940b3d7e3..8b77ecbf375c 100644 --- a/pkg/sql/opt/norm/testdata/rules/join +++ b/pkg/sql/opt/norm/testdata/rules/join @@ -2896,44 +2896,57 @@ FROM (SELECT * FROM a WHERE i>0) AS a INNER JOIN (SELECT x, y, y+1 AS z FROM b WHERE y>10) AS b ON a.f>=b.z::float AND (a.k=b.x) IS True AND a.f>=b.z::float AND (a.i=b.y) IS NOT False ---- -inner-join (hash) +project ├── columns: k:1!null i:2!null f:3!null s:4 j:5 x:8!null y:9!null z:12!null - ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-one) ├── immutable ├── key: (8) ├── fd: (1)-->(2-5), (8)-->(9), (9)-->(12), (1)==(8), (8)==(1), (2)==(9), (9)==(2) - ├── select - │ ├── columns: k:1!null i:2!null f:3!null s:4 j:5 - │ ├── key: (1) - │ ├── fd: (1)-->(2-5) - │ ├── scan a - │ │ ├── columns: k:1!null i:2 f:3!null s:4 j:5 - │ │ ├── key: (1) - │ │ └── fd: (1)-->(2-5) - │ └── filters - │ └── i:2 > 0 [outer=(2), constraints=(/2: [/1 - ]; tight)] - ├── project - │ ├── columns: z:12!null x:8!null y:9!null - │ ├── immutable - │ ├── key: (8) - │ ├── fd: (8)-->(9), (9)-->(12) - │ ├── select - │ │ ├── columns: x:8!null y:9!null - │ │ ├── key: (8) - │ │ ├── fd: (8)-->(9) - │ │ ├── scan b - │ │ │ ├── columns: x:8!null y:9 - │ │ │ ├── key: (8) - │ │ │ └── fd: (8)-->(9) - │ │ └── filters - │ │ └── y:9 > 10 [outer=(9), constraints=(/9: [/11 - ]; tight)] - │ └── projections - │ └── y:9 + 1 [as=z:12, outer=(9), immutable] - └── filters - ├── f:3 >= z:12::FLOAT8 [outer=(3,12), immutable, constraints=(/3: (/NULL - ])] - ├── f:3 >= z:12::FLOAT8 [outer=(3,12), immutable, constraints=(/3: (/NULL - ])] - ├── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] - └── i:2 = y:9 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] + └── inner-join (hash) + ├── columns: k:1!null i:2!null f:3!null s:4 j:5 x:8!null y:9!null z:12!null column13:13!null column14:14!null + ├── multiplicity: left-rows(zero-or-one), right-rows(zero-or-one) + ├── immutable + ├── key: (8) + ├── fd: (1)-->(2-5), (8)-->(9), (9)-->(12), (12)-->(13,14), (1)==(8), (8)==(1), (2)==(9), (9)==(2) + ├── select + │ ├── columns: k:1!null i:2!null f:3!null s:4 j:5 + │ ├── key: (1) + │ ├── fd: (1)-->(2-5) + │ ├── scan a + │ │ ├── columns: k:1!null i:2 f:3!null s:4 j:5 + │ │ ├── key: (1) + │ │ └── fd: (1)-->(2-5) + │ └── filters + │ └── i:2 > 0 [outer=(2), constraints=(/2: [/1 - ]; tight)] + ├── project + │ ├── columns: column14:14!null column13:13!null x:8!null y:9!null z:12!null + │ ├── immutable + │ ├── key: (8) + │ ├── fd: (8)-->(9), (9)-->(12), (12)-->(13,14) + │ ├── project + │ │ ├── columns: z:12!null x:8!null y:9!null + │ │ ├── immutable + │ │ ├── key: (8) + │ │ ├── fd: (8)-->(9), (9)-->(12) + │ │ ├── select + │ │ │ ├── columns: x:8!null y:9!null + │ │ │ ├── key: (8) + │ │ │ ├── fd: (8)-->(9) + │ │ │ ├── scan b + │ │ │ │ ├── columns: x:8!null y:9 + │ │ │ │ ├── key: (8) + │ │ │ │ └── fd: (8)-->(9) + │ │ │ └── filters + │ │ │ └── y:9 > 10 [outer=(9), constraints=(/9: [/11 - ]; tight)] + │ │ └── projections + │ │ └── y:9 + 1 [as=z:12, outer=(9), immutable] + │ └── projections + │ ├── z:12::FLOAT8 [as=column14:14, outer=(12), immutable] + │ └── z:12::FLOAT8 [as=column13:13, outer=(12), immutable] + └── filters + ├── k:1 = x:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] + ├── i:2 = y:9 [outer=(2,9), constraints=(/2: (/NULL - ]; /9: (/NULL - ]), fd=(2)==(9), (9)==(2)] + ├── f:3 >= column13:13 [outer=(3,13), constraints=(/3: (/NULL - ]; /13: (/NULL - ])] + └── f:3 >= column14:14 [outer=(3,14), constraints=(/3: (/NULL - ]; /14: (/NULL - ])] # Don't trigger rule when one of the variables is nullable. norm expect-not=SimplifyJoinNotNullEquality @@ -2956,10 +2969,10 @@ inner-join (cross) └── (i:2 = x:8) IS NOT false [outer=(2,8)] # -------------------------------------------------- -# ExtractJoinEqualities +# ExtractJoinComparisons # -------------------------------------------------- -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON x+y=u ---- project @@ -2991,7 +3004,7 @@ project └── filters └── column9:9 = u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ]), fd=(5)==(9), (9)==(5)] -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON u=x+y ---- project @@ -3023,7 +3036,7 @@ project └── filters └── column9:9 = u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ]), fd=(5)==(9), (9)==(5)] -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON x=u+v ---- project @@ -3055,7 +3068,7 @@ project └── filters └── x:1 = column9:9 [outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)] -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON u+v=x ---- project @@ -3087,7 +3100,7 @@ project └── filters └── x:1 = column9:9 [outer=(1,9), constraints=(/1: (/NULL - ]; /9: (/NULL - ]), fd=(1)==(9), (9)==(1)] -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON x+y=u+v ---- project @@ -3126,7 +3139,7 @@ project └── column9:9 = column10:10 [outer=(9,10), constraints=(/9: (/NULL - ]; /10: (/NULL - ]), fd=(9)==(10), (10)==(9)] # Multiple extractable equalities. -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON x+y=u AND x=u+v AND x*y+1=u*v+2 ---- project @@ -3170,7 +3183,7 @@ project └── column11:11 = column12:12 [outer=(11,12), constraints=(/11: (/NULL - ]; /12: (/NULL - ]), fd=(11)==(12), (12)==(11)] # An extractable equality with another expression. -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN uv ON x+y=u AND x+u=v ---- project @@ -3205,7 +3218,7 @@ project # Computed columns with matching expressions should be reused as projection # columns. -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN comp ON x=i+10 AND y=abs(i) ---- inner-join (hash) @@ -3237,7 +3250,7 @@ inner-join (hash) # Computed columns with matching expressions should be reused as projection # columns. -norm expect=ExtractJoinEqualities +norm expect=ExtractJoinComparisons SELECT * FROM xy JOIN comp ON i+10=x AND abs(i)=y ---- inner-join (hash) @@ -3268,7 +3281,7 @@ inner-join (hash) └── y:2 = v:7 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ]), fd=(2)==(7), (7)==(2)] # Cases with non-extractable equality. -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy FULL OUTER JOIN uv ON x=u ---- full-join (hash) @@ -3287,7 +3300,7 @@ full-join (hash) └── filters └── x:1 = u:5 [outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)] -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy FULL OUTER JOIN uv ON x+y=1 ---- full-join (cross) @@ -3306,7 +3319,7 @@ full-join (cross) └── filters └── (x:1 + y:2) = 1 [outer=(1,2), immutable] -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy FULL OUTER JOIN uv ON 1=u+v ---- full-join (cross) @@ -3325,7 +3338,7 @@ full-join (cross) └── filters └── (u:5 + v:6) = 1 [outer=(5,6), immutable] -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy INNER JOIN uv ON (SELECT k FROM a WHERE i=x)=u ---- project @@ -3370,7 +3383,7 @@ project └── filters └── u:5 = k:9 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ]), fd=(5)==(9), (9)==(5)] -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy INNER JOIN uv ON x=(SELECT k FROM a WHERE i=u) ---- project @@ -3418,7 +3431,7 @@ project # Don't extract equalities where one side is an expression with no outer cols # (#44746). This is a rare case where we can't constant fold because the # function call errors out. -norm expect-not=ExtractJoinEqualities +norm expect-not=ExtractJoinComparisons SELECT * FROM xy FULL JOIN uv ON (substring('', ')') = '') = (u > 0) ---- full-join (cross) @@ -3437,6 +3450,134 @@ full-join (cross) └── filters └── (substring('', ')') = '') = (u:5 > 0) [outer=(5), immutable] +# Case with < operator. +norm expect=ExtractJoinComparisons +SELECT * FROM xy JOIN uv ON x+y(2), (5)-->(6) + └── inner-join (cross) + ├── columns: x:1!null y:2 u:5!null v:6 column9:9!null + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2,9), (5)-->(6) + ├── project + │ ├── columns: column9:9 x:1!null y:2 + │ ├── immutable + │ ├── key: (1) + │ ├── fd: (1)-->(2,9) + │ ├── scan xy + │ │ ├── columns: x:1!null y:2 + │ │ ├── key: (1) + │ │ └── fd: (1)-->(2) + │ └── projections + │ └── x:1 + y:2 [as=column9:9, outer=(1,2), immutable] + ├── scan uv + │ ├── columns: u:5!null v:6 + │ ├── key: (5) + │ └── fd: (5)-->(6) + └── filters + └── column9:9 < u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ])] + +# Case with <= operator. +norm expect=ExtractJoinComparisons +SELECT * FROM xy JOIN uv ON x+y<=u +---- +project + ├── columns: x:1!null y:2 u:5!null v:6 + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2), (5)-->(6) + └── inner-join (cross) + ├── columns: x:1!null y:2 u:5!null v:6 column9:9!null + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2,9), (5)-->(6) + ├── project + │ ├── columns: column9:9 x:1!null y:2 + │ ├── immutable + │ ├── key: (1) + │ ├── fd: (1)-->(2,9) + │ ├── scan xy + │ │ ├── columns: x:1!null y:2 + │ │ ├── key: (1) + │ │ └── fd: (1)-->(2) + │ └── projections + │ └── x:1 + y:2 [as=column9:9, outer=(1,2), immutable] + ├── scan uv + │ ├── columns: u:5!null v:6 + │ ├── key: (5) + │ └── fd: (5)-->(6) + └── filters + └── column9:9 <= u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ])] + +# Case with > operator. +norm expect=ExtractJoinComparisons +SELECT * FROM xy JOIN uv ON x+y>u +---- +project + ├── columns: x:1!null y:2 u:5!null v:6 + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2), (5)-->(6) + └── inner-join (cross) + ├── columns: x:1!null y:2 u:5!null v:6 column9:9!null + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2,9), (5)-->(6) + ├── project + │ ├── columns: column9:9 x:1!null y:2 + │ ├── immutable + │ ├── key: (1) + │ ├── fd: (1)-->(2,9) + │ ├── scan xy + │ │ ├── columns: x:1!null y:2 + │ │ ├── key: (1) + │ │ └── fd: (1)-->(2) + │ └── projections + │ └── x:1 + y:2 [as=column9:9, outer=(1,2), immutable] + ├── scan uv + │ ├── columns: u:5!null v:6 + │ ├── key: (5) + │ └── fd: (5)-->(6) + └── filters + └── column9:9 > u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ])] + +# Case with >= operator. +norm expect=ExtractJoinComparisons +SELECT * FROM xy JOIN uv ON x+y>=u +---- +project + ├── columns: x:1!null y:2 u:5!null v:6 + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2), (5)-->(6) + └── inner-join (cross) + ├── columns: x:1!null y:2 u:5!null v:6 column9:9!null + ├── immutable + ├── key: (1,5) + ├── fd: (1)-->(2,9), (5)-->(6) + ├── project + │ ├── columns: column9:9 x:1!null y:2 + │ ├── immutable + │ ├── key: (1) + │ ├── fd: (1)-->(2,9) + │ ├── scan xy + │ │ ├── columns: x:1!null y:2 + │ │ ├── key: (1) + │ │ └── fd: (1)-->(2) + │ └── projections + │ └── x:1 + y:2 [as=column9:9, outer=(1,2), immutable] + ├── scan uv + │ ├── columns: u:5!null v:6 + │ ├── key: (5) + │ └── fd: (5)-->(6) + └── filters + └── column9:9 >= u:5 [outer=(5,9), constraints=(/5: (/NULL - ]; /9: (/NULL - ])] + # -------------------------------------------------- # LeftAssociateJoinsLeft, LeftAssociateJoinsRight, # RightAssociateJoinsLeft, RightAssociateJoinsRight diff --git a/pkg/sql/opt/norm/testdata/rules/prune_cols b/pkg/sql/opt/norm/testdata/rules/prune_cols index f257695e927b..23ff4069ef25 100644 --- a/pkg/sql/opt/norm/testdata/rules/prune_cols +++ b/pkg/sql/opt/norm/testdata/rules/prune_cols @@ -4813,13 +4813,20 @@ semi-join (hash) │ ├── columns: abcde.a:1!null abcde.b:2 abcde.c:3 │ ├── key: (1) │ └── fd: (1)-->(2,3), (2,3)~~>(1) - ├── scan family - │ ├── columns: "family".a:8!null "family".b:9 "family".c:10 + ├── project + │ ├── columns: column15:15 "family".a:8!null + │ ├── immutable │ ├── key: (8) - │ └── fd: (8)-->(9,10) + │ ├── fd: (8)-->(15) + │ ├── scan family + │ │ ├── columns: "family".a:8!null "family".b:9 "family".c:10 + │ │ ├── key: (8) + │ │ └── fd: (8)-->(9,10) + │ └── projections + │ └── "family".b:9 + "family".c:10 [as=column15:15, outer=(9,10), immutable] └── filters ├── abcde.a:1 = "family".a:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)] - └── abcde.b:2 > ("family".b:9 + "family".c:10) [outer=(2,9,10), immutable, constraints=(/2: (/NULL - ])] + └── abcde.b:2 > column15:15 [outer=(2,15), constraints=(/2: (/NULL - ]; /15: (/NULL - ])] norm expect=PruneSemiAntiJoinRightCols SELECT a, b, c FROM abcde WHERE NOT EXISTS (SELECT * FROM family WHERE abcde.a=family.a) diff --git a/pkg/sql/opt/operator.go b/pkg/sql/opt/operator.go index 85cf4c38beaf..d28192c6de08 100644 --- a/pkg/sql/opt/operator.go +++ b/pkg/sql/opt/operator.go @@ -465,6 +465,26 @@ func AggregateIgnoresDuplicates(op Operator) bool { } } +// CommuteEqualityOrInequalityOp returns the commuted version of the given +// operator, e.g. '<' -> '>' and '=' -> '='. It only handles equality and +// inequality operators. Note that commuting an operator is not the same as +// negating it. +func CommuteEqualityOrInequalityOp(op Operator) Operator { + switch op { + case EqOp: + return EqOp + case GeOp: + return LeOp + case GtOp: + return LtOp + case LeOp: + return GeOp + case LtOp: + return GtOp + } + panic(errors.AssertionFailedf("attempted to commute operator: %s", redact.Safe(op))) +} + // OpaqueMetadata is an object stored in OpaqueRelExpr and passed // through to the exec factory. type OpaqueMetadata interface { diff --git a/pkg/sql/opt/optbuilder/create_function.go b/pkg/sql/opt/optbuilder/create_function.go index 922c9459663c..ccaa7b6efd6f 100644 --- a/pkg/sql/opt/optbuilder/create_function.go +++ b/pkg/sql/opt/optbuilder/create_function.go @@ -37,6 +37,11 @@ func (b *Builder) buildCreateFunction(cf *tree.CreateFunction, inScope *scope) ( schID := b.factory.Metadata().AddSchema(sch) cf.FuncName.ObjectNamePrefix = resName + // TODO(chengxiong,mgartner): this is a hack to disallow UDF usage in UDF and + // we will need to lift this hack when we plan to allow it. + preFuncResolver := b.semaCtx.FunctionResolver + b.semaCtx.FunctionResolver = nil + b.insideFuncDef = true b.trackSchemaDeps = true // Make sure datasource names are qualified. @@ -47,6 +52,9 @@ func (b *Builder) buildCreateFunction(cf *tree.CreateFunction, inScope *scope) ( b.schemaDeps = nil b.schemaTypeDeps = util.FastIntSet{} b.qualifyDataSourceNamesInAST = false + + b.semaCtx.FunctionResolver = preFuncResolver + maybePanicOnUnknownFunction("function body") }() if cf.RoutineBody != nil { diff --git a/pkg/sql/opt/optbuilder/create_view.go b/pkg/sql/opt/optbuilder/create_view.go index 597a6bb78e42..0ca175227e6c 100644 --- a/pkg/sql/opt/optbuilder/create_view.go +++ b/pkg/sql/opt/optbuilder/create_view.go @@ -11,10 +11,13 @@ package optbuilder import ( + "fmt" + "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sqlerrors" "github.com/cockroachdb/cockroach/pkg/util" + "github.com/cockroachdb/errors" ) func (b *Builder) buildCreateView(cv *tree.CreateView, inScope *scope) (outScope *scope) { @@ -23,6 +26,9 @@ func (b *Builder) buildCreateView(cv *tree.CreateView, inScope *scope) (outScope schID := b.factory.Metadata().AddSchema(sch) viewName := tree.MakeTableNameFromPrefix(resName, tree.Name(cv.Name.Object())) + preFuncResolver := b.semaCtx.FunctionResolver + b.semaCtx.FunctionResolver = nil + // We build the select statement to: // - check the statement semantically, // - get the fully resolved names into the AST, and @@ -37,6 +43,9 @@ func (b *Builder) buildCreateView(cv *tree.CreateView, inScope *scope) (outScope b.schemaDeps = nil b.schemaTypeDeps = util.FastIntSet{} b.qualifyDataSourceNamesInAST = false + + b.semaCtx.FunctionResolver = preFuncResolver + maybePanicOnUnknownFunction("view query") }() defScope := b.buildStmtAtRoot(cv.AsSource, nil /* desiredTypes */) @@ -92,3 +101,25 @@ func (b *Builder) buildCreateView(cv *tree.CreateView, inScope *scope) (outScope ) return outScope } + +func maybePanicOnUnknownFunction(target string) { + // TODO(chengxiong,mgartner): this is a hack to disallow UDF usage in view and + // we will need to lift this hack when we plan to allow it. + switch recErr := recover().(type) { + case nil: + // No error. + case error: + if errors.Is(recErr, tree.ErrFunctionUndefined) { + panic( + errors.WithHint( + recErr, + fmt.Sprintf("There is probably a typo in function name. Or the intention was to use a user-defined "+ + "function in the %s, which is currently not supported.", target), + ), + ) + } + panic(recErr) + default: + panic(recErr) + } +} diff --git a/pkg/sql/opt/optbuilder/testdata/udf b/pkg/sql/opt/optbuilder/testdata/udf index 7079a4f9a815..a4f2d341dfc4 100644 --- a/pkg/sql/opt/optbuilder/testdata/udf +++ b/pkg/sql/opt/optbuilder/testdata/udf @@ -9,7 +9,7 @@ CREATE TABLE abc ( build SELECT foo() ---- -error (42883): unknown function: foo +error (42883): unknown function: foo: function undefined exec-ddl CREATE FUNCTION one() RETURNS INT LANGUAGE SQL AS 'SELECT 1'; diff --git a/pkg/sql/opt/testutils/testcat/function.go b/pkg/sql/opt/testutils/testcat/function.go index 80186d6eeb8d..8cd97b24cca3 100644 --- a/pkg/sql/opt/testutils/testcat/function.go +++ b/pkg/sql/opt/testutils/testcat/function.go @@ -15,8 +15,6 @@ import ( "fmt" "strings" - "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" - "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sem/volatility" "github.com/cockroachdb/cockroach/pkg/util/treeprinter" @@ -47,7 +45,7 @@ func (tc *Catalog) ResolveFunction( if def, ok := tc.udfs[name.String()]; ok { return def, nil } - return nil, pgerror.Newf(pgcode.UndefinedFunction, "unknown function: %s", name) + return nil, errors.Wrapf(tree.ErrFunctionUndefined, "unknown function: %s", name) } // ResolveFunctionByOID part of the tree.FunctionReferenceResolver interface. diff --git a/pkg/sql/opt/xform/join_funcs.go b/pkg/sql/opt/xform/join_funcs.go index 012bf688c63e..749daf2386a4 100644 --- a/pkg/sql/opt/xform/join_funcs.go +++ b/pkg/sql/opt/xform/join_funcs.go @@ -320,6 +320,31 @@ func (c *CustomFuncs) GenerateLookupJoinsWithVirtualCols( ) } +// canGenerateLookupJoins makes a best-effort to filter out cases where no +// joins can be constructed based on the join's filters and flags. It may miss +// some cases that will be filtered out later. +func canGenerateLookupJoins( + input memo.RelExpr, joinFlags memo.JoinFlags, leftCols, rightCols opt.ColSet, on memo.FiltersExpr, +) bool { + if joinFlags.Has(memo.DisallowLookupJoinIntoRight) { + return false + } + if leftEq, _, _ := memo.ExtractJoinEqualityColumns(leftCols, rightCols, on); len(leftEq) > 0 { + // There is at least one valid equality between left and right columns. + return true + } + // There are no valid equality conditions, but there may be an inequality that + // can be used for lookups. Since the current implementation does not + // deduplicate the resulting spans, only plan a lookup join with no equalities + // when the input has one row, or if a lookup join is forced. + if input.Relational().Cardinality.IsZeroOrOne() || + joinFlags.Has(memo.AllowOnlyLookupJoinIntoRight) { + cmp, _, _ := memo.ExtractJoinConditionColumns(leftCols, rightCols, on, true /* inequality */) + return len(cmp) > 0 + } + return false +} + // generateLookupJoinsImpl is the general implementation for generating lookup // joins. The rightCols argument must be the columns output by the right side of // matched join expression. projectedVirtualCols is the set of virtual columns @@ -337,27 +362,22 @@ func (c *CustomFuncs) generateLookupJoinsImpl( on memo.FiltersExpr, joinPrivate *memo.JoinPrivate, ) { + md := c.e.mem.Metadata() + inputProps := input.Relational() - if joinPrivate.Flags.Has(memo.DisallowLookupJoinIntoRight) { + if !canGenerateLookupJoins(input, joinPrivate.Flags, inputProps.OutputCols, rightCols, on) { return } - md := c.e.mem.Metadata() - inputProps := input.Relational() var cb lookupjoin.ConstraintBuilder - if ok := cb.Init( + cb.Init( c.e.f, c.e.mem.Metadata(), c.e.evalCtx, scanPrivate.Table, inputProps.OutputCols, rightCols, - on, - ); !ok { - // No lookup joins can be generated with the given filters and - // left/right columns. - return - } + ) // Generate implicit filters from CHECK constraints and computed columns as // optional filters to help generate lookup join keys. @@ -381,12 +401,19 @@ func (c *CustomFuncs) generateLookupJoinsImpl( return } - lookupConstraint := cb.Build(index, onFilters, optionalFilters) + lookupConstraint, foundEqualityCols := cb.Build(index, onFilters, optionalFilters) if lookupConstraint.IsUnconstrained() { // We couldn't find equality columns or a lookup expression to // perform a lookup join on this index. return } + if !foundEqualityCols && !inputProps.Cardinality.IsZeroOrOne() && + !joinPrivate.Flags.Has(memo.AllowOnlyLookupJoinIntoRight) { + // Avoid planning an inequality-only lookup when the input has more than + // one row unless the lookup join is forced (see canGenerateLookupJoins + // for a brief explanation). + return + } lookupJoin := memo.LookupJoinExpr{Input: input} lookupJoin.JoinPrivate = *joinPrivate diff --git a/pkg/sql/opt/xform/testdata/coster/spatial-filters b/pkg/sql/opt/xform/testdata/coster/spatial-filters index 0958852ad7e4..1c42587ea198 100644 --- a/pkg/sql/opt/xform/testdata/coster/spatial-filters +++ b/pkg/sql/opt/xform/testdata/coster/spatial-filters @@ -270,28 +270,55 @@ SELECT * FROM g JOIN x ON g.id = x.id WHERE st_area(g.geog) > st_area(x.geog); ---- -inner-join (merge) +project ├── columns: id:1!null a:2 b:3 geog:4 id:7!null a:8 b:9 geog:10 - ├── left ordering: +1 - ├── right ordering: +7 ├── immutable - ├── stats: [rows=166666.7, distinct(1)=166667, null(1)=0, avgsize(1)=4, distinct(7)=166667, null(7)=0, avgsize(7)=4] - ├── cost: 2095049.67 + ├── stats: [rows=166666.7] + ├── cost: 1116716.4 ├── key: (7) ├── fd: (1)-->(2-4), (7)-->(8-10), (1)==(7), (7)==(1) - ├── scan g - │ ├── columns: g.id:1!null g.a:2 g.b:3 g.geog:4 - │ ├── stats: [rows=500000, distinct(1)=500000, null(1)=0, avgsize(1)=4] - │ ├── cost: 540024.82 - │ ├── key: (1) - │ ├── fd: (1)-->(2-4) - │ └── ordering: +1 - ├── scan x - │ ├── columns: x.id:7!null x.a:8 x.b:9 x.geog:10 - │ ├── stats: [rows=500000, distinct(7)=500000, null(7)=0, avgsize(7)=4] - │ ├── cost: 540024.82 - │ ├── key: (7) - │ ├── fd: (7)-->(8-10) - │ └── ordering: +7 - └── filters - └── st_area(g.geog:4) > st_area(x.geog:10) [outer=(4,10), immutable] + └── inner-join (merge) + ├── columns: g.id:1!null g.a:2 g.b:3 g.geog:4 x.id:7!null x.a:8 x.b:9 x.geog:10 column13:13!null column14:14!null + ├── left ordering: +1 + ├── right ordering: +7 + ├── immutable + ├── stats: [rows=166666.7, distinct(1)=166667, null(1)=0, avgsize(1)=4, distinct(7)=166667, null(7)=0, avgsize(7)=4, distinct(13)=50000, null(13)=0, avgsize(13)=4, distinct(14)=50000, null(14)=0, avgsize(14)=4] + ├── cost: 1115049.71 + ├── key: (7) + ├── fd: (1)-->(2-4), (4)-->(13), (7)-->(8-10), (10)-->(14), (1)==(7), (7)==(1) + ├── project + │ ├── columns: column13:13 g.id:1!null g.a:2 g.b:3 g.geog:4 + │ ├── immutable + │ ├── stats: [rows=500000, distinct(1)=500000, null(1)=0, avgsize(1)=4, distinct(13)=50000, null(13)=0, avgsize(13)=4] + │ ├── cost: 550024.84 + │ ├── key: (1) + │ ├── fd: (1)-->(2-4), (4)-->(13) + │ ├── ordering: +1 + │ ├── scan g + │ │ ├── columns: g.id:1!null g.a:2 g.b:3 g.geog:4 + │ │ ├── stats: [rows=500000, distinct(1)=500000, null(1)=0, avgsize(1)=4, distinct(4)=50000, null(4)=5000, avgsize(4)=4] + │ │ ├── cost: 540024.82 + │ │ ├── key: (1) + │ │ ├── fd: (1)-->(2-4) + │ │ └── ordering: +1 + │ └── projections + │ └── st_area(g.geog:4) [as=column13:13, outer=(4), immutable] + ├── project + │ ├── columns: column14:14 x.id:7!null x.a:8 x.b:9 x.geog:10 + │ ├── immutable + │ ├── stats: [rows=500000, distinct(7)=500000, null(7)=0, avgsize(7)=4, distinct(14)=50000, null(14)=0, avgsize(14)=4] + │ ├── cost: 550024.84 + │ ├── key: (7) + │ ├── fd: (7)-->(8-10), (10)-->(14) + │ ├── ordering: +7 + │ ├── scan x + │ │ ├── columns: x.id:7!null x.a:8 x.b:9 x.geog:10 + │ │ ├── stats: [rows=500000, distinct(7)=500000, null(7)=0, avgsize(7)=4, distinct(10)=50000, null(10)=5000, avgsize(10)=4] + │ │ ├── cost: 540024.82 + │ │ ├── key: (7) + │ │ ├── fd: (7)-->(8-10) + │ │ └── ordering: +7 + │ └── projections + │ └── st_area(x.geog:10) [as=column14:14, outer=(10), immutable] + └── filters + └── column13:13 > column14:14 [outer=(13,14), constraints=(/13: (/NULL - ]; /14: (/NULL - ])] diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index 72aa799ea6a7..dcec492190ea 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -2317,11 +2317,13 @@ SELECT a,b,n,m FROM small LEFT JOIN abcd ON a=m AND b>n ---- left-join (lookup abcd@abcd_a_b_idx) ├── columns: a:6 b:7 n:2 m:1 - ├── key columns: [1] = [6] + ├── lookup expression + │ └── filters + │ ├── m:1 = a:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] + │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] ├── scan small │ └── columns: m:1 n:2 - └── filters - └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] + └── filters (true) # Non-covering case. opt expect=GenerateLookupJoins @@ -2369,12 +2371,14 @@ inner-join (lookup abcd) ├── fd: (1)==(6), (6)==(1) ├── inner-join (lookup abcd@abcd_a_b_idx) │ ├── columns: m:1!null n:2!null a:6!null b:7!null abcd.rowid:9!null - │ ├── key columns: [1] = [6] + │ ├── lookup expression + │ │ └── filters + │ │ ├── m:1 = a:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] + │ │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] │ ├── fd: (9)-->(6,7), (1)==(6), (6)==(1) │ ├── scan small │ │ └── columns: m:1 n:2 - │ └── filters - │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] + │ └── filters (true) └── filters (true) # Non-covering case, extra filter bound by index, left join. @@ -2387,12 +2391,14 @@ left-join (lookup abcd) ├── lookup columns are key ├── left-join (lookup abcd@abcd_a_b_idx) │ ├── columns: m:1 n:2 a:6 b:7 abcd.rowid:9 - │ ├── key columns: [1] = [6] + │ ├── lookup expression + │ │ └── filters + │ │ ├── m:1 = a:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] + │ │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] │ ├── fd: (9)-->(6,7) │ ├── scan small │ │ └── columns: m:1 n:2 - │ └── filters - │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] + │ └── filters (true) └── filters (true) # Non-covering case, extra filter not bound by index. @@ -3118,8 +3124,6 @@ DROP INDEX idx_vrw # The OR filter gets converted to an IN expression in the lookup expression # filters. -# TODO(rytaft): The OR filter shouldn't get re-applied as an additional filter -# in the ON expression. opt expect=GenerateLookupJoinsWithFilter SELECT * FROM (VALUES (1, 10), (2, 20), (3, NULL)) AS q(w, v) LEFT LOOKUP JOIN lookup_expr t ON (t.u = 1 OR t.u = 2) AND q.v = t.v @@ -3278,6 +3282,49 @@ project └── projections └── count:10 [as=count:11, outer=(10)] +# Don't plan a lookup join with no equalities unless the input has only one row +# or the join has a lookup hint. +opt expect-not=(GenerateLookupJoins,GenerateLookupJoinsWithFilter) +SELECT a,b,n,m FROM small JOIN abcd ON a>=m +---- +inner-join (cross) + ├── columns: a:6!null b:7 n:2 m:1!null + ├── scan abcd@abcd_a_b_idx + │ └── columns: a:6 b:7 + ├── scan small + │ └── columns: m:1 n:2 + └── filters + └── a:6 >= m:1 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ])] + +opt expect=GenerateLookupJoins +SELECT a,b,n,m FROM (SELECT * FROM small LIMIT 1) JOIN abcd ON a>=m +---- +inner-join (lookup abcd@abcd_a_b_idx) + ├── columns: a:6!null b:7 n:2 m:1!null + ├── lookup expression + │ └── filters + │ └── a:6 >= m:1 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ])] + ├── fd: ()-->(1,2) + ├── scan small + │ ├── columns: m:1 n:2 + │ ├── limit: 1 + │ ├── key: () + │ └── fd: ()-->(1,2) + └── filters (true) + +opt expect=GenerateLookupJoins +SELECT a,b,n,m FROM small INNER LOOKUP JOIN abcd ON a>=m +---- +inner-join (lookup abcd@abcd_a_b_idx) + ├── columns: a:6!null b:7 n:2 m:1!null + ├── flags: force lookup join (into right side) + ├── lookup expression + │ └── filters + │ └── a:6 >= m:1 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ])] + ├── scan small + │ └── columns: m:1 n:2 + └── filters (true) + # -------------------------------------------------- # GenerateLookupJoinsWithFilter # -------------------------------------------------- @@ -3370,12 +3417,12 @@ inner-join (lookup abcd) │ ├── lookup expression │ │ └── filters │ │ ├── m:1 = a:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] - │ │ └── b:7 > 1 [outer=(7), constraints=(/7: [/2 - ]; tight)] + │ │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] │ ├── fd: (9)-->(6,7), (1)==(6), (6)==(1) │ ├── scan small │ │ └── columns: m:1 n:2 │ └── filters - │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] + │ └── b:7 > 1 [outer=(7), constraints=(/7: [/2 - ]; tight)] └── filters (true) # Non-covering case, extra filter bound by index, left join. @@ -3391,12 +3438,12 @@ left-join (lookup abcd) │ ├── lookup expression │ │ └── filters │ │ ├── m:1 = a:6 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)] - │ │ └── b:7 > 1 [outer=(7), constraints=(/7: [/2 - ]; tight)] + │ │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] │ ├── fd: (9)-->(6,7) │ ├── scan small │ │ └── columns: m:1 n:2 │ └── filters - │ └── b:7 > n:2 [outer=(2,7), constraints=(/2: (/NULL - ]; /7: (/NULL - ])] + │ └── b:7 > 1 [outer=(7), constraints=(/7: [/2 - ]; tight)] └── filters (true) # Non-covering case, extra filter not bound by index. diff --git a/pkg/sql/pgwire/testdata/pgtest/notice b/pkg/sql/pgwire/testdata/pgtest/notice index 3729b632bc6b..8a78ae6b0a25 100644 --- a/pkg/sql/pgwire/testdata/pgtest/notice +++ b/pkg/sql/pgwire/testdata/pgtest/notice @@ -55,7 +55,7 @@ Query {"String": "DROP INDEX t_x_idx"} until crdb_only CommandComplete ---- -{"Severity":"NOTICE","SeverityUnlocalized":"NOTICE","Code":"00000","Message":"the data for dropped indexes is reclaimed asynchronously","Detail":"","Hint":"The reclamation delay can be customized in the zone configuration for the table.","Position":0,"InternalPosition":0,"InternalQuery":"","Where":"","SchemaName":"","TableName":"","ColumnName":"","DataTypeName":"","ConstraintName":"","File":"drop_index.go","Line":541,"Routine":"dropIndexByName","UnknownFields":null} +{"Severity":"NOTICE","SeverityUnlocalized":"NOTICE","Code":"00000","Message":"the data for dropped indexes is reclaimed asynchronously","Detail":"","Hint":"The reclamation delay can be customized in the zone configuration for the table.","Position":0,"InternalPosition":0,"InternalQuery":"","Where":"","SchemaName":"","TableName":"","ColumnName":"","DataTypeName":"","ConstraintName":"","File":"drop_index.go","Line":546,"Routine":"dropIndexByName","UnknownFields":null} {"Type":"CommandComplete","CommandTag":"DROP INDEX"} until noncrdb_only diff --git a/pkg/sql/rename_column.go b/pkg/sql/rename_column.go index 78736c6a28b0..cd724eebfcc3 100644 --- a/pkg/sql/rename_column.go +++ b/pkg/sql/rename_column.go @@ -101,9 +101,6 @@ func (p *planner) findColumnToRename( } for _, tableRef := range tableDesc.DependedOnBy { - if err := p.maybeFailOnDroppingFunction(ctx, tableRef.ID); err != nil { - return nil, err - } found := false for _, colID := range tableRef.ColumnIDs { if colID == col.GetID() { @@ -111,7 +108,7 @@ func (p *planner) findColumnToRename( } } if found { - return nil, p.dependentViewError( + return nil, p.dependentError( ctx, "column", oldName.String(), tableDesc.ParentID, tableRef.ID, "rename", ) } diff --git a/pkg/sql/rename_index.go b/pkg/sql/rename_index.go index f82f963b7993..89e40e2dd1a7 100644 --- a/pkg/sql/rename_index.go +++ b/pkg/sql/rename_index.go @@ -81,13 +81,10 @@ func (n *renameIndexNode) startExec(params runParams) error { idx := n.idx for _, tableRef := range tableDesc.DependedOnBy { - if err := params.p.maybeFailOnDroppingFunction(params.ctx, tableRef.ID); err != nil { - return err - } if tableRef.IndexID != idx.GetID() { continue } - return p.dependentViewError( + return p.dependentError( ctx, "index", n.n.Index.Index.String(), tableDesc.ParentID, tableRef.ID, "rename", ) } diff --git a/pkg/sql/rename_table.go b/pkg/sql/rename_table.go index e1e4b8997de9..bb6033b3c02d 100644 --- a/pkg/sql/rename_table.go +++ b/pkg/sql/rename_table.go @@ -82,10 +82,7 @@ func (p *planner) RenameTable(ctx context.Context, n *tree.RenameTable) (planNod // If so, then we disallow renaming, otherwise we allow it. for _, dependent := range tableDesc.DependedOnBy { if !dependent.ByID { - if err := p.maybeFailOnDroppingFunction(ctx, dependent.ID); err != nil { - return nil, err - } - return nil, p.dependentViewError( + return nil, p.dependentError( ctx, string(tableDesc.DescriptorType()), oldTn.String(), tableDesc.ParentID, dependent.ID, "rename", ) @@ -278,18 +275,51 @@ func (n *renameTableNode) Close(context.Context) {} // TODO(a-robinson): Support renaming objects depended on by views once we have // a better encoding for view queries (#10083). -func (p *planner) dependentViewError( - ctx context.Context, typeName, objName string, parentID, viewID descpb.ID, op string, +func (p *planner) dependentError( + ctx context.Context, typeName string, objName string, parentID descpb.ID, id descpb.ID, op string, ) error { - viewDesc, err := p.Descriptors().Direct().MustGetTableDescByID(ctx, p.txn, viewID) + desc, err := p.Descriptors().GetImmutableDescriptorByID(ctx, p.txn, id, tree.CommonLookupFlags{Required: true}) if err != nil { return err } + switch desc.DescriptorType() { + case catalog.Table: + return p.dependentViewError(ctx, typeName, objName, parentID, desc.(catalog.TableDescriptor), op) + case catalog.Function: + return p.dependentFunctionError(typeName, objName, desc.(catalog.FunctionDescriptor), op) + default: + return errors.AssertionFailedf( + "unexpected dependent %s %s on %s %s", + desc.DescriptorType(), desc.GetName(), typeName, objName, + ) + } +} + +func (p *planner) dependentFunctionError( + typeName, objName string, fnDesc catalog.FunctionDescriptor, op string, +) error { + return errors.WithHintf( + sqlerrors.NewDependentObjectErrorf( + "cannot %s %s %q because function %q depends on it", + op, typeName, objName, fnDesc.GetName(), + ), + "you can drop %s instead.", + fnDesc.GetName(), + ) +} + +func (p *planner) dependentViewError( + ctx context.Context, + typeName, objName string, + parentID descpb.ID, + viewDesc catalog.TableDescriptor, + op string, +) error { viewName := viewDesc.GetName() if viewDesc.GetParentID() != parentID { viewFQName, err := p.getQualifiedTableName(ctx, viewDesc) if err != nil { - log.Warningf(ctx, "unable to retrieve name of view %d: %v", viewID, err) + log.Warningf(ctx, "unable to retrieve name of view %d: %v", viewDesc.GetID(), err) return sqlerrors.NewDependentObjectErrorf( "cannot %s %s %q because a view depends on it", op, typeName, objName) diff --git a/pkg/sql/row/fetcher.go b/pkg/sql/row/fetcher.go index 8ba7dd4b4c74..3c3baf25ccb6 100644 --- a/pkg/sql/row/fetcher.go +++ b/pkg/sql/row/fetcher.go @@ -250,6 +250,12 @@ type FetcherInitArgs struct { // TraceKV indicates whether or not session tracing is enabled. TraceKV bool ForceProductionKVBatchSize bool + // SpansCanOverlap indicates whether the spans in a given batch can overlap + // with one another. If it is true, spans that correspond to the same row must + // share the same span ID, since the span IDs are used to determine when a new + // row is being processed. In practice, this means that span IDs must be + // passed in when SpansCanOverlap is true. + SpansCanOverlap bool } // Init sets up a Fetcher for a given table and index. @@ -660,7 +666,14 @@ func (rf *Fetcher) nextKey(ctx context.Context) (newRow bool, spanID int, _ erro // unchangedPrefix will be set to true if the current KV belongs to the same // row as the previous KV (i.e. the last and current keys have identical // prefix). In this case, we can skip decoding the index key completely. - unchangedPrefix := rf.table.spec.MaxKeysPerRow > 1 && rf.indexKey != nil && bytes.HasPrefix(rf.kv.Key, rf.indexKey) + // If the spans can overlap, it is not sufficient to check the prefix of the + // key in order to determine whether a new row is being processed. Instead, we + // have to rely on checking if the associated span ID has changed. Note that + // we cannot use the span ID check unconditionally. This is because it is + // possible for multiple span IDs to be associated with a given row when the + // spans cannot overlap. + unchangedPrefix := (!rf.args.SpansCanOverlap || rf.spanID == spanID) && + rf.table.spec.MaxKeysPerRow > 1 && rf.indexKey != nil && bytes.HasPrefix(rf.kv.Key, rf.indexKey) if unchangedPrefix { // Skip decoding! rf.keyRemainingBytes = rf.kv.Key[len(rf.indexKey):] diff --git a/pkg/sql/rowexec/joinreader.go b/pkg/sql/rowexec/joinreader.go index b00f79264c10..f7c6a928d7c7 100644 --- a/pkg/sql/rowexec/joinreader.go +++ b/pkg/sql/rowexec/joinreader.go @@ -169,6 +169,11 @@ type joinReader struct { lookupExpr execinfrapb.ExprHelper remoteLookupExpr execinfrapb.ExprHelper + // spansCanOverlap indicates whether the spans generated for a given input + // batch can overlap. It is used in the fetcher when deciding whether a newly + // read kv corresponds to a new row. + spansCanOverlap bool + // Batch size for fetches. Not a constant so we can lower for testing. batchSizeBytes int64 curBatchSizeBytes int64 @@ -543,6 +548,7 @@ func newJoinReader( Spec: &spec.FetchSpec, TraceKV: flowCtx.TraceKV, ForceProductionKVBatchSize: flowCtx.EvalCtx.TestingKnobs.ForceProductionValues, + SpansCanOverlap: jr.spansCanOverlap, }, ); err != nil { return nil, err @@ -600,9 +606,10 @@ func (jr *joinReader) initJoinReaderStrategy( // If jr.remoteLookupExpr is set, this is a locality optimized lookup join // and we need to use localityOptimizedSpanGenerator. + var err error if jr.remoteLookupExpr.Expr == nil { multiSpanGen := &multiSpanGenerator{} - if err := multiSpanGen.init( + if jr.spansCanOverlap, err = multiSpanGen.init( flowCtx.EvalCtx, flowCtx.Codec(), &jr.fetchSpec, @@ -618,7 +625,7 @@ func (jr *joinReader) initJoinReaderStrategy( } else { localityOptSpanGen := &localityOptimizedSpanGenerator{} remoteSpanGenMemAcc := jr.MemMonitor.MakeBoundAccount() - if err := localityOptSpanGen.init( + if jr.spansCanOverlap, err = localityOptSpanGen.init( flowCtx.EvalCtx, flowCtx.Codec(), &jr.fetchSpec, diff --git a/pkg/sql/rowexec/joinreader_span_generator.go b/pkg/sql/rowexec/joinreader_span_generator.go index b79046f4f73e..4250ac68309e 100644 --- a/pkg/sql/rowexec/joinreader_span_generator.go +++ b/pkg/sql/rowexec/joinreader_span_generator.go @@ -13,6 +13,7 @@ package rowexec import ( "context" "fmt" + "strconv" "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" @@ -73,6 +74,11 @@ type spanIDHelper struct { // // Index joins already have unique rows that generate unique spans to fetch, // so they don't need this map. + // + // TODO(drewk): using a map instead of a sort-merge strategy is inefficient + // for inequality spans, which tend to overlap significantly without being + // exactly the same. For now, we can just limit when inequality-only lookup + // joins are planned to avoid regression. spanKeyToSpanID map[string]int // spanIDToInputRowIndices maps a span ID to the input row indices that // desire the lookup of the span corresponding to that span ID. @@ -99,8 +105,11 @@ func (h *spanIDHelper) reset() { // span as well as a boolean indicating whether this span key is seen for the // first time are returned. func (h *spanIDHelper) addInputRowIdxForSpan( - spanKey string, inputRowIdx int, + span *roachpb.Span, inputRowIdx int, ) (spanID int, newSpanKey bool) { + // Derive a unique key for the span. This pattern for constructing the string + // is more efficient than using fmt.Sprintf(). + spanKey := strconv.Itoa(len(span.Key)) + "/" + string(span.Key) + "/" + string(span.EndKey) spanID, ok := h.spanKeyToSpanID[spanKey] if !ok { spanID = len(h.spanKeyToSpanID) @@ -243,7 +252,7 @@ func (g *defaultSpanGenerator) generateSpans( g.scratchSpans, generatedSpan, len(g.lookupCols), containsNull, ) } else { - spanID, newSpanKey := g.addInputRowIdxForSpan(string(generatedSpan.Key), i) + spanID, newSpanKey := g.addInputRowIdxForSpan(&generatedSpan, i) if newSpanKey { numOldSpans := len(g.scratchSpans) g.scratchSpans = g.spanSplitter.MaybeSplitSpanIntoSeparateFamilies( @@ -295,16 +304,22 @@ type multiSpanGenerator struct { indexKeyRows []rowenc.EncDatumRow indexKeySpans roachpb.Spans + // inequalityInfo holds the information needed to generate spans when the last + // lookup column is constrained by an inequality condition. + inequalityInfo struct { + // colIdx is the index of the lookup column that is constrained to a range. + // It is set to -1 if no lookup column is constrained by an inequality. + colIdx int + colTyp *types.T + startInclusive, endInclusive bool + start, end tree.TypedExpr + } + spanIDHelper // spansCount is the number of spans generated for each input row. spansCount int - // indexOrds contains the ordinals (i.e., the positions in the index) of the - // index columns that are constrained by the spans produced by this - // multiSpanGenerator. indexOrds must be a prefix of the index columns. - indexOrds util.FastIntSet - // fetchedOrdToIndexKeyOrd maps the ordinals of fetched (right-hand side) // columns to ordinals in the index key columns. fetchedOrdToIndexKeyOrd util.FastIntMap @@ -312,10 +327,6 @@ type multiSpanGenerator struct { // numInputCols is the number of columns in the input to the joinReader. numInputCols int - // inequalityColIdx is the index of inequality colinfo (there can be only one), - // -1 otherwise. - inequalityColIdx int - scratchSpans roachpb.Spans // memAcc is owned by this span generator and is closed when the generator @@ -356,38 +367,15 @@ func (i multiSpanGeneratorIndexVarColInfo) String() string { return fmt.Sprintf("[inputRowIdx: %d]", i.inputRowIdx) } -// multiSpanGeneratorInequalityColInfo represents a column that is bound by a -// range expression. If there are <,>, >= or <= inequalities we distill them -// into a start and end datum. -type multiSpanGeneratorInequalityColInfo struct { - start tree.Datum - startInclusive bool - end tree.Datum - endInclusive bool -} - -func (i multiSpanGeneratorInequalityColInfo) String() string { - var startBoundary byte - if i.startInclusive { - startBoundary = '[' - } else { - startBoundary = '(' - } - var endBoundary rune - if i.endInclusive { - endBoundary = ']' - } else { - endBoundary = ')' - } - return fmt.Sprintf("%c%v - %v%c", startBoundary, i.start, i.end, endBoundary) -} - var _ multiSpanGeneratorColInfo = &multiSpanGeneratorValuesColInfo{} var _ multiSpanGeneratorColInfo = &multiSpanGeneratorIndexVarColInfo{} -var _ multiSpanGeneratorColInfo = &multiSpanGeneratorInequalityColInfo{} // init must be called before the multiSpanGenerator can be used to generate // spans. +// - spansCanOverlap indicates whether it is possible for the same spans to be +// used more than once for a given input batch. This is only the case when an +// inequality on an input column is used, since in that case we don't fully +// de-duplicate. func (g *multiSpanGenerator) init( evalCtx *eval.Context, codec keys.SQLCodec, @@ -397,13 +385,13 @@ func (g *multiSpanGenerator) init( exprHelper *execinfrapb.ExprHelper, fetchedOrdToIndexKeyOrd util.FastIntMap, memAcc *mon.BoundAccount, -) error { +) (spansCanOverlap bool, _ error) { g.spanBuilder.InitWithFetchSpec(evalCtx, codec, fetchSpec) g.spanSplitter = span.MakeSplitterWithFamilyIDs(len(fetchSpec.KeyFullColumns()), splitFamilyIDs) g.numInputCols = numInputCols g.spanKeyToSpanID = make(map[string]int) g.fetchedOrdToIndexKeyOrd = fetchedOrdToIndexKeyOrd - g.inequalityColIdx = -1 + g.inequalityInfo.colIdx = -1 g.memAcc = memAcc // Initialize the spansCount to 1, since we'll always have at least one span. @@ -414,20 +402,19 @@ func (g *multiSpanGenerator) init( // join conditions. This info will be used later to generate the spans. g.indexColInfos = make([]multiSpanGeneratorColInfo, 0, len(fetchSpec.KeyAndSuffixColumns)) if err := g.fillInIndexColInfos(exprHelper.Expr); err != nil { - return err + return false, err } // Check that the results of fillInIndexColInfos can be used to generate valid // spans. lookupColsCount := len(g.indexColInfos) - if lookupColsCount != g.indexOrds.Len() { - return errors.AssertionFailedf( - "columns in the join condition do not form a prefix on the index", - ) + if g.inequalityInfo.colIdx != -1 { + lookupColsCount++ } if lookupColsCount > len(fetchSpec.KeyAndSuffixColumns) { - return errors.AssertionFailedf( - "%d lookup columns specified, expecting at most %d", lookupColsCount, len(fetchSpec.KeyAndSuffixColumns), + return false, errors.AssertionFailedf( + "%d lookup columns specified, expecting at most %d", + lookupColsCount, len(fetchSpec.KeyAndSuffixColumns), ) } @@ -448,37 +435,50 @@ func (g *multiSpanGenerator) init( // tenant and id to be filled in later: // // [ 'east' - 1 - ] - // [ 'west' - 1 - ] // [ 'east' - 2 - ] + // [ 'west' - 1 - ] // [ 'west' - 2 - ] // - // Make first pass flushing out the structure with const values. - g.indexKeyRows = make([]rowenc.EncDatumRow, 1, g.spansCount) - g.indexKeyRows[0] = make(rowenc.EncDatumRow, 0, lookupColsCount) - for _, info := range g.indexColInfos { + // First fill the structure with empty EncDatum values. + g.indexKeyRows = make([]rowenc.EncDatumRow, g.spansCount) + for rowIdx := range g.indexKeyRows { + g.indexKeyRows[rowIdx] = make(rowenc.EncDatumRow, lookupColsCount) + } + + // Next replace the constant values according to the cartesian product, as in + // the example above. + productSize := len(g.indexKeyRows) + for colIdx, info := range g.indexColInfos { if valuesInfo, ok := info.(multiSpanGeneratorValuesColInfo); ok { - for i, n := 0, len(g.indexKeyRows); i < n; i++ { - indexKeyRow := g.indexKeyRows[i] - for j := 1; j < len(valuesInfo.constVals); j++ { - newIndexKeyRow := make(rowenc.EncDatumRow, len(indexKeyRow), lookupColsCount) - copy(newIndexKeyRow, indexKeyRow) - newIndexKeyRow = append(newIndexKeyRow, rowenc.EncDatum{Datum: valuesInfo.constVals[j]}) - g.indexKeyRows = append(g.indexKeyRows, newIndexKeyRow) - } - g.indexKeyRows[i] = append(indexKeyRow, rowenc.EncDatum{Datum: valuesInfo.constVals[0]}) - } - } else { - for i := 0; i < len(g.indexKeyRows); i++ { - // Just fill in an empty EncDatum for now -- this will be replaced - // inside generateNonNullSpans when we process each row. - g.indexKeyRows[i] = append(g.indexKeyRows[i], rowenc.EncDatum{}) + productSize /= len(valuesInfo.constVals) + for rowIdx := range g.indexKeyRows { + valueIdx := (rowIdx / productSize) % len(valuesInfo.constVals) + g.indexKeyRows[rowIdx][colIdx] = rowenc.EncDatum{Datum: valuesInfo.constVals[valueIdx]} } } } g.indexKeySpans = make(roachpb.Spans, 0, g.spansCount) - return nil + return lookupExprHasVarInequality(exprHelper.Expr), nil +} + +// lookupExprHasVarInequality returns true if the given lookup expression +// contains an inequality that references an input column. +func lookupExprHasVarInequality(lookupExpr tree.TypedExpr) bool { + switch t := lookupExpr.(type) { + case *tree.AndExpr: + return lookupExprHasVarInequality(t.Left.(tree.TypedExpr)) || + lookupExprHasVarInequality(t.Right.(tree.TypedExpr)) + case *tree.ComparisonExpr: + switch t.Operator.Symbol { + case treecmp.LT, treecmp.LE, treecmp.GT, treecmp.GE: + _, leftIsVar := t.Left.(*tree.IndexedVar) + _, rightIsVar := t.Right.(*tree.IndexedVar) + return leftIsVar && rightIsVar + } + } + return false } // fillInIndexColInfos recursively walks the expression tree to collect join @@ -503,11 +503,10 @@ func (g *multiSpanGenerator) fillInIndexColInfos(expr tree.TypedExpr) error { return g.fillInIndexColInfos(t.Right.(tree.TypedExpr)) case *tree.ComparisonExpr: - setOfVals := false - inequality := false + var inequality bool switch t.Operator.Symbol { case treecmp.EQ, treecmp.In: - setOfVals = true + inequality = false case treecmp.GE, treecmp.LE, treecmp.GT, treecmp.LT: inequality = true default: @@ -520,38 +519,42 @@ func (g *multiSpanGenerator) fillInIndexColInfos(expr tree.TypedExpr) error { var info multiSpanGeneratorColInfo // For EQ and In, we just need to check the types of the arguments in order - // to extract the info. For inequalities we return the const datums that + // to extract the info. For inequalities we return the expressions that // will form the span boundaries. - getInfo := func(typedExpr tree.TypedExpr) (tree.Datum, error) { + getInfo := func(typedExpr tree.TypedExpr) (tree.TypedExpr, error) { switch t := typedExpr.(type) { case *tree.IndexedVar: - // IndexedVars can either be from the input or the index. If the - // IndexedVar is from the index, shift it over by numInputCols to - // find the corresponding ordinal in the base table. if t.Idx >= g.numInputCols { + // The IndexedVar is from the index. shift it over to find the + // corresponding ordinal in the base table. tabOrd = t.Idx - g.numInputCols - } else { - info = multiSpanGeneratorIndexVarColInfo{inputRowIdx: t.Idx} + return nil, nil } + // The IndexedVar is from the input. It will be used to generate spans. + if inequality { + // We will use the IndexVar expression as an inequality bound. + return t, nil + } + info = multiSpanGeneratorIndexVarColInfo{inputRowIdx: t.Idx} case tree.Datum: - if setOfVals { - var values tree.Datums - switch t.ResolvedType().Family() { - case types.TupleFamily: - values = t.(*tree.DTuple).D - default: - values = tree.Datums{t} - } - // Every time there are multiple possible values, we multiply the - // spansCount by the number of possibilities. We will need to create - // spans representing the cartesian product of possible values for - // each column. - info = multiSpanGeneratorValuesColInfo{constVals: values} - g.spansCount *= len(values) - } else { + if inequality { + // We will use the Datum as an inequality bound. return t, nil } + var values tree.Datums + switch t.ResolvedType().Family() { + case types.TupleFamily: + values = t.(*tree.DTuple).D + default: + values = tree.Datums{t} + } + // Every time there are multiple possible values, we multiply the + // spansCount by the number of possibilities. We will need to create + // spans representing the cartesian product of possible values for + // each column. + info = multiSpanGeneratorValuesColInfo{constVals: values} + g.spansCount *= len(values) default: return nil, errors.AssertionFailedf("unhandled comparison argument type %T", t) @@ -577,50 +580,43 @@ func (g *multiSpanGenerator) fillInIndexColInfos(expr tree.TypedExpr) error { return errors.AssertionFailedf("table column %d not found in index", tabOrd) } - // Make sure slice has room for new entry. - if len(g.indexColInfos) <= idxOrd { - g.indexColInfos = g.indexColInfos[:idxOrd+1] - } - - if inequality { - // If we have two inequalities we might already have an info, ie if we - // have a < 10 and a > 0 we'll have two invocations of fillInIndexColInfo - // for each comparison and they need to update the same info. - colInfo := g.indexColInfos[idxOrd] - var inequalityInfo multiSpanGeneratorInequalityColInfo - if colInfo != nil { - inequalityInfo, ok = colInfo.(multiSpanGeneratorInequalityColInfo) - if !ok { - return errors.AssertionFailedf("unexpected colinfo type (%d): %T", idxOrd, colInfo) - } + if !inequality { + // Make sure slice has room for new entry. + if len(g.indexColInfos) <= idxOrd { + g.indexColInfos = g.indexColInfos[:idxOrd+1] } + g.indexColInfos[idxOrd] = info + return nil + } - if lval != nil { - if t.Operator.Symbol == treecmp.LT || t.Operator.Symbol == treecmp.LE { - inequalityInfo.start = lval - inequalityInfo.startInclusive = t.Operator.Symbol == treecmp.LE - } else { - inequalityInfo.end = lval - inequalityInfo.endInclusive = t.Operator.Symbol == treecmp.GE - } + if g.inequalityInfo.colIdx != -1 && g.inequalityInfo.colIdx != idxOrd { + return errors.AssertionFailedf("two inequality columns found: %d and %d", + g.inequalityInfo.colIdx, idxOrd) + } + g.inequalityInfo.colIdx = idxOrd + + if lval != nil { + g.inequalityInfo.colTyp = lval.ResolvedType() + if t.Operator.Symbol == treecmp.LT || t.Operator.Symbol == treecmp.LE { + g.inequalityInfo.start = lval + g.inequalityInfo.startInclusive = t.Operator.Symbol == treecmp.LE + } else { + g.inequalityInfo.end = lval + g.inequalityInfo.endInclusive = t.Operator.Symbol == treecmp.GE } + } - if rval != nil { - if t.Operator.Symbol == treecmp.LT || t.Operator.Symbol == treecmp.LE { - inequalityInfo.end = rval - inequalityInfo.endInclusive = t.Operator.Symbol == treecmp.LE - } else { - inequalityInfo.start = rval - inequalityInfo.startInclusive = t.Operator.Symbol == treecmp.GE - } + if rval != nil { + g.inequalityInfo.colTyp = rval.ResolvedType() + if t.Operator.Symbol == treecmp.LT || t.Operator.Symbol == treecmp.LE { + g.inequalityInfo.end = rval + g.inequalityInfo.endInclusive = t.Operator.Symbol == treecmp.LE + } else { + g.inequalityInfo.start = rval + g.inequalityInfo.startInclusive = t.Operator.Symbol == treecmp.GE } - info = inequalityInfo - g.inequalityColIdx = idxOrd } - g.indexColInfos[idxOrd] = info - g.indexOrds.Add(idxOrd) - default: return errors.AssertionFailedf("unhandled expression type %T", t) } @@ -647,27 +643,33 @@ func (g *multiSpanGenerator) generateNonNullSpans(row rowenc.EncDatumRow) (roach g.indexKeySpans = g.indexKeySpans[:0] // Hoist inequality lookup out of loop if we have one. - var inequalityInfo multiSpanGeneratorInequalityColInfo - if g.inequalityColIdx != -1 { - inequalityInfo = g.indexColInfos[g.inequalityColIdx].(multiSpanGeneratorInequalityColInfo) + var startBound, endBound *rowenc.EncDatum + if g.inequalityInfo.colIdx != -1 { + startBound, endBound = g.getInequalityBounds(row) } // Build spans for each row. for _, indexKeyRow := range g.indexKeyRows { var s roachpb.Span var err error - var containsNull bool - if g.inequalityColIdx == -1 { + var containsNull, filterRow bool + if g.inequalityInfo.colIdx == -1 { s, containsNull, err = g.spanBuilder.SpanFromEncDatums(indexKeyRow[:len(g.indexColInfos)]) } else { - s, containsNull, err = g.spanBuilder.SpanFromEncDatumsWithRange(indexKeyRow, len(g.indexColInfos), - inequalityInfo.start, inequalityInfo.startInclusive, inequalityInfo.end, inequalityInfo.endInclusive) + s, containsNull, filterRow, err = g.spanBuilder.SpanFromEncDatumsWithRange( + indexKeyRow, len(g.indexColInfos), startBound, endBound, + g.inequalityInfo.startInclusive, g.inequalityInfo.endInclusive, g.inequalityInfo.colTyp) } if err != nil { return roachpb.Spans{}, err } + if filterRow { + // The row has been filtered by the range conditions. + return roachpb.Spans{}, nil + } + if !containsNull { g.indexKeySpans = append(g.indexKeySpans, s) } @@ -689,13 +691,13 @@ func (g *multiSpanGenerator) generateSpans( } for j := range generatedSpans { generatedSpan := &generatedSpans[j] - spanID, newSpanKey := g.spanIDHelper.addInputRowIdxForSpan(string(generatedSpan.Key), i) + spanID, newSpanKey := g.spanIDHelper.addInputRowIdxForSpan(generatedSpan, i) if newSpanKey { numOldSpans := len(g.scratchSpans) // MaybeSplitSpanIntoSeparateFamilies is an optimization for doing more // efficient point lookups when the span hits multiple column families. // It doesn't work with inequality ranges because they aren't point lookups. - if g.inequalityColIdx != -1 { + if g.inequalityInfo.colIdx != -1 { g.scratchSpans = append(g.scratchSpans, *generatedSpan) } else { g.scratchSpans = g.spanSplitter.MaybeSplitSpanIntoSeparateFamilies( @@ -719,6 +721,26 @@ func (g *multiSpanGenerator) generateSpans( return g.scratchSpans, g.scratchSpanIDs, nil } +// getInequalityBounds returns the start and end bounds for the index column +// that is constrained by a range expression. If either the start or end is +// unconstrained, the corresponding bound is nil. +func (g *multiSpanGenerator) getInequalityBounds( + row []rowenc.EncDatum, +) (start, end *rowenc.EncDatum) { + getBound := func(expr tree.TypedExpr) *rowenc.EncDatum { + switch t := expr.(type) { + case tree.Datum: + return &rowenc.EncDatum{Datum: t} + case *tree.IndexedVar: + return &row[t.Idx] + } + return nil + } + start = getBound(g.inequalityInfo.start) + end = getBound(g.inequalityInfo.end) + return start, end +} + func (g *multiSpanGenerator) close(ctx context.Context) { g.memAcc.Close(ctx) *g = multiSpanGenerator{} @@ -751,28 +773,29 @@ func (g *localityOptimizedSpanGenerator) init( fetchedOrdToIndexKeyOrd util.FastIntMap, localSpanGenMemAcc *mon.BoundAccount, remoteSpanGenMemAcc *mon.BoundAccount, -) error { - if err := g.localSpanGen.init( +) (spansCanOverlap bool, err error) { + var localSpansCanOverlap, remoteSpansCanOverlap bool + if localSpansCanOverlap, err = g.localSpanGen.init( evalCtx, codec, fetchSpec, splitFamilyIDs, numInputCols, localExprHelper, fetchedOrdToIndexKeyOrd, localSpanGenMemAcc, ); err != nil { - return err + return false, err } - if err := g.remoteSpanGen.init( + if remoteSpansCanOverlap, err = g.remoteSpanGen.init( evalCtx, codec, fetchSpec, splitFamilyIDs, numInputCols, remoteExprHelper, fetchedOrdToIndexKeyOrd, remoteSpanGenMemAcc, ); err != nil { - return err + return false, err } // Check that the resulting span generators have the same lookup columns. localLookupCols := len(g.localSpanGen.indexColInfos) remoteLookupCols := len(g.remoteSpanGen.indexColInfos) if localLookupCols != remoteLookupCols { - return errors.AssertionFailedf( + return false, errors.AssertionFailedf( "local lookup cols (%d) != remote lookup cols (%d)", localLookupCols, remoteLookupCols, ) } - return nil + return localSpansCanOverlap || remoteSpansCanOverlap, nil } func (g *localityOptimizedSpanGenerator) setResizeMemoryAccountFunc(f resizeMemoryAccountFunc) { diff --git a/pkg/sql/schema_resolver.go b/pkg/sql/schema_resolver.go index e5291746964f..5d7902e9a5bd 100644 --- a/pkg/sql/schema_resolver.go +++ b/pkg/sql/schema_resolver.go @@ -414,7 +414,7 @@ func (sr *schemaResolver) ResolveFunction( extraMsg = fmt.Sprintf(", but %s() exists", alternative.Name) } } - return nil, pgerror.Newf(pgcode.UndefinedFunction, "unknown function: %s()%s", tree.ErrString(name), extraMsg) + return nil, errors.Wrapf(tree.ErrFunctionUndefined, "unknown function: %s()%s", tree.ErrString(name), extraMsg) } if builtinDef == nil { return udfDef, nil @@ -445,7 +445,7 @@ func (sr *schemaResolver) ResolveFunctionByOID( if !funcdesc.IsOIDUserDefinedFunc(oid) { name, ok := tree.OidToBuiltinName[oid] if !ok { - return "", nil, pgerror.Newf(pgcode.UndefinedFunction, "function %d not found", oid) + return "", nil, errors.Wrapf(tree.ErrFunctionUndefined, "function %d not found", oid) } funcDef := tree.FunDefs[name] for _, o := range funcDef.Definition { diff --git a/pkg/sql/schemachanger/scbuild/builder_state.go b/pkg/sql/schemachanger/scbuild/builder_state.go index a6de43e29442..f8a2f8e012a0 100644 --- a/pkg/sql/schemachanger/scbuild/builder_state.go +++ b/pkg/sql/schemachanger/scbuild/builder_state.go @@ -930,6 +930,12 @@ func (b *builderState) ensureDescriptor(id catid.DescID) { for _, objectID := range objectIDs { c.backrefs.Add(objectID) } + if err := d.ForEachFunctionOverload(func(overload descpb.SchemaDescriptor_FunctionOverload) error { + c.backrefs.Add(overload.ID) + return nil + }); err != nil { + panic(err) + } default: b.ensureDescriptor(c.desc.GetParentID()) db := b.descCache[c.desc.GetParentID()].desc diff --git a/pkg/sql/schemachanger/scbuild/dependencies.go b/pkg/sql/schemachanger/scbuild/dependencies.go index 9130107e6e8c..2c058bd28947 100644 --- a/pkg/sql/schemachanger/scbuild/dependencies.go +++ b/pkg/sql/schemachanger/scbuild/dependencies.go @@ -102,6 +102,7 @@ type CreatePartitioningCCLCallback func( type CatalogReader interface { tree.TypeReferenceResolver tree.QualifiedNameResolver + tree.FunctionReferenceResolver // MayResolveDatabase looks up a database by name. MayResolveDatabase(ctx context.Context, name tree.Name) catalog.DatabaseDescriptor diff --git a/pkg/sql/schemachanger/scbuild/tree_context_builder.go b/pkg/sql/schemachanger/scbuild/tree_context_builder.go index 6d3877dda18d..d9e5e1725d64 100644 --- a/pkg/sql/schemachanger/scbuild/tree_context_builder.go +++ b/pkg/sql/schemachanger/scbuild/tree_context_builder.go @@ -32,6 +32,7 @@ func newSemaCtx(d Dependencies) *tree.SemaContext { semaCtx.Annotations = nil semaCtx.SearchPath = &d.SessionData().SearchPath semaCtx.TypeResolver = d.CatalogReader() + semaCtx.FunctionResolver = d.CatalogReader() semaCtx.TableNameResolver = d.CatalogReader() semaCtx.DateStyle = d.SessionData().GetDateStyle() semaCtx.IntervalStyle = d.SessionData().GetIntervalStyle() diff --git a/pkg/sql/schemachanger/scdeps/build_deps.go b/pkg/sql/schemachanger/scdeps/build_deps.go index 0dd5dce1d514..d98c09740575 100644 --- a/pkg/sql/schemachanger/scdeps/build_deps.go +++ b/pkg/sql/schemachanger/scdeps/build_deps.go @@ -210,6 +210,20 @@ func (d *buildDeps) ResolveTypeByOID(ctx context.Context, oid oid.Oid) (*types.T return d.schemaResolver.ResolveTypeByOID(ctx, oid) } +// ResolveFunction implements the scbuild.CatalogReader interface. +func (d *buildDeps) ResolveFunction( + ctx context.Context, name *tree.UnresolvedName, path tree.SearchPath, +) (*tree.ResolvedFunctionDefinition, error) { + return d.schemaResolver.ResolveFunction(ctx, name, path) +} + +// ResolveFunctionByOID implements the scbuild.CatalogReader interface. +func (d *buildDeps) ResolveFunctionByOID( + ctx context.Context, oid oid.Oid, +) (string, *tree.Overload, error) { + return d.schemaResolver.ResolveFunctionByOID(ctx, oid) +} + // GetQualifiedTableNameByID implements the scbuild.CatalogReader interface. func (d *buildDeps) GetQualifiedTableNameByID( ctx context.Context, id int64, requiredType tree.RequiredTableKind, diff --git a/pkg/sql/schemachanger/scdeps/sctestdeps/test_deps.go b/pkg/sql/schemachanger/scdeps/sctestdeps/test_deps.go index f3ab167b552a..81106b3941fc 100644 --- a/pkg/sql/schemachanger/scdeps/sctestdeps/test_deps.go +++ b/pkg/sql/schemachanger/scdeps/sctestdeps/test_deps.go @@ -1148,3 +1148,37 @@ func (s *TestState) GetTestingKnobs() *scexec.TestingKnobs { func (s *TestState) AddTableForStatsRefresh(id descpb.ID) { s.LogSideEffectf("adding table for stats refresh: %d", id) } + +// ResolveFunction implements the scbuild.CatalogReader interface. +func (s *TestState) ResolveFunction( + ctx context.Context, name *tree.UnresolvedName, path tree.SearchPath, +) (*tree.ResolvedFunctionDefinition, error) { + // TODO(chengxiong): add UDF support for test. + fn, err := name.ToFunctionName() + if err != nil { + return nil, err + } + fd, err := tree.GetBuiltinFuncDefinitionOrFail(fn, path) + if err != nil { + return nil, err + } + return fd, nil +} + +// ResolveFunctionByOID implements the scbuild.CatalogReader interface. +func (s *TestState) ResolveFunctionByOID( + ctx context.Context, oid oid.Oid, +) (string, *tree.Overload, error) { + // TODO(chengxiong): add UDF support for test. + name, ok := tree.OidToBuiltinName[oid] + if !ok { + return "", nil, errors.Newf("function %d not found", oid) + } + funcDef := tree.FunDefs[name] + for _, o := range funcDef.Definition { + if o.Oid == oid { + return funcDef.Name, o, nil + } + } + return "", nil, errors.Newf("function %d not found", oid) +} diff --git a/pkg/sql/sem/catconstants/constants.go b/pkg/sql/sem/catconstants/constants.go index 1a85e45691c1..99ec1098d25e 100644 --- a/pkg/sql/sem/catconstants/constants.go +++ b/pkg/sql/sem/catconstants/constants.go @@ -97,6 +97,7 @@ const ( CrdbInternalClusterContendedTablesViewID CrdbInternalClusterContentionEventsTableID CrdbInternalClusterDistSQLFlowsTableID + CrdbInternalClusterExecutionInsightsTableID CrdbInternalClusterLocksTableID CrdbInternalClusterQueriesTableID CrdbInternalClusterTransactionsTableID diff --git a/pkg/sql/sem/tree/function_definition.go b/pkg/sql/sem/tree/function_definition.go index c10540dba848..d9b8501b179b 100644 --- a/pkg/sql/sem/tree/function_definition.go +++ b/pkg/sql/sem/tree/function_definition.go @@ -11,9 +11,12 @@ package tree import ( + "strings" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants" + "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/iterutil" "github.com/cockroachdb/errors" "github.com/lib/pq/oid" @@ -238,6 +241,63 @@ func (fd *ResolvedFunctionDefinition) MergeWith( }, nil } +// MatchOverload searches an overload which takes exactly the same input +// argument types. The overload from the most significant schema is returned. If +// argTypes==nil, an error is returned if the function name is not unique in the +// most significant schema. If argTypes is not nil, an error with +// ErrFunctionUndefined cause is returned if not matched found. +func (fd *ResolvedFunctionDefinition) MatchOverload( + argTypes []*types.T, explicitSchema string, searchPath SearchPath, +) (QualifiedOverload, error) { + matched := func(ol QualifiedOverload, schema string) bool { + return schema == ol.Schema && (argTypes == nil || ol.params().Match(argTypes)) + } + typeNames := func() string { + ns := make([]string, len(argTypes)) + for i, t := range argTypes { + ns[i] = t.Name() + } + return strings.Join(ns, ",") + } + + found := false + ret := make([]QualifiedOverload, 0, len(fd.Overloads)) + + findMatches := func(schema string) { + for i := range fd.Overloads { + if matched(fd.Overloads[i], schema) { + found = true + ret = append(ret, fd.Overloads[i]) + } + } + } + + if explicitSchema != "" { + findMatches(explicitSchema) + } else { + err := searchPath.IterateSearchPath(func(schema string) error { + findMatches(schema) + if found { + return iterutil.StopIteration() + } + return nil + }) + if err != nil { + return QualifiedOverload{}, err + } + } + + if len(ret) == 0 { + return QualifiedOverload{}, errors.Wrapf( + ErrFunctionUndefined, "function %s(%s) does not exist", fd.Name, typeNames(), + ) + } + if len(ret) > 1 { + return QualifiedOverload{}, errors.Errorf("function name %q is not unique", fd.Name) + } + return ret[0], nil +} + func combineOverloads(a, b []QualifiedOverload) []QualifiedOverload { return append(append(make([]QualifiedOverload, 0, len(a)+len(b)), a...), b...) } @@ -316,7 +376,7 @@ func GetBuiltinFuncDefinitionOrFail( return nil, err } if def == nil { - return nil, pgerror.Newf(pgcode.UndefinedFunction, "unknown function: %s()", ErrString(fName)) + return nil, errors.Wrapf(ErrFunctionUndefined, "unknown function: %s()", ErrString(fName)) } return def, nil } diff --git a/pkg/sql/sem/tree/function_definition_test.go b/pkg/sql/sem/tree/function_definition_test.go index 6ab9c4010295..782412519caa 100644 --- a/pkg/sql/sem/tree/function_definition_test.go +++ b/pkg/sql/sem/tree/function_definition_test.go @@ -15,8 +15,10 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" + "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/lib/pq/oid" "github.com/stretchr/testify/require" ) @@ -85,3 +87,122 @@ func TestBuiltinFunctionResolver(t *testing.T) { }) } } + +func TestMatchOverload(t *testing.T) { + defer leaktest.AfterTest(t)() + defer log.Scope(t).Close(t) + + fd := &tree.ResolvedFunctionDefinition{ + Name: "f", + Overloads: []tree.QualifiedOverload{ + { + Schema: "pg_catalog", + Overload: &tree.Overload{Oid: 1, IsUDF: false, Types: tree.ArgTypes{tree.ArgType{Typ: types.Int}}}, + }, + { + Schema: "sc1", + Overload: &tree.Overload{Oid: 2, IsUDF: true, Types: tree.ArgTypes{tree.ArgType{Typ: types.Int}}}, + }, + { + Schema: "sc1", + Overload: &tree.Overload{Oid: 3, IsUDF: true, Types: tree.ArgTypes{}}, + }, + { + Schema: "sc2", + Overload: &tree.Overload{Oid: 4, IsUDF: true, Types: tree.ArgTypes{tree.ArgType{Typ: types.Int}}}, + }, + }, + } + + testCase := []struct { + testName string + argTypes []*types.T + explicitSchema string + path []string + expectedOid oid.Oid + expectedErr string + }{ + { + testName: "nil arg types implicit pg_catalog in path", + argTypes: nil, + path: []string{"sc1", "sc2"}, + expectedOid: 1, + }, + { + testName: "nil arg types explicit pg_catalog in path", + argTypes: nil, + path: []string{"sc2", "sc1", "pg_catalog"}, + expectedOid: 4, + }, + { + testName: "nil arg types explicit pg_catalog in path not unique", + argTypes: nil, + path: []string{"sc1", "sc2", "pg_catalog"}, + expectedErr: `function name "f" is not unique`, + }, + { + testName: "int arg type implicit pg_catalog in path", + argTypes: []*types.T{types.Int}, + path: []string{"sc1", "sc2"}, + expectedOid: 1, + }, + { + testName: "empty arg type implicit pg_catalog in path", + argTypes: []*types.T{}, + path: []string{"sc1", "sc2"}, + expectedOid: 3, + }, + { + testName: "int arg types explicit pg_catalog in path", + argTypes: []*types.T{types.Int}, + path: []string{"sc1", "sc2", "pg_catalog"}, + expectedOid: 2, + }, + { + testName: "int arg types explicit pg_catalog in path schema order matters", + argTypes: []*types.T{types.Int}, + path: []string{"sc2", "sc1", "pg_catalog"}, + expectedOid: 4, + }, + { + testName: "explicit schema in search path", + argTypes: []*types.T{types.Int}, + explicitSchema: "sc2", + path: []string{"sc2", "sc1", "pg_catalog"}, + expectedOid: 4, + }, + { + testName: "explicit schema not in search path", + argTypes: []*types.T{types.Int}, + explicitSchema: "sc2", + path: []string{"sc1", "pg_catalog"}, + expectedOid: 4, + }, + { + testName: "explicit schema not in search path not found", + argTypes: []*types.T{types.Int}, + explicitSchema: "sc3", + path: []string{"s2", "sc1", "pg_catalog"}, + expectedErr: `function f\(int\) does not exist`, + }, + { + testName: "signature not found", + argTypes: []*types.T{types.String}, + path: []string{"sc2", "sc1", "pg_catalog"}, + expectedErr: `function f\(string\) does not exist`, + }, + } + + for _, tc := range testCase { + t.Run(tc.testName, func(t *testing.T) { + path := sessiondata.MakeSearchPath(tc.path) + ol, err := fd.MatchOverload(tc.argTypes, tc.explicitSchema, &path) + if tc.expectedErr != "" { + require.Regexp(t, tc.expectedErr, err.Error()) + return + } + require.NoError(t, err) + require.Equal(t, tc.expectedOid, ol.Oid) + }) + } +} diff --git a/pkg/sql/sem/tree/function_name.go b/pkg/sql/sem/tree/function_name.go index 744ab62b3a6f..572e69c62c3b 100644 --- a/pkg/sql/sem/tree/function_name.go +++ b/pkg/sql/sem/tree/function_name.go @@ -15,12 +15,19 @@ import ( "fmt" "strings" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants" "github.com/cockroachdb/errors" "github.com/cockroachdb/redact" "github.com/lib/pq/oid" ) +// ErrFunctionUndefined indicates that the required function is not found. It is +// used as the cause of the errors thrown when function resolution cannot find a +// required function. +var ErrFunctionUndefined = pgerror.Newf(pgcode.UndefinedFunction, "function undefined") + // Function names are used in expressions in the FuncExpr node. // General syntax: // [ . ] @@ -34,7 +41,9 @@ import ( // resolve built-in or user-defined function definitions from unresolved names. type FunctionReferenceResolver interface { // ResolveFunction resolves a group of overloads with the given function name - // within a search path. + // within a search path. An error with ErrFunctionUndefined cause is returned + // if function does not exist. + // // TODO(Chengxiong): Consider adding an optional slice of argument types to // the input of this method, so that we can try to narrow down the scope of // overloads a bit earlier and decrease the possibility of ambiguous error diff --git a/pkg/sql/sem/tree/udf.go b/pkg/sql/sem/tree/udf.go index a2a6d64b5107..2aa2f0cf94ad 100644 --- a/pkg/sql/sem/tree/udf.go +++ b/pkg/sql/sem/tree/udf.go @@ -11,10 +11,13 @@ package tree import ( + "context" "strings" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" + "github.com/cockroachdb/cockroach/pkg/sql/types" + "github.com/cockroachdb/cockroach/pkg/util/errorutil/unimplemented" "github.com/cockroachdb/errors" ) @@ -356,6 +359,27 @@ func (node FuncObj) Format(ctx *FmtCtx) { } } +// InputArgTypes returns a slice of argument types of the function. +func (node FuncObj) InputArgTypes( + ctx context.Context, res TypeReferenceResolver, +) ([]*types.T, error) { + // TODO(chengxiong): handle INOUT, OUT and VARIADIC argument classes when we + // support them. This is because only IN and INOUT arg types need to be + // considered to match a overload. + var argTypes []*types.T + if node.Args != nil { + argTypes = make([]*types.T, len(node.Args)) + for i, arg := range node.Args { + typ, err := ResolveType(ctx, arg.Type, res) + if err != nil { + return nil, err + } + argTypes[i] = typ + } + } + return argTypes, nil +} + // AlterFunctionOptions represents a ALTER FUNCTION...action statement. type AlterFunctionOptions struct { Function FuncObj @@ -431,3 +455,36 @@ func (node *AlterFunctionDepExtension) Format(ctx *FmtCtx) { ctx.WriteString(" DEPENDS ON EXTENSION ") ctx.WriteString(string(node.Extension)) } + +// UDFDisallowanceVisitor is used to determine if a type checked expression +// contains any UDF function sub-expression. It's needed only temporarily to +// disallow any usage of UDF from relation objects. +type UDFDisallowanceVisitor struct { + FoundUDF bool +} + +// VisitPre implements the Visitor interface. +func (v *UDFDisallowanceVisitor) VisitPre(expr Expr) (recurse bool, newExpr Expr) { + if funcExpr, ok := expr.(*FuncExpr); ok && funcExpr.ResolvedOverload().IsUDF { + v.FoundUDF = true + return false, expr + } + return true, expr +} + +// VisitPost implements the Visitor interface. +func (v *UDFDisallowanceVisitor) VisitPost(expr Expr) (newNode Expr) { + return expr +} + +// MaybeFailOnUDFUsage returns an error if the given expression or any +// sub-expression used a UDF. +// TODO(chengxiong): remove this function when we start allowing UDF references. +func MaybeFailOnUDFUsage(expr TypedExpr) error { + visitor := &UDFDisallowanceVisitor{} + WalkExpr(visitor, expr) + if visitor.FoundUDF { + return unimplemented.NewWithIssue(83234, "usage of user-defined function from relations not supported") + } + return nil +} diff --git a/pkg/sql/span/BUILD.bazel b/pkg/sql/span/BUILD.bazel index 4c1c5fc17eaf..206782e9801a 100644 --- a/pkg/sql/span/BUILD.bazel +++ b/pkg/sql/span/BUILD.bazel @@ -22,6 +22,7 @@ go_library( "//pkg/sql/rowenc/keyside", "//pkg/sql/sem/eval", "//pkg/sql/sem/tree", + "//pkg/sql/types", "//pkg/util", "//pkg/util/encoding", "@com_github_cockroachdb_errors//:errors", diff --git a/pkg/sql/span/span_builder.go b/pkg/sql/span/span_builder.go index 60b93ddbab90..b03918922118 100644 --- a/pkg/sql/span/span_builder.go +++ b/pkg/sql/span/span_builder.go @@ -25,6 +25,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/rowenc/keyside" "github.com/cockroachdb/cockroach/pkg/sql/sem/eval" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/types" "github.com/cockroachdb/cockroach/pkg/util/encoding" "github.com/cockroachdb/errors" ) @@ -75,55 +76,80 @@ func (s *Builder) SpanFromEncDatums( // SpanFromEncDatumsWithRange encodes a range span. The inequality is assumed to // be the end of the span and the start/end keys are generated by putting them -// in the values row at the prefixLen - 1 position. Only one of start or end +// in the values row at the prefixLen position. Only one of start or end // need be non-nil, omitted one causing an open ended range span to be // generated. Since the exec code knows nothing about index column sorting // direction we assume ascending if they are descending we deal with that here. func (s *Builder) SpanFromEncDatumsWithRange( values rowenc.EncDatumRow, prefixLen int, - startDatum tree.Datum, - startInclusive bool, - endDatum tree.Datum, - endInclusive bool, -) (_ roachpb.Span, containsNull bool, err error) { - - isDesc := s.keyAndPrefixCols[prefixLen-1].Direction == catpb.IndexColumn_DESC + startBound, endBound *rowenc.EncDatum, + startInclusive, endInclusive bool, + rangeColTyp *types.T, +) (_ roachpb.Span, containsNull, filterRow bool, err error) { + isDesc := s.keyAndPrefixCols[prefixLen].Direction == catpb.IndexColumn_DESC if isDesc { - startDatum, endDatum = endDatum, startDatum + startBound, endBound = endBound, startBound startInclusive, endInclusive = endInclusive, startInclusive } + if startBound != nil { + if err = startBound.EnsureDecoded(rangeColTyp, &s.alloc); err != nil { + return roachpb.Span{}, false, false, err + } + if startBound.IsNull() { + // Inequalities are null-rejecting. + return roachpb.Span{}, true, true, nil + } + if !startInclusive { + if (isDesc && startBound.Datum.IsMin(s.evalCtx)) || + (!isDesc && startBound.Datum.IsMax(s.evalCtx)) { + // There are no values that satisfy the start bound. + return roachpb.Span{}, false, true, nil + } + } + } + if endBound != nil { + if err = endBound.EnsureDecoded(rangeColTyp, &s.alloc); err != nil { + return roachpb.Span{}, false, false, err + } + if endBound.IsNull() { + // Inequalities are null-rejecting. + return roachpb.Span{}, true, true, nil + } + } + makeKeyFromRow := func(r rowenc.EncDatumRow) (_ roachpb.Key, containsNull bool, _ error) { return rowenc.MakeKeyFromEncDatums(r, s.keyAndPrefixCols, &s.alloc, s.KeyPrefix) } var startKey, endKey roachpb.Key var startContainsNull, endContainsNull bool - if startDatum != nil { - if !startInclusive { - // Since the spans are defined such that the start boundary is - // inclusive, yet our inequality condition wants to exclude it, - // we'll "advance" the start datum by one. + if startBound != nil { + startDatum := startBound.Datum + if !startInclusive && isDesc { + // We need the datum that sorts immediately before startDatum in order + // to make the start boundary inclusive. The optimizer should have + // filtered cases where this is not possible. If the index column is ASC, + // we can directly increment the key below instead of the datum. var ok bool - if isDesc { - startDatum, ok = startDatum.Prev(s.evalCtx) - } else { - startDatum, ok = startDatum.Next(s.evalCtx) - } + startDatum, ok = startDatum.Prev(s.evalCtx) if !ok { - // The optimizer should have checked that the datum can be - // "advanced" when construing the range-based lookup join, so - // this is unexpected. - return roachpb.Span{}, false, errors.AssertionFailedf( - "couldn't get a Next or Prev value for %s", startDatum, + return roachpb.Span{}, false, false, errors.AssertionFailedf( + "couldn't get a Prev value for %s", startBound.Datum, ) } } - values[prefixLen-1] = rowenc.EncDatum{Datum: startDatum} - startKey, startContainsNull, err = makeKeyFromRow(values[:prefixLen]) + values[prefixLen] = rowenc.EncDatum{Datum: startDatum} + startKey, startContainsNull, err = makeKeyFromRow(values[:prefixLen+1]) + if !startInclusive && !isDesc { + // The start key of a span is always inclusive, so we need to increment to + // the key that sorts immediately after this one in order to make it + // exclusive. + startKey = startKey.PrefixEnd() + } } else { - startKey, startContainsNull, err = makeKeyFromRow(values[:prefixLen-1]) + startKey, startContainsNull, err = makeKeyFromRow(values[:prefixLen]) // If we have an ascending index make sure not to include NULLs. if !isDesc { startKey = encoding.EncodeNotNullAscending(startKey) @@ -131,17 +157,18 @@ func (s *Builder) SpanFromEncDatumsWithRange( } if err != nil { - return roachpb.Span{}, false, err + return roachpb.Span{}, false, false, err } - if endDatum != nil { - values[prefixLen-1] = rowenc.EncDatum{Datum: endDatum} - endKey, endContainsNull, err = makeKeyFromRow(values[:prefixLen]) + if endBound != nil { + endDatum := endBound.Datum + values[prefixLen] = rowenc.EncDatum{Datum: endDatum} + endKey, endContainsNull, err = makeKeyFromRow(values[:prefixLen+1]) if endInclusive { endKey = endKey.PrefixEnd() } } else { - endKey, endContainsNull, err = makeKeyFromRow(values[:prefixLen-1]) + endKey, endContainsNull, err = makeKeyFromRow(values[:prefixLen]) // If we have a descending index make sure not to include NULLs. if isDesc { endKey = encoding.EncodeNotNullDescending(endKey) @@ -151,10 +178,16 @@ func (s *Builder) SpanFromEncDatumsWithRange( } if err != nil { - return roachpb.Span{}, false, err + return roachpb.Span{}, false, false, err + } + + if startKey.Compare(endKey) >= 0 { + // It is possible that the inequality bounds filter out the input row. + return roachpb.Span{}, false, true, nil } - return roachpb.Span{Key: startKey, EndKey: endKey}, startContainsNull || endContainsNull, nil + span := roachpb.Span{Key: startKey, EndKey: endKey} + return span, startContainsNull || endContainsNull, false, nil } // SpanFromDatumRow generates an index span with prefixLen constraint columns from the index. diff --git a/pkg/sql/sqlstats/insights/integration/insights_test.go b/pkg/sql/sqlstats/insights/integration/insights_test.go index 7557305b22dc..36b211851381 100644 --- a/pkg/sql/sqlstats/insights/integration/insights_test.go +++ b/pkg/sql/sqlstats/insights/integration/insights_test.go @@ -55,7 +55,7 @@ func TestInsightsIntegration(t *testing.T) { // See no recorded insights. var count int - row := conn.QueryRowContext(ctx, "SELECT count(*) FROM crdb_internal.node_execution_insights") + row := conn.QueryRowContext(ctx, "SELECT count(*) FROM crdb_internal.cluster_execution_insights") err := row.Scan(&count) require.NoError(t, err) require.Equal(t, 0, count) @@ -67,7 +67,7 @@ func TestInsightsIntegration(t *testing.T) { // Eventually see one recorded insight. testutils.SucceedsWithin(t, func() error { - row = conn.QueryRowContext(ctx, "SELECT count(*) FROM crdb_internal.node_execution_insights") + row = conn.QueryRowContext(ctx, "SELECT count(*) FROM crdb_internal.cluster_execution_insights") if err = row.Scan(&count); err != nil { return err } diff --git a/pkg/storage/pebble.go b/pkg/storage/pebble.go index bfac4cefa12b..178e55332c2f 100644 --- a/pkg/storage/pebble.go +++ b/pkg/storage/pebble.go @@ -468,6 +468,27 @@ func (tc *pebbleDataBlockMVCCTimeIntervalCollector) UpdateKeySuffixes( const mvccWallTimeIntervalCollector = "MVCCTimeInterval" +var _ pebble.BlockPropertyFilterMask = (*mvccWallTimeIntervalRangeKeyMask)(nil) + +type mvccWallTimeIntervalRangeKeyMask struct { + sstable.BlockIntervalFilter +} + +// SetSuffix implements the pebble.BlockPropertyFilterMask interface. +func (m *mvccWallTimeIntervalRangeKeyMask) SetSuffix(suffix []byte) error { + if len(suffix) == 0 { + // This is currently impossible, because the only range key Cockroach + // writes today is the MVCC Delete Range that's always suffixed. + return nil + } + ts, err := DecodeMVCCTimestampSuffix(suffix) + if err != nil { + return err + } + m.BlockIntervalFilter.SetInterval(uint64(ts.WallTime), math.MaxUint64) + return nil +} + // PebbleBlockPropertyCollectors is the list of functions to construct // BlockPropertyCollectors. var PebbleBlockPropertyCollectors = []func() pebble.BlockPropertyCollector{ diff --git a/pkg/storage/pebble_iterator.go b/pkg/storage/pebble_iterator.go index da919c907474..d6e565dba19b 100644 --- a/pkg/storage/pebble_iterator.go +++ b/pkg/storage/pebble_iterator.go @@ -40,6 +40,8 @@ type pebbleIterator struct { lowerBoundBuf []byte upperBoundBuf []byte rangeKeyMaskingBuf []byte + // Filter to use if masking is enabled. + maskFilter mvccWallTimeIntervalRangeKeyMask // True if the iterator's underlying reader supports range keys. // @@ -223,6 +225,8 @@ func (p *pebbleIterator) setOptions(opts IterOptions, durability DurabilityRequi p.rangeKeyMaskingBuf = encodeMVCCTimestampSuffixToBuf( p.rangeKeyMaskingBuf, opts.RangeKeyMaskingBelow) p.options.RangeKeyMasking.Suffix = p.rangeKeyMaskingBuf + p.maskFilter.BlockIntervalFilter.Init(mvccWallTimeIntervalCollector, 0, math.MaxUint64) + p.options.RangeKeyMasking.Filter = &p.maskFilter } if opts.MaxTimestampHint.IsSet() {