Skip to content

Commit

Permalink
Support Cross-database references in views (babelfish-for-postgresql#…
Browse files Browse the repository at this point in the history
…2899) (babelfish-for-postgresql#2956)

Support execution of views which references objects (tables/views/functions) from
across the databases. Here we are talking about Babelfish logical database (T-SQL database)
which is different from a physical Postgres database.
To support this, perform permission checks for cross database objects using session user (login)
instead of current_user (user of current T-SQL database). The reason login can be used for
permission check is since login is member of all it’s users, so it inherits all their permissions so it
will be able execute any cross database objects owned by its users.

This commit handles functions and tables/views separately for cross database permission
checks. For functions/procedures, a new hook `ExecFuncProc_AclCheck_hook` and for tables/views
existing `ExecutorStart_hook` will be used to decide whether to use session user or current_user
for permission check depending upon whether the object is from same or different database.
We will be using `is_schema_from_db` function to identify if the object is from different database
which performs a lookup into `babelfish_namespace_ext` catalog table which can be expensive as will
be doing it pretty frequently. So, added this table into SYSCACHE for better performance.
Tables/views permissions are handled slightly different than functions as we do not blindly want to check
the permissions against session user (current login) since permissions of RTEs inside a view are checked
against that view's owner which can very well be a user of some different database. So if we blindly check
permission against session user instead of view's owner then it would break view's ownership chaining.
Instead, we will replace `checkAsUser` with it's corresponding mapped login if present and only in cases
where `checkAsUser` is not set, we will replace it with session user (login). We are using login to allow cross
database queries since login can access all its objects across the databases. Getting mapped login to a
user require lookup into sys.babelfish_authid_user_ext catalog table using its primary key column (rolname) so
added this table is also into SYSCACHE.

Additionally, remove previous code to globally set current user to session user since newer logic
takes care of the permission check now.

Task: BABEL-5206
Signed-off-by: Rishabh Tanwar <[email protected]>

Engine PR: babelfish-for-postgresql/postgresql_modified_for_babelfish#434
  • Loading branch information
rishabhtanwar29 authored Sep 24, 2024
1 parent ffdb092 commit bdca706
Show file tree
Hide file tree
Showing 29 changed files with 1,415 additions and 384 deletions.
14 changes: 7 additions & 7 deletions contrib/babelfishpg_tsql/sql/ownership.sql
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,6 @@ where ext.dbid = sys.db_id();
GRANT SELECT ON sys.schemas TO PUBLIC;
CREATE SEQUENCE sys.babelfish_db_seq MAXVALUE 32767 CYCLE;

-- CATALOG INITIALIZER
CREATE OR REPLACE PROCEDURE babel_catalog_initializer()
LANGUAGE C
AS 'babelfishpg_tsql', 'init_catalog';

CALL babel_catalog_initializer();

CREATE OR REPLACE PROCEDURE babel_create_builtin_dbs(IN login TEXT)
LANGUAGE C
AS 'babelfishpg_tsql', 'create_builtin_dbs';
Expand Down Expand Up @@ -408,6 +401,13 @@ SELECT pg_catalog.pg_extension_config_dump('sys.babelfish_authid_login_ext', '')
SELECT pg_catalog.pg_extension_config_dump('sys.babelfish_authid_user_ext', '');
SELECT pg_catalog.pg_extension_config_dump('sys.babelfish_schema_permissions', '');

-- CATALOG INITIALIZER
CREATE OR REPLACE PROCEDURE babel_catalog_initializer()
LANGUAGE C
AS 'babelfishpg_tsql', 'init_catalog';

CALL babel_catalog_initializer();

-- DATABASE_PRINCIPALS
CREATE OR REPLACE VIEW sys.database_principals AS
SELECT
Expand Down
Loading

0 comments on commit bdca706

Please sign in to comment.