| 814 | use crate::pure::PgSourcePurificationError; |
| 815 | |
| 816 | async fn check_schema_privileges(client: &Client, table_oids: &[Oid]) -> Result<(), PlanError> { |
| 817 | let invalid_schema_privileges_rows = query( |
| 818 | client, |
| 819 | sql!( |
| 820 | " |
| 821 | WITH distinct_namespace AS ( |
| 822 | SELECT |
| 823 | DISTINCT n.oid, n.nspname AS schema_name |
| 824 | FROM unnest($1::OID[]) AS oids (oid) |
| 825 | JOIN pg_class AS c ON c.oid = oids.oid |
| 826 | JOIN pg_namespace AS n ON c.relnamespace = n.oid |
| 827 | ) |
| 828 | SELECT d.schema_name |
| 829 | FROM distinct_namespace AS d |
| 830 | WHERE |
| 831 | NOT has_schema_privilege(CURRENT_USER::TEXT, d.oid, 'usage')" |
| 832 | ), |
| 833 | &[&table_oids], |
| 834 | ) |
| 835 | .await?; |
| 836 | |
| 837 | let mut invalid_schema_privileges = invalid_schema_privileges_rows |
| 838 | .into_iter() |
| 839 | .map(|row| row.get("schema_name")) |
| 840 | .collect::<Vec<String>>(); |
| 841 | |
| 842 | if invalid_schema_privileges.is_empty() { |
| 843 | Ok(()) |
| 844 | } else { |
| 845 | invalid_schema_privileges.sort(); |
| 846 | Err(PgSourcePurificationError::UserLacksUsageOnSchemas { |
| 847 | schemas: invalid_schema_privileges, |
| 848 | })? |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | /// Ensure that the user specified in `config` has: |
| 853 | /// |