-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sql: improve pg_table_is_visible performance #59880
Conversation
b758054
to
d593785
Compare
pkg/sql/sem/builtins/pg_builtins.go
Outdated
"SELECT nspname FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON c.relnamespace=n.oid "+ | ||
"WHERE c.oid=$1 AND nspname=ANY(current_schemas(true))", oid) | ||
oid := tree.MustBeDOid(args[0]) | ||
isVisibe, err := ctx.Planner.IsTableVisible(ctx.Context, ctx.SessionData.SearchPath, int64(oid.DInt)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VISIBE!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixd
pkg/sql/resolver.go
Outdated
@@ -205,6 +206,31 @@ func (p *planner) CommonLookupFlags(required bool) tree.CommonLookupFlags { | |||
} | |||
} | |||
|
|||
// IsTableVisible is part of the tree.EvalDatabase interface. | |||
func (p *planner) IsTableVisible( | |||
ctx context.Context, searchPath sessiondata.SearchPath, tableId int64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: tableID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix'd
return false, nil | ||
} | ||
iter := searchPath.Iter() | ||
for scName, ok := iter.Next(); ok; scName, ok = iter.Next() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to check database too? what if db is in dropping state?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhh i guess not since it relies on search path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm actually my code won't work because you could have two schemas in different databases, but with the same name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess the old code had the same bug..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HMMM though actually when cross-database references are fully banned, then we don't need to worry about it... (#55791)
pkg/sql/sem/tree/eval.go
Outdated
|
||
// IsTableVisible checks if the table with the given ID belongs to a schema | ||
// on the given sessiondata.SearchPath. | ||
IsTableVisible(ctx context.Context, searchPath sessiondata.SearchPath, tableId int64) (bool, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: tableID
d593785
to
57340dd
Compare
RFAL -- i updated to explicitly account for cross-db references (and match the PG behavior) |
This is motivated by a query that Django makes in order to retrieve all the tables visible in the current session. The query uses the pg_table_is_visible function. Previously this was implemented by using the internal executor to inspect the pg_catalog. This was expensive because the internal executor does not share the same descriptor collection as the external context, so it ended up fetching every single table descriptor one-by-one. Now, we avoid the internal executor and lookup the table descriptor directly. There are other builtins that use the internal executor that may face the same problem. Perhaps an approach for the future is to allow builtin functions to be implemented using user-defined scalar functions. I added a benchmark that shows the original Django query performing a constant number of descriptor lookups with this new implementation. Previously, the same benchmark would make hundreds of roundtrips. Release note (performance improvement): Improve performance of the pg_table_is_visible builtin function.
57340dd
to
061e90e
Compare
tftr! bors r=otan |
i mean bors r=otan |
Build succeeded: |
This is motivated by a query that Django makes in order to retrieve all
the tables visible in the current session. The query uses the
pg_table_is_visible function. Previously this was implemented by using
the internal executor to inspect the pg_catalog. This was expensive
because the internal executor does not share the same descriptor
collection as the external context, so it ended up fetching every single
table descriptor one-by-one.
Now, we avoid the internal executor and lookup the table descriptor
directly.
There are other builtins that use the internal executor that may face
the same problem. Perhaps an approach for the future is to allow builtin
functions to be implemented using user-defined scalar functions.
I added a benchmark that shows the original Django query performing a
constant number of descriptor lookups with this new implementation.
fixes #57924
Release note (performance improvement): Improve performance of the
pg_table_is_visible builtin function.