Expand AclMode to 64 bits

We're running out of bits for new permissions. This change doubles the
number of permissions we can accomodate from 16 to 32, so the
forthcoming new ones for vacuum/analyze don't exhaust the pool.

Nathan Bossart

Reviewed by: Bharath Rupireddy, Kyotaro Horiguchi, Stephen Frost, Robert
Haas, Mark Dilger, Tom Lane, Corey Huinker, David G. Johnston, Michael
Paquier.

Discussion: https://postgr.es/m/20220722203735.GB3996698@nathanxps13
This commit is contained in:
Andrew Dunstan 2022-11-23 14:41:30 -05:00
parent b6074846ce
commit 7b378237aa
6 changed files with 56 additions and 21 deletions

View File

@ -560,7 +560,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
WRITE_BOOL_FIELD(lateral); WRITE_BOOL_FIELD(lateral);
WRITE_BOOL_FIELD(inh); WRITE_BOOL_FIELD(inh);
WRITE_BOOL_FIELD(inFromCl); WRITE_BOOL_FIELD(inFromCl);
WRITE_UINT_FIELD(requiredPerms); WRITE_UINT64_FIELD(requiredPerms);
WRITE_OID_FIELD(checkAsUser); WRITE_OID_FIELD(checkAsUser);
WRITE_BITMAPSET_FIELD(selectedCols); WRITE_BITMAPSET_FIELD(selectedCols);
WRITE_BITMAPSET_FIELD(insertedCols); WRITE_BITMAPSET_FIELD(insertedCols);

View File

@ -28,6 +28,7 @@ static void check_for_incompatible_polymorphics(ClusterInfo *cluster);
static void check_for_tables_with_oids(ClusterInfo *cluster); static void check_for_tables_with_oids(ClusterInfo *cluster);
static void check_for_composite_data_type_usage(ClusterInfo *cluster); static void check_for_composite_data_type_usage(ClusterInfo *cluster);
static void check_for_reg_data_type_usage(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster);
static void check_for_aclitem_data_type_usage(ClusterInfo *cluster);
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster); static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
static void check_for_pg_role_prefix(ClusterInfo *cluster); static void check_for_pg_role_prefix(ClusterInfo *cluster);
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster); static void check_for_new_tablespace_dir(ClusterInfo *new_cluster);
@ -107,6 +108,13 @@ check_and_dump_old_cluster(bool live_check)
check_for_reg_data_type_usage(&old_cluster); check_for_reg_data_type_usage(&old_cluster);
check_for_isn_and_int8_passing_mismatch(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster);
/*
* PG 16 increased the size of the 'aclitem' type, which breaks the on-disk
* format for existing data.
*/
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1500)
check_for_aclitem_data_type_usage(&old_cluster);
/* /*
* PG 14 changed the function signature of encoding conversion functions. * PG 14 changed the function signature of encoding conversion functions.
* Conversions from older versions cannot be upgraded automatically * Conversions from older versions cannot be upgraded automatically
@ -1319,6 +1327,33 @@ check_for_reg_data_type_usage(ClusterInfo *cluster)
check_ok(); check_ok();
} }
/*
* check_for_aclitem_data_type_usage
*
* aclitem changed its storage format in 16, so check for it.
*/
static void
check_for_aclitem_data_type_usage(ClusterInfo *cluster)
{
char output_path[MAXPGPATH];
prep_status("Checking for incompatible aclitem data type in user tables");
snprintf(output_path, sizeof(output_path), "tables_using_aclitem.txt");
if (check_for_data_type_usage(cluster, "pg_catalog.aclitem", output_path))
{
pg_log(PG_REPORT, "fatal");
pg_fatal("Your installation contains the \"aclitem\" data type in user tables.\n"
"The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
"so this cluster cannot currently be upgraded. You can drop the\n"
"problem columns and restart the upgrade. A list of the problem\n"
"columns is in the file:\n"
" %s", output_path);
}
else
check_ok();
}
/* /*
* check_for_jsonb_9_4_usage() * check_for_jsonb_9_4_usage()

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202211211 #define CATALOG_VERSION_NO 202211221
#endif #endif

View File

@ -267,9 +267,9 @@
# OIDS 1000 - 1099 # OIDS 1000 - 1099
{ oid => '1033', array_type_oid => '1034', descr => 'access control list', { oid => '1033', array_type_oid => '1034', descr => 'access control list',
typname => 'aclitem', typlen => '12', typbyval => 'f', typcategory => 'U', typname => 'aclitem', typlen => '16', typbyval => 'f', typcategory => 'U',
typinput => 'aclitemin', typoutput => 'aclitemout', typreceive => '-', typinput => 'aclitemin', typoutput => 'aclitemout', typreceive => '-',
typsend => '-', typalign => 'i' }, typsend => '-', typalign => 'd' },
{ oid => '1042', array_type_oid => '1014', { oid => '1042', array_type_oid => '1014',
descr => 'char(length), blank-padded string, fixed storage length', descr => 'char(length), blank-padded string, fixed storage length',
typname => 'bpchar', typlen => '-1', typbyval => 'f', typcategory => 'S', typname => 'bpchar', typlen => '-1', typbyval => 'f', typcategory => 'S',

View File

@ -73,12 +73,12 @@ typedef enum SetQuantifier
/* /*
* Grantable rights are encoded so that we can OR them together in a bitmask. * Grantable rights are encoded so that we can OR them together in a bitmask.
* The present representation of AclItem limits us to 16 distinct rights, * The present representation of AclItem limits us to 32 distinct rights,
* even though AclMode is defined as uint32. See utils/acl.h. * even though AclMode is defined as uint64. See utils/acl.h.
* *
* Caution: changing these codes breaks stored ACLs, hence forces initdb. * Caution: changing these codes breaks stored ACLs, hence forces initdb.
*/ */
typedef uint32 AclMode; /* a bitmask of privilege bits */ typedef uint64 AclMode; /* a bitmask of privilege bits */
#define ACL_INSERT (1<<0) /* for relations */ #define ACL_INSERT (1<<0) /* for relations */
#define ACL_SELECT (1<<1) #define ACL_SELECT (1<<1)

