8000 Altering default privileges on schemas · postgrespro/postgres_cluster@ab89e46 · GitHub
[go: up one dir, main page]

Skip to content

Commit ab89e46

Browse files
committed
Altering default privileges on schemas
Extend ALTER DEFAULT PRIVILEGES command to schemas. Author: Matheus Oliveira Reviewed-by: Petr Jelínek, Ashutosh Sharma https://commitfest.postgresql.org/13/887/
1 parent 8516364 commit ab89e46

File tree

13 files changed

+176
-12
lines changed
  • include
  • test/regress
  • 13 files changed

    +176
    -12
    lines changed

    doc/src/sgml/ref/alter_default_privileges.sgml

    Lines changed: 15 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -46,6 +46,10 @@ GRANT { USAGE | ALL [ PRIVILEGES ] }
    4646
    ON TYPES
    4747
    TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
    4848

    49+
    GRANT { USAGE | CREATE | ALL [ PRIVILEGES ] }
    50+
    ON SCHEMAS
    51+
    TO { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
    52+
    4953
    REVOKE [ GRANT OPTION FOR ]
    5054
    { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    5155
    [, ...] | ALL [ PRIVILEGES ] }
    @@ -71,6 +75,12 @@ REVOKE [ GRANT OPTION FOR ]
    7175
    ON TYPES
    7276
    FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
    7377
    [ CASCADE | RESTRICT ]
    78+
    79+
    REVOKE [ GRANT OPTION FOR ]
    80+
    { USA 57AE GE | CREATE | ALL [ PRIVILEGES ] }
    81+
    ON SCHEMAS
    82+
    FROM { [ GROUP ] <replaceable class="PARAMETER">role_name</replaceable> | PUBLIC } [, ...]
    83+
    [ CASCADE | RESTRICT ]
    7484
    </synopsis>
    7585
    </refsynopsisdiv>
    7686

    @@ -81,8 +91,9 @@ REVOKE [ GRANT OPTION FOR ]
    8191
    <command>ALTER DEFAULT PRIVILEGES</> allows you to set the privileges
    8292
    that will be applied to objects created in the future. (It does not
    8393
    affect privileges assigned to already-existing objects.) Currently,
    84-
    only the privileges for tables (including views and foreign tables),
    85-
    sequences, functions, and types (including domains) can be altered.
    94+
    only the privileges for schemas, tables (including views and foreign
    95+
    tables), sequences, functions, and types (including domains) can be
    96+
    altered.
    8697
    </para>
    8798

    8899
    <para>
    @@ -125,6 +136,8 @@ REVOKE [ GRANT OPTION FOR ]
    125136
    are altered for objects later created in that schema.
    126137
    If <literal>IN SCHEMA</> is omitted, the global default privileges
    127138
    are altered.
    139+
    <literal>IN SCHEMA</> is not allowed when using <literal>ON SCHEMAS</>
    140+
    as schemas can't be nested.
    128141
    </para>
    129142
    </listitem>
    130143
    </varlistentry>

    src/backend/catalog/aclchk.c

    Lines changed: 21 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -959,6 +959,10 @@ ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *s
    959959
    all_privileges = ACL_ALL_RIGHTS_TYPE;
    960960
    errormsg = gettext_noop("invalid privilege type %s for type");
    961961
    break;
    962+
    case ACL_OBJECT_NAMESPACE:
    963+
    all_privileges = ACL_ALL_RIGHTS_NAMESPACE;
    964+
    errormsg = gettext_noop("invalid privilege type %s for schema");
    965+
    break;
    962966
    default:
    963967
    elog(ERROR, "unrecognized GrantStmt.objtype: %d",
    964968
    (int) action->objtype);
    @@ -1146,6 +1150,16 @@ SetDefaultACL(InternalDefaultACL *iacls)
    11461150
    this_privileges = ACL_ALL_RIGHTS_TYPE;
    11471151
    break;
    11481152

    1153+
    case ACL_OBJECT_NAMESPACE:
    1154+
    if (OidIsValid(iacls->nspid))
    1155+
    ereport(ERROR,
    1156+
    (errcode(ERRCODE_INVALID_GRANT_OPERATION),
    1157+
    errmsg("cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS")));
    1158+
    objtype = DEFACLOBJ_NAMESPACE;
    1159+
    if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
    1160+
    this_privileges = ACL_ALL_RIGHTS_NAMESPACE;
    1161+
    break;
    1162+
    11491163
    default:
    11501164
    elog(ERROR, "unrecognized objtype: %d",
    11511165
    (int) iacls->objtype);
    @@ -1369,6 +1383,9 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
    13691383
    case DEFACLOBJ_TYPE:
    13701384
    iacls.objtype = ACL_OBJECT_TYPE;
    13711385
    break;
    1386+
    case DEFACLOBJ_NAMESPACE:
    1387+
    iacls.objtype = ACL_OBJECT_NAMESPACE;
    1388+
    break;
    13721389
    default:
    13731390
    /* Shouldn't get here */
    13741391
    elog(ERROR, "unexpected default ACL type: %d",
    @@ -5259,6 +5276,10 @@ get_user_default_acl(GrantObjectType objtype, Oid ownerId, Oid nsp_oid)
    52595276
    defaclobjtype = DEFACLOBJ_TYPE;
    52605277
    break;
    52615278

    5279+
    case ACL_OBJECT_NAMESPACE:
    5280+
    defaclobjtype = DEFACLOBJ_NAMESPACE;
    5281+
    break;
    5282+
    52625283
    default:
    52635284
    return NULL;
    52645285
    }

    src/backend/catalog/objectaddress.c

    Lines changed: 13 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -1843,11 +1843,14 @@ get_object_address_defacl(List *object, bool missing_ok)
    18431843
    case DEFACLOBJ_TYPE:
    18441844
    objtype_str = "types";
    18451845
    break;
    1846+
    case DEFACLOBJ_NAMESPACE:
    1847+
    objtype_str = "schemas";
    1848+
    break;
    18461849
    default:
    18471850
    ereport(ERROR,
    18481851
    (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    18491852
    errmsg("unrecognized default ACL object type %c", objtype),
    1850-
    errhint("Valid object types are \"r\", \"S\", \"f\", and \"T\".")));
    1853+
    errhint("Valid object types are \"r\", \"S\", \"f\", \"T\" and \"s\".")));
    18511854
    }
    18521855

    18531856
    /*
    @@ -3255,6 +3258,11 @@ getObjectDescription(const ObjectAddress *object)
    32553258
    _("default privileges on new types belonging to role %s"),
    32563259
    GetUserNameFromId(defacl->defaclrole, false));
    32573260
    break;
    3261+
    case DEFACLOBJ_NAMESPACE:
    3262+
    appendStringInfo(&buffer,
    3263+
    _("default privileges on new schemas belonging to role %s"),
    3264+
    GetUserNameFromId(defacl->defaclrole, false));
    3265+
    break;
    32583266
    default:
    32593267
    /* shouldn't get here */
    32603268
    appendStringInfo(&buffer,
    @@ -4762,6 +4770,10 @@ getObjectIdentityParts(const ObjectAddress *object,
    47624770
    appendStringInfoString(&buffer,
    47634771
    " on types");
    47644772
    break;
    4773+
    case DEFACLOBJ_NAMESPACE:
    4774+
    appendStringInfoString(&buffer,
    4775+
    " on schemas");
    4776+
    break;
    47654777
    }
    47664778

    47674779
    if (objname)

    src/backend/catalog/pg_namespace.c

    Lines changed: 16 additions & 5 deletions
    Original file line numberDiff line numberDiff line change
    @@ -31,10 +31,11 @@
    3131
    * Create a namespace (schema) with the given name and owner OID.
    3232
    *
    3333
    * If isTemp is true, this schema is a per-backend schema for holding
    34-
    * temporary tables. Currently, the only effect of that is to prevent it
    35-
    * from being linked as a member of any active extension. (If someone
    36-
    * does CREATE TEMP TABLE in an extension script, we don't want the temp
    37-
    * schema to become part of the extension.)
    34+
    * temporary tables. Currently, it is used to prevent it from being
    35+
    * linked as a member of any active extension. (If someone does CREATE
    36+
    * TEMP TABLE in an extension script, we don't want the temp schema to
    37+
    * become part of the extension). And to avoid checking for default ACL
    38+
    * for temp namespace (as it is not necessary).
    3839
    * ---------------
    3940
    */
    4041
    Oid
    @@ -49,6 +50,7 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
    4950
    TupleDesc tupDesc;
    5051
    ObjectAddress myself;
    5152
    int i;
    53+
    Acl *nspacl;
    5254

    5355
    /* sanity checks */
    5456
    if (!nspName)
    @@ -60,6 +62,12 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
    6062
    (errcode(ERRCODE_DUPLICATE_SCHEMA),
    6163
    errmsg("schema \"%s\" already exists", nspName)));
    6264

    65+
    if (!isTemp)
    66+
    nspacl = get_user_default_acl(ACL_OBJECT_NAMESPACE, ownerId,
    67+
    InvalidOid);
    68+
    else
    69+
    nspacl = NULL;
    70+
    6371
    /* initialize nulls and values */
    6472
    for (i = 0; i < Natts_pg_namespace; i++)
    6573
    {
    @@ -69,7 +77,10 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
    6977
    namestrcpy(&nname, nspName);
    7078
    values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
    7179
    values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
    72-
    nulls[Anum_pg_namespace_nspacl - 1] = true;
    80+
    if (nspacl != NULL)
    81+
    values[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(nspacl);
    82+
    else
    83+
    nulls[Anum_pg_namespace_nspacl - 1] = true;
    7384

    7485
    nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
    7586
    tupDesc = nspdesc->rd_att;

    src/backend/parser/gram.y

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -668,7 +668,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
    668668
    RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
    669669
    ROW ROWS RULE
    670670

    671-
    SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
    671+
    SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
    672672
    SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
    673673
    SIMILAR SIMPLE SKIP SLOT SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P
    674674
    START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P
    @@ -7035,6 +7035,7 @@ defacl_privilege_target:
    70357035
    | FUNCTIONS { $$ = ACL_OBJECT_FUNCTION; }
    70367036
    | SEQUENCES { $$ = ACL_OBJECT_SEQUENCE; }
    70377037
    | TYPES_P { $$ = ACL_OBJECT_TYPE; }
    7038+
    | SCHEMAS { $$ = ACL_OBJECT_NAMESPACE; }
    70387039
    ;
    70397040

    70407041

    @@ -14713,6 +14714,7 @@ unreserved_keyword:
    1471314714
    | RULE
    1471414715
    | SAVEPOINT
    1471514716
    | SCHEMA
    14717+
    | SCHEMAS
    1471614718
    | SCROLL
    1471714719
    | SEARCH
    1471814720
    | SECOND_P

    src/bin/pg_dump/dumputils.c

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -520,7 +520,9 @@ do { \
    520520
    CONVERT_PRIV('X', "EXECUTE");
    521521
    else if (strcmp(type, "LANGUAGE") == 0)
    522522
    CONVERT_PRIV('U', "USAGE");
    523-
    else if (strcmp(type, "SCHEMA") == 0)
    523+
    else if (strcmp(type, "SCHEMA") == 0 ||
    524+
    strcmp(type, "SCHEMAS") == 0
    525+
    )
    524526
    {
    525527
    CONVERT_PRIV('C', "CREATE");
    526528
    CONVERT_PRIV('U', "USAGE");

    src/bin/pg_dump/pg_dump.c

    Lines changed: 3 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -14295,6 +14295,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
    1429514295
    case DEFACLOBJ_TYPE:
    1429614296
    type = "TYPES";
    1429714297
    break;
    14298+
    case DEFACLOBJ_NAMESPACE:
    14299+
    type = "SCHEMAS";
    14300+
    break;
    1429814301
    default:
    1429914302
    /* shouldn't get here */
    1430014303
    exit_horribly(NULL,

    src/bin/psql/describe.c

    Lines changed: 3 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -1028,7 +1028,7 @@ listDefaultACLs(const char *pattern)
    10281028
    printfPQExpBuffer(&buf,
    10291029
    "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
    10301030
    " n.nspname AS \"%s\",\n"
    1031-
    " CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
    1031+
    " CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
    10321032
    " ",
    10331033
    gettext_noop("Owner"),
    10341034
    gettext_noop("Schema"),
    @@ -1040,6 +1040,8 @@ listDefaultACLs(const char *pattern)
    10401040
    gettext_noop("function"),
    10411041
    DEFACLOBJ_TYPE,
    10421042
    gettext_noop("type"),
    1043+
    DEFACLOBJ_NAMESPACE,
    1044+
    gettext_noop("schema"),
    10431045
    gettext_noop("Type"));
    10441046

    10451047
    printACLColumn(&buf, "d.defaclacl");

    src/bin/psql/tab-complete.c

    Lines changed: 1 addition & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -2796,7 +2796,7 @@ psql_completion(const char *text, int start, int end)
    27962796
    * to the kinds of objects supported.
    27972797
    */
    27982798
    if (HeadMatches3("ALTER","DEFAULT","PRIVILEGES"))
    2799-
    COMPLETE_WITH_LIST4("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES");
    2799+
    COMPLETE_WITH_LIST5("TABLES", "SEQUENCES", "FUNCTIONS", "TYPES", "SCHEMAS");
    28002800
    else
    28012801
    COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf,
    28022802
    " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'"

    src/include/catalog/pg_default_acl.h

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -70,5 +70,6 @@ typedef FormData_pg_default_acl *Form_pg_default_acl;
    7070
    #define DEFACLOBJ_SEQUENCE 'S' /* sequence */
    7171
    #define DEFACLOBJ_FUNCTION 'f' /* function */
    7272
    #define DEFACLOBJ_TYPE 'T' /* type */
    73+
    #define DEFACLOBJ_NAMESPACE 'n' /* namespace */
    7374

    7475
    #endif /* PG_DEFAULT_ACL_H */

    src/include/parser/kwlist.h

    Lines changed: 1 addition & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -344,6 +344,7 @@ PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD)
    344344
    PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD)
    345345
    PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD)
    346346
    PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD)
    347+
    PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD)
    347348
    PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD)
    348349
    PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD)
    349350
    PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD)

    src/test/regress/expected/privileges.out

    Lines changed: 62 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -1356,6 +1356,64 @@ SELECT has_table_privilege('regress_user1', 'testns.acltest1', 'INSERT'); -- no
    13561356
    (1 row)
    13571357

    13581358
    ALTER DEFAULT PRIVILEGES FOR ROLE regress_user1 REVOKE EXECUTE ON FUNCTIONS FROM public;
    1359+
    ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_user2; -- error
    1360+
    ERROR: cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS
    1361+
    ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_user2;
    1362+
    CREATE SCHEMA testns2;
    1363+
    SELECT has_schema_privilege('regress_user2', 'testns2', 'USAGE'); -- yes
    1364+
    has_schema_privilege
    1365+
    ----------------------
    1366+
    t
    1367+
    (1 row)
    1368+
    1369+
    SELECT has_schema_privilege('regress_user2', 'testns2', 'CREATE'); -- no
    1370+
    has_schema_privilege
    1371+
    ----------------------
    1372+
    f
    1373+
    (1 row)
    1374+
    1375+
    ALTER DEFAULT PRIVILEGES REVOKE USAGE ON SCHEMAS FROM regress_user2;
    1376+
    CREATE SCHEMA testns3;
    1377+
    SELECT has_schema_privilege('regress_user2', 'testns3', 'USAGE'); -- no
    1378+
    has_schema_privilege
    1379+
    ----------------------
    1380+
    f
    1381+
    (1 row)
    1382+
    1383+
    SELECT has_schema_privilege('regress_user2', 'testns3', 'CREATE'); -- no
    1384+
    has_schema_privilege
    1385+
    ----------------------
    1386+
    f
    1387+
    (1 row)
    1388+
    1389+
    ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_user2;
    1390+
    CREATE SCHEMA testns4;
    1391+
    SELECT has_schema_privilege('regress_user2', 'testns4', 'USAGE'); -- yes
    1392+
    has_schema_privilege
    1393+
    ----------------------
    1394+
    t
    1395+
    (1 row)
    1396+
    1397+
    SELECT has_schema_privilege('regress_user2', 'testns4', 'CREATE'); -- yes
    1398+
    has_schema_privilege
    1399+
    ----------------------
    1400+
    t
    1401+
    (1 row)
    1402+
    1403+
    ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_user2;
    1404+
    CREATE SCHEMA testns5;
    1405+
    SELECT has_schema_privilege('regress_user2', 'testns5', 'USAGE'); -- no
    1406+
    has_schema_privilege
    1407+
    ----------------------
    1408+
    f
    1409+
    (1 row)
    1410+
    1411+
    SELECT has_schema_privilege('regress_user2', 'testns5', 'CREATE'); -- no
    1412+
    has_schema_privilege
    1413+
    ----------------------
    1414+
    f
    1415+
    (1 row)
    1416+
    13591417
    SET ROLE regress_user1;
    13601418
    CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
    13611419
    SELECT has_function_privilege('regress_user2', 'testns.foo()', 'EXECUTE'); -- no
    @@ -1403,6 +1461,10 @@ SELECT count(*)
    14031461

    14041462
    DROP SCHEMA testns CASCADE;
    14051463
    NOTICE: drop cascades to table testns.acltest1
    1464+
    DROP SCHEMA testns2 CASCADE;
    1465+
    DROP SCHEMA testns3 CASCADE;
    1466+
    DROP SCHEMA testns4 CASCADE;
    1467+
    DROP SCHEMA testns5 CASCADE;
    14061468
    SELECT d.* -- check that entries went away
    14071469
    FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
    14081470
    WHERE nspname IS NULL AND defaclnamespace != 0;

    src/test/regress/sql/privileges.sql

    Lines changed: 34 additions & 0 deletions
    Original file line numberDiff line numberDiff line change
    @@ -816,6 +816,36 @@ SELECT has_table_privilege('regress_user1', 'testns.acltest1', 'INSERT'); -- no
    816816

    817817
    ALTER DEFAULT PRIVILEGES FOR ROLE regress_user1 REVOKE EXECUTE ON FUNCTIONS FROM public;
    818818

    819+
    ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_user2; -- error
    820+
    821+
    ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_user2;
    822+
    823+
    CREATE SCHEMA testns2;
    824+
    825+
    SELECT has_schema_privilege('regress_user2', 'testns2', 'USAGE'); -- yes
    826+
    SELECT has_schema_privilege('regress_user2', 'testns2', 'CREATE'); -- no
    827+
    828+
    ALTER DEFAULT PRIVILEGES REVOKE USAGE ON SCHEMAS FROM regress_user2;
    829+
    830+
    CREATE SCHEMA testns3;
    831+
    832+
    SELECT has_schema_privilege('regress_user2', 'testns3', 'USAGE'); -- no
    833+
    SELECT has_schema_privilege('regress_user2', 'testns3', 'CREATE'); -- no
    834+
    835+
    ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_user2;
    836+
    837+
    CREATE SCHEMA testns4;
    838+
    839+
    SELECT has_schema_privilege('regress_user2', 'testns4', 'USAGE'); -- yes
    840+
    SELECT has_schema_privilege('regress_user2', 'testns4', 'CREATE'); -- yes
    841+
    842+
    ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_user2;
    843+
    844+
    CREATE SCHEMA testns5;
    845+
    846+
    SELECT has_schema_privilege('regress_user2', 'testns5', 'USAGE'); -- no
    847+
    SELECT has_schema_privilege('regress_user2', 'testns5', 'CREATE'); -- no
    848+
    819849
    SET ROLE regress_user1;
    820850

    821851
    CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
    @@ -853,6 +883,10 @@ SELECT count(*)
    853883
    WHERE nspname = 'testns';
    854884

    855885
    DROP SCHEMA testns CASCADE;
    886+
    DROP SCHEMA testns2 CASCADE;
    887+
    DROP SCHEMA testns3 CASCADE;
    888+
    DROP SCHEMA testns4 CASCADE;
    889+
    DROP SCHEMA testns5 CASCADE;
    856890

    857891
    SELECT d.* -- check that entries went away
    858892
    FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid

    0 commit comments

    Comments
     (0)
    0