{"record":{"id":"fd9c63b222f760e7","repo":"prestodb/presto","slug":"view-owner-s-cannot-create-view-that-selects-fr","errorCode":null,"errorMessage":"View owner '%s' cannot create view that selects from %s%s","messagePattern":"View owner '(.+?)' cannot create view that selects from (.+?)(.+?)","errorType":"exception","errorClass":"AccessDeniedException","httpStatus":null,"severity":"error","filePath":"presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java","lineNumber":282,"sourceCode":"\n    public static void denyCreateView(String viewName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot create view %s%s\", viewName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyCreateViewWithSelect(String sourceName, Identity identity)\n    {\n        denyCreateViewWithSelect(sourceName, identity.toConnectorIdentity());\n    }\n\n    public static void denyCreateViewWithSelect(String sourceName, ConnectorIdentity identity)\n    {\n        denyCreateViewWithSelect(sourceName, identity, null);\n    }\n\n    public static void denyCreateViewWithSelect(String sourceName, ConnectorIdentity identity, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"View owner '%s' cannot create view that selects from %s%s\", identity.getUser(), sourceName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyRenameView(String viewName, String newViewName)\n    {\n        denyRenameView(viewName, newViewName, null);\n    }\n\n    public static void denyRenameView(String viewName, String newViewName, String extraInfo)\n    {\n        throw new AccessDeniedException(format(\"Cannot rename view from %s to %s%s\", viewName, newViewName, formatExtraInfo(extraInfo)));\n    }\n\n    public static void denyDropView(String viewName)\n    {\n        denyDropView(viewName, null);\n    }\n\n    public static void denyDropView(String viewName, String extraInfo)","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-spi/src/main/java/com/facebook/presto/spi/security/AccessDeniedException.java#L264-L300","documentation":"Thrown when the owner of a view being created does not have permission to SELECT from the source table it references. Presto checks that the view's designated owner can read every source; denyCreateViewWithSelect fires during checkCanCreateViewWithSelect. This prevents users from creating views over data they themselves cannot read (privilege escalation).","triggerScenarios":"CREATE VIEW by a user whose owner identity cannot SELECT from the referenced source table; AccessControlManager.checkCanCreateViewWithSelect checks each source against identity.getUser().","commonSituations":"Run-as semantics: definer-based views where the owner lost SELECT on the base table; migrating views between catalogs; role-based security where the creator has SELECT via their session role but the owner identity does not.","solutions":["Grant the view owner SELECT on the source table, then re-run CREATE VIEW","Change the view owner to a principal that already has SELECT on the source","Rewrite the view to reference only tables the owner can read"],"exampleFix":"// before\nCREATE VIEW v AS SELECT * FROM secure.t; -- owner lacks SELECT on secure.t\n// after (as admin)\nGRANT SELECT ON secure.t TO USER viewowner;\nCREATE VIEW v AS SELECT * FROM secure.t;","handlingStrategy":"validation","validationCode":"// before CREATE VIEW, verify the designated owner can SELECT each source table\nfor (String source : extractTableNames(query)) {\n    if (!catalogAdmin.userHasPrivilege(viewOwner, source, \"SELECT\")) {\n        throw new IllegalStateException(\"View owner \" + viewOwner + \" lacks SELECT on \" + source);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    execute(createViewSql);\n} catch (AccessDeniedException e) {\n    if (e.getMessage().contains(\"View owner\")) {\n        log.error(\"Grant SELECT on all source tables to the view owner: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Set view owners that hold SELECT on every referenced table","Re-check owner privileges after access changes to base tables","Avoid definer-based views over tables the definer cannot read"],"tags":["security","authorization","views","privilege-escalation"],"backgroundTag":"access-denied","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}