postgres.git / summary / log / commit / refs

commit    16a104073d012ac2c70e9d233dc5e76f71455035
Author:   Peter Eisentraut <peter@eisentraut.org>
Date:     Fri Sep 25 05:51:20 2026 +0000

    Declare variable-length catalog columns as [] rather than [1]
    
    Variable-length catalog columns have been declared like
    
        text attoptions[1];
    
    but that "1" has always been a fiction.  Before the use of #ifdef
    CATALOG_VARLEN, these declarations were visible to the C compiler, and
    this was also before flexible array members were universally
    available, so this was just a convenient workaround to make this
    compile.  But these reasons are long gone, and the "1" is now just a
    confusing relic.  Change this to
    
        text attoptions[];
    
    which more intuitively reflects the actual nature of these
    fields (while still being syntactically valid but semantically invalid
    C code).
    
    Catalog.pm could already parse both spellings, but no existing code
    used bare [].  To enforce future consistency, it is changed to no
    longer permit digits between the brackets.  But to help developers
    transition, it still recognizes the old style and gives an explicit
    error message.  (Otherwise it would produce some garbage output and
    give confusing errors later.)
    
    Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
    Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
    Reviewed-by: Chao Li <li.evan.chao@gmail.com>
    Discussion: https://www.postgresql.org/message-id/flat/963b2109-833c-4e93-bdb1-546741d893f4%40eisentraut.org