View File

@ -59,33 +59,33 @@ typedef struct AclItem
} AclItem; } AclItem;
/* /*
* The upper 16 bits of the ai_privs field of an AclItem are the grant option * The upper 32 bits of the ai_privs field of an AclItem are the grant option
* bits, and the lower 16 bits are the actual privileges. We use "rights" * bits, and the lower 32 bits are the actual privileges. We use "rights"
* to mean the combined grant option and privilege bits fields. * to mean the combined grant option and privilege bits fields.
*/ */
#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFF) #define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFFFFFF)
#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF) #define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 32) & 0xFFFFFFFF)
#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs) #define ACLITEM_GET_RIGHTS(item) ((item).ai_privs)
#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16) #define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFFFFFF) << 32)
#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 16) & 0xFFFF) #define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 32) & 0xFFFFFFFF)
#define ACLITEM_SET_PRIVS(item,privs) \ #define ACLITEM_SET_PRIVS(item,privs) \
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \ ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFFFFFF)) | \
((AclMode) (privs) & 0xFFFF)) ((AclMode) (privs) & 0xFFFFFFFF))
#define ACLITEM_SET_GOPTIONS(item,goptions) \ #define ACLITEM_SET_GOPTIONS(item,goptions) \
((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16)) | \ ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFFFFFF) << 32)) | \
(((AclMode) (goptions) & 0xFFFF) << 16)) (((AclMode) (goptions) & 0xFFFFFFFF) << 32))
#define ACLITEM_SET_RIGHTS(item,rights) \ #define ACLITEM_SET_RIGHTS(item,rights) \
((item).ai_privs = (AclMode) (rights)) ((item).ai_privs = (AclMode) (rights))
#define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \ #define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \
((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \ ((item).ai_privs = ((AclMode) (privs) & 0xFFFFFFFF) | \
(((AclMode) (goptions) & 0xFFFF) << 16)) (((AclMode) (goptions) & 0xFFFFFFFF) << 32))
#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xFFFF) #define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xFFFFFFFF)
#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16) #define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFFFFFF << 32)
/* /*
* Definitions for convenient access to Acl (array of AclItem). * Definitions for convenient access to Acl (array of AclItem).