src/backend/catalog/Catalog.pm | 16 ++++++++++++---- src/include/catalog/pg_attribute.h | 6 +++--- src/include/catalog/pg_class.h | 4 ++-- src/include/catalog/pg_constraint.h | 14 +++++++------- src/include/catalog/pg_database.h | 2 +- src/include/catalog/pg_db_role_setting.h | 2 +- src/include/catalog/pg_default_acl.h | 4 ++-- src/include/catalog/pg_event_trigger.h | 2 +- src/include/catalog/pg_extension.h | 4 ++-- src/include/catalog/pg_foreign_data_wrapper.h | 4 ++-- src/include/catalog/pg_foreign_server.h | 4 ++-- src/include/catalog/pg_foreign_table.h | 2 +- src/include/catalog/pg_init_privs.h | 2 +- src/include/catalog/pg_language.h | 2 +- src/include/catalog/pg_largeobject_metadata.h | 2 +- src/include/catalog/pg_namespace.h | 2 +- src/include/catalog/pg_parameter_acl.h | 2 +- src/include/catalog/pg_policy.h | 2 +- src/include/catalog/pg_proc.h | 12 ++++++------ src/include/catalog/pg_statistic.h | 10 +++++----- src/include/catalog/pg_statistic_ext.h | 2 +- src/include/catalog/pg_statistic_ext_data.h | 2 +- src/include/catalog/pg_subscription.h | 2 +- src/include/catalog/pg_tablespace.h | 4 ++-- src/include/catalog/pg_type.h | 2 +- src/include/catalog/pg_user_mapping.h | 2 +- 26 files changed, 60 insertions(+), 52 deletions(-) diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm index 219af5884d9..fb78926246f 100644 --- a/src/backend/catalog/Catalog.pm +++ b/src/backend/catalog/Catalog.pm @@ -226,11 +226,19 @@ sub ParseHeader $atttype = $RENAME_ATTTYPE{$atttype}; } - # If the C name ends with '[]' or '[digits]', we have - # an array type, so we discard that from the name and - # prepend '_' to the type. - if ($attname =~ /(\w+)\[\d*\]/) + # If the C name ends with '[]', we have an array type, + # so we discard that from the name and prepend '_' to + # the type. + # + # Older versions used '[1]' for this. Catch those + # explicitly rather than produce garbage later. + if ($attname =~ /(\w+)\[(\d*)\]/) { + if ($2 ne '') + { + die + "catalog array column \"$atttype $attname\" must be declared with []"; + } $attname = $1; $atttype = '_' . $atttype; } diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index f33a57573f2..00811a8f42c 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -171,13 +171,13 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, int16 attstattarget BKI_DEFAULT(_null_) BKI_FORCE_NULL; /* Column-level access permissions */ - aclitem attacl[1] BKI_DEFAULT(_null_); + aclitem attacl[] BKI_DEFAULT(_null_); /* Column-level options */ - text attoptions[1] BKI_DEFAULT(_null_); + text attoptions[] BKI_DEFAULT(_null_); /* Column-level FDW options */ - text attfdwoptions[1] BKI_DEFAULT(_null_); + text attfdwoptions[] BKI_DEFAULT(_null_); /* * Missing value for added columns. This is a one element array which lets diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index ae6e36aeff6..005b62b38c9 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -136,10 +136,10 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ /* access permissions */ - aclitem relacl[1] BKI_DEFAULT(_null_); + aclitem relacl[] BKI_DEFAULT(_null_); /* access-method-specific options */ - text reloptions[1] BKI_DEFAULT(_null_); + text reloptions[] BKI_DEFAULT(_null_); /* partition bound node tree */ pg_node_tree relpartbound BKI_DEFAULT(_null_); diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 1b7fedf1750..e8d27546ed9 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -122,45 +122,45 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) * Columns of conrelid that the constraint applies to, if known (this is * NULL for trigger constraints) */ - int16 conkey[1]; + int16 conkey[]; /* * If a foreign key, the referenced columns of confrelid */ - int16 confkey[1]; + int16 confkey[]; /* * If a foreign key, the OIDs of the PK = FK equality/overlap operators * for each column of the constraint */ - Oid conpfeqop[1] BKI_LOOKUP(pg_operator); + Oid conpfeqop[] BKI_LOOKUP(pg_operator); /* * If a foreign key, the OIDs of the PK = PK equality/overlap operators * for each column of the constraint (i.e., equality for the referenced * columns) */ - Oid conppeqop[1] BKI_LOOKUP(pg_operator); + Oid conppeqop[] BKI_LOOKUP(pg_operator); /* * If a foreign key, the OIDs of the FK = FK equality/overlap operators * for each column of the constraint (i.e., equality for the referencing * columns) */ - Oid conffeqop[1] BKI_LOOKUP(pg_operator); + Oid conffeqop[] BKI_LOOKUP(pg_operator); /* * If a foreign key with an ON DELETE SET NULL/DEFAULT action, the subset * of conkey to updated. If null, all columns are updated. */ - int16 confdelsetcols[1]; + int16 confdelsetcols[]; /* * If an exclusion constraint, the OIDs of the exclusion operators for * each column of the constraint. Also set for unique constraints/primary * keys using WITHOUT OVERLAPS. */ - Oid conexclop[1] BKI_LOOKUP(pg_operator); + Oid conexclop[] BKI_LOOKUP(pg_operator); /* * If a check constraint, nodeToString representation of expression diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index 8a495e96eed..e32886d1198 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -86,7 +86,7 @@ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID text datcollversion BKI_DEFAULT(_null_); /* access permissions */ - aclitem datacl[1]; + aclitem datacl[]; #endif } FormData_pg_database; diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h index 55da8288a07..3af80bc5890 100644 --- a/src/include/catalog/pg_db_role_setting.h +++ b/src/include/catalog/pg_db_role_setting.h @@ -42,7 +42,7 @@ CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION Oid setrole BKI_LOOKUP_OPT(pg_authid); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text setconfig[1]; /* GUC settings to apply at login */ + text setconfig[]; /* GUC settings to apply at login */ #endif } FormData_pg_db_role_setting; diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h index dc1722f7a68..c6a88a1f76b 100644 --- a/src/include/catalog/pg_default_acl.h +++ b/src/include/catalog/pg_default_acl.h @@ -39,8 +39,8 @@ CATALOG(pg_default_acl,826,DefaultAclRelationId) char defaclobjtype; /* see DEFACLOBJ_xxx constants below */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem defaclacl[1] BKI_FORCE_NOT_NULL; /* permissions to add at - * CREATE time */ + aclitem defaclacl[] BKI_FORCE_NOT_NULL; /* permissions to add at + * CREATE time */ #endif } FormData_pg_default_acl; diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h index eaacaaf2e2c..b59e5221123 100644 --- a/src/include/catalog/pg_event_trigger.h +++ b/src/include/catalog/pg_event_trigger.h @@ -40,7 +40,7 @@ CATALOG(pg_event_trigger,3466,EventTriggerRelationId) * session_replication_role */ #ifdef CATALOG_VARLEN - text evttags[1]; /* command TAGs this event trigger targets */ + text evttags[]; /* command TAGs this event trigger targets */ #endif } FormData_pg_event_trigger; diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h index 19ec291ad7e..c8711418435 100644 --- a/src/include/catalog/pg_extension.h +++ b/src/include/catalog/pg_extension.h @@ -40,9 +40,9 @@ CATALOG(pg_extension,3079,ExtensionRelationId) #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* extversion may never be null, but the others can be. */ text extversion BKI_FORCE_NOT_NULL; /* extension version name */ - Oid extconfig[1] BKI_LOOKUP(pg_class); /* dumpable configuration + Oid extconfig[] BKI_LOOKUP(pg_class); /* dumpable configuration * tables */ - text extcondition[1]; /* WHERE clauses for config tables */ + text extcondition[]; /* WHERE clauses for config tables */ #endif } FormData_pg_extension; diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h index 3d8389de65e..2be35a4a03b 100644 --- a/src/include/catalog/pg_foreign_data_wrapper.h +++ b/src/include/catalog/pg_foreign_data_wrapper.h @@ -43,8 +43,8 @@ CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId) * none */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem fdwacl[1]; /* access permissions */ - text fdwoptions[1]; /* FDW options */ + aclitem fdwacl[]; /* access permissions */ + text fdwoptions[]; /* FDW options */ #endif } FormData_pg_foreign_data_wrapper; diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h index cac0b9faafe..c381f538e8e 100644 --- a/src/include/catalog/pg_foreign_server.h +++ b/src/include/catalog/pg_foreign_server.h @@ -37,8 +37,8 @@ CATALOG(pg_foreign_server,1417,ForeignServerRelationId) #ifdef CATALOG_VARLEN /* variable-length fields start here */ text srvtype; text srvversion; - aclitem srvacl[1]; /* access permissions */ - text srvoptions[1]; /* FDW-specific options */ + aclitem srvacl[]; /* access permissions */ + text srvoptions[]; /* FDW-specific options */ #endif } FormData_pg_foreign_server; diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h index 601115c183d..e7bfc7cbffd 100644 --- a/src/include/catalog/pg_foreign_table.h +++ b/src/include/catalog/pg_foreign_table.h @@ -33,7 +33,7 @@ CATALOG(pg_foreign_table,3118,ForeignTableRelationId) Oid ftserver BKI_LOOKUP(pg_foreign_server); /* OID of foreign server */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text ftoptions[1]; /* FDW-specific options */ + text ftoptions[]; /* FDW-specific options */ #endif } FormData_pg_foreign_table; diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h index 44c7e50d470..36c03508a9e 100644 --- a/src/include/catalog/pg_init_privs.h +++ b/src/include/catalog/pg_init_privs.h @@ -54,7 +54,7 @@ CATALOG(pg_init_privs,3394,InitPrivsRelationId) char privtype; /* from initdb or extension? */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem initprivs[1] BKI_FORCE_NOT_NULL; /* initial privs on object */ + aclitem initprivs[] BKI_FORCE_NOT_NULL; /* initial privs on object */ #endif } FormData_pg_init_privs; diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h index d64e4525547..736adbdacf0 100644 --- a/src/include/catalog/pg_language.h +++ b/src/include/catalog/pg_language.h @@ -55,7 +55,7 @@ CATALOG(pg_language,2612,LanguageRelationId) #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* Access privileges */ - aclitem lanacl[1] BKI_DEFAULT(_null_); + aclitem lanacl[] BKI_DEFAULT(_null_); #endif } FormData_pg_language; diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h index 86f369255d4..521f8ac401f 100644 --- a/src/include/catalog/pg_largeobject_metadata.h +++ b/src/include/catalog/pg_largeobject_metadata.h @@ -37,7 +37,7 @@ CATALOG(pg_largeobject_metadata,2995,LargeObjectMetadataRelationId) * owner */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem lomacl[1]; /* access permissions */ + aclitem lomacl[]; /* access permissions */ #endif } FormData_pg_largeobject_metadata; diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index 474f4c574e0..358fc67c047 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -42,7 +42,7 @@ CATALOG(pg_namespace,2615,NamespaceRelationId) Oid nspowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem nspacl[1]; + aclitem nspacl[]; #endif } FormData_pg_namespace; diff --git a/src/include/catalog/pg_parameter_acl.h b/src/include/catalog/pg_parameter_acl.h index 902e2666069..3eeb1cc08d6 100644 --- a/src/include/catalog/pg_parameter_acl.h +++ b/src/include/catalog/pg_parameter_acl.h @@ -38,7 +38,7 @@ CATALOG(pg_parameter_acl,6243,ParameterAclRelationId) BKI_SHARED_RELATION BKI_RO text parname BKI_FORCE_NOT_NULL; /* access permissions */ - aclitem paracl[1] BKI_DEFAULT(_null_); + aclitem paracl[] BKI_DEFAULT(_null_); #endif } FormData_pg_parameter_acl; diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h index 5bcaf0cd896..f2df1ddc080 100644 --- a/src/include/catalog/pg_policy.h +++ b/src/include/catalog/pg_policy.h @@ -39,7 +39,7 @@ CATALOG(pg_policy,3256,PolicyRelationId) #ifdef CATALOG_VARLEN /* Roles to which the policy is applied; zero means PUBLIC */ - Oid polroles[1] BKI_LOOKUP_OPT(pg_authid) BKI_FORCE_NOT_NULL; + Oid polroles[] BKI_LOOKUP_OPT(pg_authid) BKI_FORCE_NOT_NULL; pg_node_tree polqual; /* Policy quals. */ pg_node_tree polwithcheck; /* WITH CHECK quals. */ #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 2f9e0b695e2..48010e93313 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -99,19 +99,19 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce #ifdef CATALOG_VARLEN /* all param types (NULL if IN only) */ - Oid proallargtypes[1] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); + Oid proallargtypes[] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); /* parameter modes (NULL if IN only) */ - char proargmodes[1] BKI_DEFAULT(_null_); + char proargmodes[] BKI_DEFAULT(_null_); /* parameter names (NULL if no names) */ - text proargnames[1] BKI_DEFAULT(_null_); + text proargnames[] BKI_DEFAULT(_null_); /* list of expression trees for argument defaults (NULL if none) */ pg_node_tree proargdefaults BKI_DEFAULT(_null_); /* types for which to apply transforms */ - Oid protrftypes[1] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); + Oid protrftypes[] BKI_DEFAULT(_null_) BKI_LOOKUP(pg_type); /* procedure source text */ text prosrc BKI_FORCE_NOT_NULL; @@ -123,10 +123,10 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce pg_node_tree prosqlbody BKI_DEFAULT(_null_); /* procedure-local GUC settings */ - text proconfig[1] BKI_DEFAULT(_null_); + text proconfig[] BKI_DEFAULT(_null_); /* access permissions */ - aclitem proacl[1] BKI_DEFAULT(_null_); + aclitem proacl[] BKI_DEFAULT(_null_); #endif } FormData_pg_proc; diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h index 032bf177b95..6404b2ba46a 100644 --- a/src/include/catalog/pg_statistic.h +++ b/src/include/catalog/pg_statistic.h @@ -106,11 +106,11 @@ CATALOG(pg_statistic,2619,StatisticRelationId) Oid stacoll5 BKI_LOOKUP_OPT(pg_collation); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - float4 stanumbers1[1]; - float4 stanumbers2[1]; - float4 stanumbers3[1]; - float4 stanumbers4[1]; - float4 stanumbers5[1]; + float4 stanumbers1[]; + float4 stanumbers2[]; + float4 stanumbers3[]; + float4 stanumbers4[]; + float4 stanumbers5[]; /* * Values in these arrays are values of the column's data type, or of some diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h index e4a0cb4d41c..bf8b495e8f8 100644 --- a/src/include/catalog/pg_statistic_ext.h +++ b/src/include/catalog/pg_statistic_ext.h @@ -54,7 +54,7 @@ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId) #ifdef CATALOG_VARLEN int16 stxstattarget BKI_DEFAULT(_null_) BKI_FORCE_NULL; /* statistics target */ - char stxkind[1] BKI_FORCE_NOT_NULL; /* statistics kinds requested + char stxkind[] BKI_FORCE_NOT_NULL; /* statistics kinds requested * to build */ pg_node_tree stxexprs; /* A list of expression trees for stats * attributes that are not simple column diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h index dbc4acc7d1a..4e7034b5e6b 100644 --- a/src/include/catalog/pg_statistic_ext_data.h +++ b/src/include/catalog/pg_statistic_ext_data.h @@ -41,7 +41,7 @@ CATALOG(pg_statistic_ext_data,3429,StatisticExtDataRelationId) pg_ndistinct stxdndistinct; /* ndistinct coefficients (serialized) */ pg_dependencies stxddependencies; /* dependencies (serialized) */ pg_mcv_list stxdmcv; /* MCV (serialized) */ - pg_statistic stxdexpr[1]; /* stats for expressions */ + pg_statistic stxdexpr[]; /* stats for expressions */ #endif diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h index d2781a0b837..b860f02d166 100644 --- a/src/include/catalog/pg_subscription.h +++ b/src/include/catalog/pg_subscription.h @@ -117,7 +117,7 @@ CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROW text subwalrcvtimeout BKI_FORCE_NOT_NULL; /* List of publications subscribed to */ - text subpublications[1] BKI_FORCE_NOT_NULL; + text subpublications[] BKI_FORCE_NOT_NULL; /* Only publish data originating from the specified origin */ text suborigin BKI_DEFAULT(LOGICALREP_ORIGIN_ANY); diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index 3bd4a74f003..5b838e4988f 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -37,8 +37,8 @@ CATALOG(pg_tablespace,1213,TableSpaceRelationId) BKI_SHARED_RELATION Oid spcowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem spcacl[1]; /* access permissions */ - text spcoptions[1]; /* per-tablespace options */ + aclitem spcacl[]; /* access permissions */ + text spcoptions[]; /* per-tablespace options */ #endif } FormData_pg_tablespace; diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 74183ec5a2e..3f00c9b1cdb 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -251,7 +251,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati /* * Access permissions */ - aclitem typacl[1] BKI_DEFAULT(_null_); + aclitem typacl[] BKI_DEFAULT(_null_); #endif } FormData_pg_type; diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h index 921a9ec009d..8b9b331c938 100644 --- a/src/include/catalog/pg_user_mapping.h +++ b/src/include/catalog/pg_user_mapping.h @@ -38,7 +38,7 @@ CATALOG(pg_user_mapping,1418,UserMappingRelationId) * mapping */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text umoptions[1]; /* user mapping options */ + text umoptions[]; /* user mapping options */ #endif } FormData_pg_user_mapping;