Hi, In a lot of places in the code we have many structures doing declarations of the type foo[1] to emulate variable length arrays. Attached are a set of patches aimed at replacing that with FLEXIBLE_ARRAY_MEMBER to prevent potential failures that could be caused by compiler optimizations and improve report of static code analyzers of the type Coverity (idea by Tom, patches from me): - 0001 uses FLEXIBLE_ARRAY_MEMBER in a bunch of trivial places (at least check-world does not complain) - 0002 does the same for catalog tables - 0003 changes varlena in c.h. This is done as a separate patch because this needs some other modifications as variable-length things need to be placed at the end of structures, because of: -- rolpassword that should be placed as the last field of pg_authid (and shouldn't there be CATALOG_VARLEN here??) -- inv_api.c uses bytea in an internal structure without putting it at the end of the structure. For clarity I think that we should just use a bytea pointer and do a sufficient allocation for the duration of the lobj manipulation. -- Similarly, tuptoaster.c needed to be patched for toast_save_datum
There are as well couple of things that are not changed on purpose: - in namespace.h for FuncCandidateList. I tried manipulating it but it resulted in allocation overflow in PortalHeapMemory - I don't think that the t_bits fields in htup_details.h should be updated either. Regards, -- Michael
From f3389a945811e1db19eb5debc9e41b84fed0a9f5 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@otacoo.com> Date: Mon, 16 Feb 2015 02:44:10 +0900 Subject: [PATCH 1/3] First cut with FLEXIBLE_ARRAY_MEMBER This is targetted to prevent false positive errors that static code analyzers may do by assuming that some structures have an unvarying size. --- contrib/cube/cubedata.h | 7 +++---- contrib/intarray/_int.h | 4 ++-- contrib/ltree/ltree.h | 14 +++++++------- contrib/pg_trgm/trgm.h | 2 +- src/bin/pg_dump/dumputils.h | 2 +- src/include/access/gin_private.h | 4 ++-- src/include/access/gist_private.h | 5 +++-- src/include/access/heapam_xlog.h | 2 +- src/include/access/htup_details.h | 4 ++-- src/include/access/spgist_private.h | 10 +++++----- src/include/access/xact.h | 8 ++++---- src/include/c.h | 4 ++-- src/include/commands/dbcommands.h | 4 ++-- src/include/commands/tablespace.h | 2 +- src/include/executor/hashjoin.h | 2 +- src/include/nodes/bitmapset.h | 2 +- src/include/nodes/params.h | 2 +- src/include/nodes/tidbitmap.h | 2 +- src/include/postgres.h | 9 +++++---- src/include/postmaster/syslogger.h | 2 +- src/include/replication/walsender_private.h | 2 +- src/include/storage/bufpage.h | 3 ++- src/include/storage/fsm_internals.h | 2 +- src/include/storage/standby.h | 4 ++-- src/include/tsearch/dicts/regis.h | 2 +- src/include/tsearch/dicts/spell.h | 6 +++--- src/include/tsearch/ts_type.h | 6 +++--- src/include/utils/catcache.h | 2 +- src/include/utils/datetime.h | 5 +++-- src/include/utils/geo_decls.h | 3 ++- src/include/utils/jsonb.h | 2 +- src/include/utils/relmapper.h | 2 +- src/include/utils/varbit.h | 3 ++- 33 files changed, 69 insertions(+), 64 deletions(-) diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h index 5d44e11..3535847 100644 --- a/contrib/cube/cubedata.h +++ b/contrib/cube/cubedata.h @@ -23,11 +23,10 @@ typedef struct NDBOX unsigned int header; /* - * Variable length array. The lower left coordinates for each dimension - * come first, followed by upper right coordinates unless the point flag - * is set. + * The lower left coordinates for each dimension come first, followed + * by upper right coordinates unless the point flag is set. */ - double x[1]; + double x[FLEXIBLE_ARRAY_MEMBER]; } NDBOX; #define POINT_BIT 0x80000000 diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 7f93206..d524f0f 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -73,7 +73,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 flag; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } GISTTYPE; #define ALLISTRUE 0x04 @@ -133,7 +133,7 @@ typedef struct QUERYTYPE { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 size; /* number of ITEMs */ - ITEM items[1]; /* variable length array */ + ITEM items[FLEXIBLE_ARRAY_MEMBER]; } QUERYTYPE; #define HDRSIZEQT offsetof(QUERYTYPE, items) diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h index 1b1305b..c604357 100644 --- a/contrib/ltree/ltree.h +++ b/contrib/ltree/ltree.h @@ -10,7 +10,7 @@ typedef struct { uint16 len; - char name[1]; + char name[FLEXIBLE_ARRAY_MEMBER]; } ltree_level; #define LEVEL_HDRSIZE (offsetof(ltree_level,name)) @@ -20,7 +20,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ uint16 numlevel; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } ltree; #define LTREE_HDRSIZE MAXALIGN( offsetof(ltree, data) ) @@ -34,7 +34,7 @@ typedef struct int32 val; uint16 len; uint8 flag; - char name[1]; + char name[FLEXIBLE_ARRAY_MEMBER]; } lquery_variant; #define LVAR_HDRSIZE MAXALIGN(offsetof(lquery_variant, name)) @@ -51,7 +51,7 @@ typedef struct uint16 numvar; uint16 low; uint16 high; - char variants[1]; + char variants[FLEXIBLE_ARRAY_MEMBER]; } lquery_level; #define LQL_HDRSIZE MAXALIGN( offsetof(lquery_level,variants) ) @@ -72,7 +72,7 @@ typedef struct uint16 numlevel; uint16 firstgood; uint16 flag; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } lquery; #define LQUERY_HDRSIZE MAXALIGN( offsetof(lquery, data) ) @@ -107,7 +107,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 size; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } ltxtquery; #define HDRSIZEQT MAXALIGN(VARHDRSZ + sizeof(int32)) @@ -208,7 +208,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ uint32 flag; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } ltree_gist; #define LTG_ONENODE 0x01 diff --git a/contrib/pg_trgm/trgm.h b/contrib/pg_trgm/trgm.h index ed649b8..f030558 100644 --- a/contrib/pg_trgm/trgm.h +++ b/contrib/pg_trgm/trgm.h @@ -63,7 +63,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ uint8 flag; - char data[1]; + char data[FLEXIBLE_ARRAY_MEMBER]; } TRGM; #define TRGMHDRSIZE (VARHDRSZ + sizeof(uint8)) diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index a39c1b6..94476a9 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -38,7 +38,7 @@ typedef struct SimpleOidList typedef struct SimpleStringListCell { struct SimpleStringListCell *next; - char val[1]; /* VARIABLE LENGTH FIELD */ + char val[FLEXIBLE_ARRAY_MEMBER]; } SimpleStringListCell; typedef struct SimpleStringList diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index bda7c28..8968993 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -389,7 +389,7 @@ typedef struct { ItemPointerData first; /* first item in this posting list (unpacked) */ uint16 nbytes; /* number of bytes that follow */ - unsigned char bytes[1]; /* varbyte encoded items (variable length) */ + unsigned char bytes[FLEXIBLE_ARRAY_MEMBER]; /* varbyte encoded items */ } GinPostingList; #define SizeOfGinPostingList(plist) (offsetof(GinPostingList, bytes) + SHORTALIGN((plist)->nbytes) ) @@ -527,7 +527,7 @@ typedef struct ItemPointerData rrightbound; /* new right bound of right page */ /* FOLLOWS: new compressed posting lists of left and right page */ - char newdata[1]; + char newdata[FLEXIBLE_ARRAY_MEMBER]; } ginxlogSplitDataLeaf; typedef struct diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 382826e..36f5257 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -47,7 +47,7 @@ typedef struct { BlockNumber prev; uint32 freespace; - char tupledata[1]; + char tupledata[FLEXIBLE_ARRAY_MEMBER]; } GISTNodeBufferPage; #define BUFFER_PAGE_DATA_OFFSET MAXALIGN(offsetof(GISTNodeBufferPage, tupledata)) @@ -131,7 +131,8 @@ typedef struct GISTSearchItem /* we must store parentlsn to detect whether a split occurred */ GISTSearchHeapItem heap; /* heap info, if heap tuple */ } data; - double distances[1]; /* array with numberOfOrderBys entries */ + double distances[FLEXIBLE_ARRAY_MEMBER]; /* array with numberOfOrderBys + * entries */ } GISTSearchItem; #define GISTSearchItemIsHeap(item) ((item).blkno == InvalidBlockNumber) diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h index a2ed2a0..f0f89de 100644 --- a/src/include/access/heapam_xlog.h +++ b/src/include/access/heapam_xlog.h @@ -132,7 +132,7 @@ typedef struct xl_heap_multi_insert { uint8 flags; uint16 ntuples; - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } xl_heap_multi_insert; #define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets) diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h index d2ad910..0225b17 100644 --- a/src/include/access/htup_details.h +++ b/src/include/access/htup_details.h @@ -150,7 +150,7 @@ struct HeapTupleHeaderData /* ^ - 23 bytes - ^ */ - bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ + bits8 t_bits[1]; /* bitmap of NULLs */ /* MORE DATA FOLLOWS AT END OF STRUCT */ }; @@ -579,7 +579,7 @@ struct MinimalTupleData /* ^ - 23 bytes - ^ */ - bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ + bits8 t_bits[1]; /* bitmap of NULLs */ /* MORE DATA FOLLOWS AT END OF STRUCT */ }; diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h index f11d8ef..0492ef6 100644 --- a/src/include/access/spgist_private.h +++ b/src/include/access/spgist_private.h @@ -426,7 +426,7 @@ typedef struct spgxlogMoveLeafs * the dead tuple from the source *---------- */ - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } spgxlogMoveLeafs; #define SizeOfSpgxlogMoveLeafs offsetof(spgxlogMoveLeafs, offsets) @@ -534,7 +534,7 @@ typedef struct spgxlogPickSplit * list of leaf tuples, length nInsert (unaligned!) *---------- */ - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } spgxlogPickSplit; #define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets) @@ -558,7 +558,7 @@ typedef struct spgxlogVacuumLeaf * tuple numbers to insert in nextOffset links *---------- */ - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } spgxlogVacuumLeaf; #define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets) @@ -571,7 +571,7 @@ typedef struct spgxlogVacuumRoot spgxlogState stateSrc; /* offsets of tuples to delete follow */ - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } spgxlogVacuumRoot; #define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets) @@ -583,7 +583,7 @@ typedef struct spgxlogVacuumRedirect TransactionId newestRedirectXid; /* newest XID of removed redirects */ /* offsets of redirect tuples to make placeholders follow */ - OffsetNumber offsets[1]; + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } spgxlogVacuumRedirect; #define SizeOfSpgxlogVacuumRedirect offsetof(spgxlogVacuumRedirect, offsets) diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 8205504..9b95f10 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -118,7 +118,7 @@ typedef struct xl_xact_assignment { TransactionId xtop; /* assigned XID's top-level XID */ int nsubxacts; /* number of subtransaction XIDs */ - TransactionId xsub[1]; /* assigned subxids */ + TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]; /* assigned subxids */ } xl_xact_assignment; #define MinSizeOfXactAssignment offsetof(xl_xact_assignment, xsub) @@ -128,7 +128,7 @@ typedef struct xl_xact_commit_compact TimestampTz xact_time; /* time of commit */ int nsubxacts; /* number of subtransaction XIDs */ /* ARRAY OF COMMITTED SUBTRANSACTION XIDs FOLLOWS */ - TransactionId subxacts[1]; /* VARIABLE LENGTH ARRAY */ + TransactionId subxacts[FLEXIBLE_ARRAY_MEMBER]; } xl_xact_commit_compact; #define MinSizeOfXactCommitCompact offsetof(xl_xact_commit_compact, subxacts) @@ -143,7 +143,7 @@ typedef struct xl_xact_commit Oid dbId; /* MyDatabaseId */ Oid tsId; /* MyDatabaseTableSpace */ /* Array of RelFileNode(s) to drop at commit */ - RelFileNode xnodes[1]; /* VARIABLE LENGTH ARRAY */ + RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]; /* ARRAY OF COMMITTED SUBTRANSACTION XIDs FOLLOWS */ /* ARRAY OF SHARED INVALIDATION MESSAGES FOLLOWS */ } xl_xact_commit; @@ -171,7 +171,7 @@ typedef struct xl_xact_abort int nrels; /* number of RelFileNodes */ int nsubxacts; /* number of subtransaction XIDs */ /* Array of RelFileNode(s) to drop at abort */ - RelFileNode xnodes[1]; /* VARIABLE LENGTH ARRAY */ + RelFileNode xnodes[FLEXIBLE_ARRAY_MEMBER]; /* ARRAY OF ABORTED SUBTRANSACTION XIDs FOLLOWS */ } xl_xact_abort; diff --git a/src/include/c.h b/src/include/c.h index b187520..bbd0d53 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -424,7 +424,7 @@ typedef struct Oid elemtype; int dim1; int lbound1; - int16 values[1]; /* VARIABLE LENGTH ARRAY */ + int16 values[FLEXIBLE_ARRAY_MEMBER]; } int2vector; /* VARIABLE LENGTH STRUCT */ typedef struct @@ -435,7 +435,7 @@ typedef struct Oid elemtype; int dim1; int lbound1; - Oid values[1]; /* VARIABLE LENGTH ARRAY */ + Oid values[FLEXIBLE_ARRAY_MEMBER]; } oidvector; /* VARIABLE LENGTH STRUCT */ /* diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index cb7cc0e..be1cac2 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -26,7 +26,7 @@ typedef struct xl_dbase_create_rec_old { /* Records copying of a single subdirectory incl. contents */ Oid db_id; - char src_path[1]; /* VARIABLE LENGTH STRING */ + char src_path[FLEXIBLE_ARRAY_MEMBER]; /* dst_path follows src_path */ } xl_dbase_create_rec_old; @@ -34,7 +34,7 @@ typedef struct xl_dbase_drop_rec_old { /* Records dropping of a single subdirectory incl. contents */ Oid db_id; - char dir_path[1]; /* VARIABLE LENGTH STRING */ + char dir_path[FLEXIBLE_ARRAY_MEMBER]; } xl_dbase_drop_rec_old; typedef struct xl_dbase_create_rec diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index e8b9bc4..9e40e31 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -25,7 +25,7 @@ typedef struct xl_tblspc_create_rec { Oid ts_id; - char ts_path[1]; /* VARIABLE LENGTH STRING */ + char ts_path[FLEXIBLE_ARRAY_MEMBER]; } xl_tblspc_create_rec; typedef struct xl_tblspc_drop_rec diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h index e79df71..71099b1 100644 --- a/src/include/executor/hashjoin.h +++ b/src/include/executor/hashjoin.h @@ -114,7 +114,7 @@ typedef struct HashMemoryChunkData struct HashMemoryChunkData *next; /* pointer to the next chunk (linked list) */ - char data[1]; /* buffer allocated at the end */ + char data[FLEXIBLE_ARRAY_MEMBER]; /* buffer allocated at the end */ } HashMemoryChunkData; typedef struct HashMemoryChunkData *HashMemoryChunk; diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h index 5f45f4d..1adabc3 100644 --- a/src/include/nodes/bitmapset.h +++ b/src/include/nodes/bitmapset.h @@ -32,7 +32,7 @@ typedef int32 signedbitmapword; /* must be the matching signed type */ typedef struct Bitmapset { int nwords; /* number of words in array */ - bitmapword words[1]; /* really [nwords] */ + bitmapword words[FLEXIBLE_ARRAY_MEMBER]; /* really [nwords] */ } Bitmapset; /* VARIABLE LENGTH STRUCT */ diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h index 5b096c5..0ad7ef0 100644 --- a/src/include/nodes/params.h +++ b/src/include/nodes/params.h @@ -71,7 +71,7 @@ typedef struct ParamListInfoData ParserSetupHook parserSetup; /* parser setup hook */ void *parserSetupArg; int numParams; /* number of ParamExternDatas following */ - ParamExternData params[1]; /* VARIABLE LENGTH ARRAY */ + ParamExternData params[1]; } ParamListInfoData; diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h index fb62c9e..bfbc0fb 100644 --- a/src/include/nodes/tidbitmap.h +++ b/src/include/nodes/tidbitmap.h @@ -41,7 +41,7 @@ typedef struct int ntuples; /* -1 indicates lossy result */ bool recheck; /* should the tuples be rechecked? */ /* Note: recheck is always true if ntuples < 0 */ - OffsetNumber offsets[1]; /* VARIABLE LENGTH ARRAY */ + OffsetNumber offsets[FLEXIBLE_ARRAY_MEMBER]; } TBMIterateResult; /* VARIABLE LENGTH STRUCT */ /* function prototypes in nodes/tidbitmap.c */ diff --git a/src/include/postgres.h b/src/include/postgres.h index 082c75b..482e676 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -117,20 +117,20 @@ typedef union struct /* Normal varlena (4-byte length) */ { uint32 va_header; - char va_data[1]; + char va_data[FLEXIBLE_ARRAY_MEMBER]; } va_4byte; struct /* Compressed-in-line format */ { uint32 va_header; uint32 va_rawsize; /* Original data size (excludes header) */ - char va_data[1]; /* Compressed data */ + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Compressed data */ } va_compressed; } varattrib_4b; typedef struct { uint8 va_header; - char va_data[1]; /* Data begins here */ + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Data begins here */ } varattrib_1b; /* TOAST pointers are a subset of varattrib_1b with an identifying tag byte */ @@ -138,7 +138,8 @@ typedef struct { uint8 va_header; /* Always 0x80 or 0x01 */ uint8 va_tag; /* Type of datum */ - char va_data[1]; /* Data (of the type indicated by va_tag) */ + char va_data[FLEXIBLE_ARRAY_MEMBER]; /* Data (of the type + * indicated by va_tag) */ } varattrib_1b_e; /* diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h index 602b13c..89a535c 100644 --- a/src/include/postmaster/syslogger.h +++ b/src/include/postmaster/syslogger.h @@ -48,7 +48,7 @@ typedef struct int32 pid; /* writer's pid */ char is_last; /* last chunk of message? 't' or 'f' ('T' or * 'F' for CSV case) */ - char data[1]; /* data payload starts here */ + char data[FLEXIBLE_ARRAY_MEMBER]; /* data payload starts here */ } PipeProtoHeader; typedef union diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h index 8867750..02faad8 100644 --- a/src/include/replication/walsender_private.h +++ b/src/include/replication/walsender_private.h @@ -88,7 +88,7 @@ typedef struct */ bool sync_standbys_defined; - WalSnd walsnds[1]; /* VARIABLE LENGTH ARRAY */ + WalSnd walsnds[FLEXIBLE_ARRAY_MEMBER]; } WalSndCtlData; extern WalSndCtlData *WalSndCtl; diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index f693032..b7dbd6f 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -156,7 +156,8 @@ typedef struct PageHeaderData LocationIndex pd_special; /* offset to start of special space */ uint16 pd_pagesize_version; TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */ - ItemIdData pd_linp[1]; /* beginning of line pointer array */ + ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]; /* beginning of line pointer + * array */ } PageHeaderData; typedef PageHeaderData *PageHeader; diff --git a/src/include/storage/fsm_internals.h b/src/include/storage/fsm_internals.h index 1decd90..26340b4 100644 --- a/src/include/storage/fsm_internals.h +++ b/src/include/storage/fsm_internals.h @@ -39,7 +39,7 @@ typedef struct * NonLeafNodesPerPage elements are upper nodes, and the following * LeafNodesPerPage elements are leaf nodes. Unused nodes are zero. */ - uint8 fp_nodes[1]; + uint8 fp_nodes[FLEXIBLE_ARRAY_MEMBER]; } FSMPageData; typedef FSMPageData *FSMPage; diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h index c32c963..7626c4c 100644 --- a/src/include/storage/standby.h +++ b/src/include/storage/standby.h @@ -60,7 +60,7 @@ extern void StandbyReleaseOldLocks(int nxids, TransactionId *xids); typedef struct xl_standby_locks { int nlocks; /* number of entries in locks array */ - xl_standby_lock locks[1]; /* VARIABLE LENGTH ARRAY */ + xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER]; } xl_standby_locks; /* @@ -75,7 +75,7 @@ typedef struct xl_running_xacts TransactionId oldestRunningXid; /* *not* oldestXmin */ TransactionId latestCompletedXid; /* so we can set xmax */ - TransactionId xids[1]; /* VARIABLE LENGTH ARRAY */ + TransactionId xids[FLEXIBLE_ARRAY_MEMBER]; } xl_running_xacts; #define MinSizeOfXactRunningXacts offsetof(xl_running_xacts, xids) diff --git a/src/include/tsearch/dicts/regis.h b/src/include/tsearch/dicts/regis.h index 081a502..ddf5b60 100644 --- a/src/include/tsearch/dicts/regis.h +++ b/src/include/tsearch/dicts/regis.h @@ -21,7 +21,7 @@ typedef struct RegisNode len:16, unused:14; struct RegisNode *next; - unsigned char data[1]; + unsigned char data[FLEXIBLE_ARRAY_MEMBER]; } RegisNode; #define RNHDRSZ (offsetof(RegisNode,data)) diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h index a75552b..e512532 100644 --- a/src/include/tsearch/dicts/spell.h +++ b/src/include/tsearch/dicts/spell.h @@ -49,7 +49,7 @@ typedef struct typedef struct SPNode { uint32 length; - SPNodeData data[1]; + SPNodeData data[FLEXIBLE_ARRAY_MEMBER]; } SPNode; #define SPNHDRSZ (offsetof(SPNode,data)) @@ -70,7 +70,7 @@ typedef struct spell_struct int len; } d; } p; - char word[1]; /* variable length, null-terminated */ + char word[FLEXIBLE_ARRAY_MEMBER]; } SPELL; #define SPELLHDRSZ (offsetof(SPELL, word)) @@ -120,7 +120,7 @@ typedef struct AffixNode { uint32 isvoid:1, length:31; - AffixNodeData data[1]; + AffixNodeData data[FLEXIBLE_ARRAY_MEMBER]; } AffixNode; #define ANHRDSZ (offsetof(AffixNode, data)) diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index 1cdfa82..ce919a2 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -63,7 +63,7 @@ typedef uint16 WordEntryPos; typedef struct { uint16 npos; - WordEntryPos pos[1]; /* variable length */ + WordEntryPos pos[FLEXIBLE_ARRAY_MEMBER]; } WordEntryPosVector; @@ -82,7 +82,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 size; - WordEntry entries[1]; /* variable length */ + WordEntry entries[FLEXIBLE_ARRAY_MEMBER]; /* lexemes follow the entries[] array */ } TSVectorData; @@ -233,7 +233,7 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 size; /* number of QueryItems */ - char data[1]; /* data starts here */ + char data[FLEXIBLE_ARRAY_MEMBER]; /* data starts here */ } TSQueryData; typedef TSQueryData *TSQuery; diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index 8084785..f5361f9 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -147,7 +147,7 @@ typedef struct catclist uint32 hash_value; /* hash value for lookup keys */ HeapTupleData tuple; /* header for tuple holding keys */ int n_members; /* number of member tuples */ - CatCTup *members[1]; /* members --- VARIABLE LENGTH ARRAY */ + CatCTup *members[FLEXIBLE_ARRAY_MEMBER]; /* members */ } CatCList; /* VARIABLE LENGTH STRUCT */ diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index 8912ba5..d36f297 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -219,7 +219,7 @@ typedef struct TimeZoneAbbrevTable { Size tblsize; /* size in bytes of TimeZoneAbbrevTable */ int numabbrevs; /* number of entries in abbrevs[] array */ - datetkn abbrevs[1]; /* VARIABLE LENGTH ARRAY */ + datetkn abbrevs[FLEXIBLE_ARRAY_MEMBER]; /* DynamicZoneAbbrev(s) may follow the abbrevs[] array */ } TimeZoneAbbrevTable; @@ -227,7 +227,8 @@ typedef struct TimeZoneAbbrevTable typedef struct DynamicZoneAbbrev { pg_tz *tz; /* NULL if not yet looked up */ - char zone[1]; /* zone name (var length, NUL-terminated) */ + char zone[FLEXIBLE_ARRAY_MEMBER]; /* zone name (var length, + * NUL-terminated) */ } DynamicZoneAbbrev; diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index 0b6d3c3..63885f3 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -80,7 +80,8 @@ typedef struct int32 npts; int32 closed; /* is this a closed polygon? */ int32 dummy; /* padding to make it double align */ - Point p[1]; /* variable length array of POINTs */ + Point p[FLEXIBLE_ARRAY_MEMBER]; /* variable length array + * of POINTs */ } PATH; diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h index 887eb9b..9d1770e 100644 --- a/src/include/utils/jsonb.h +++ b/src/include/utils/jsonb.h @@ -194,7 +194,7 @@ typedef struct JsonbContainer { uint32 header; /* number of elements or key/value pairs, and * flags */ - JEntry children[1]; /* variable length */ + JEntry children[FLEXIBLE_ARRAY_MEMBER]; /* the data for each child node follows. */ } JsonbContainer; diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h index 420310d..73b4905 100644 --- a/src/include/utils/relmapper.h +++ b/src/include/utils/relmapper.h @@ -29,7 +29,7 @@ typedef struct xl_relmap_update Oid dbid; /* database ID, or 0 for shared map */ Oid tsid; /* database's tablespace, or pg_global */ int32 nbytes; /* size of relmap data */ - char data[1]; /* VARIABLE LENGTH ARRAY */ + char data[FLEXIBLE_ARRAY_MEMBER]; } xl_relmap_update; #define MinSizeOfRelmapUpdate offsetof(xl_relmap_update, data) diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h index 8afc3b1..bd5bf52 100644 --- a/src/include/utils/varbit.h +++ b/src/include/utils/varbit.h @@ -26,7 +26,8 @@ typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ int32 bit_len; /* number of valid bits */ - bits8 bit_dat[1]; /* bit string, most sig. byte first */ + bits8 bit_dat[FLEXIBLE_ARRAY_MEMBER]; /* bit string, most sig. + * byte first */ } VarBit; /* -- 2.3.0
From b607e5be3ff1099d7f0374bafb7a2b497a8860fd Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@otacoo.com> Date: Mon, 16 Feb 2015 03:12:39 +0900 Subject: [PATCH 2/3] Use FLEXIBLE_ARRAY_MEMBER in catalog tables --- src/include/catalog/pg_attribute.h | 6 +++--- src/include/catalog/pg_class.h | 5 +++-- src/include/catalog/pg_constraint.h | 12 ++++++------ src/include/catalog/pg_database.h | 2 +- src/include/catalog/pg_db_role_setting.h | 3 ++- src/include/catalog/pg_default_acl.h | 3 ++- src/include/catalog/pg_event_trigger.h | 3 ++- src/include/catalog/pg_extension.h | 6 ++++-- 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_language.h | 2 +- src/include/catalog/pg_largeobject_metadata.h | 2 +- src/include/catalog/pg_namespace.h | 2 +- src/include/catalog/pg_pltemplate.h | 2 +- src/include/catalog/pg_policy.h | 3 ++- src/include/catalog/pg_proc.h | 14 +++++++++----- src/include/catalog/pg_statistic.h | 10 +++++----- src/include/catalog/pg_tablespace.h | 5 +++-- src/include/catalog/pg_type.h | 2 +- src/include/catalog/pg_user_mapping.h | 2 +- 21 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 87a3462..73bcefe 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -157,13 +157,13 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK /* NOTE: The following fields are not present in tuple descriptors. */ /* Column-level access permissions */ - aclitem attacl[1]; + aclitem attacl[FLEXIBLE_ARRAY_MEMBER]; /* Column-level options */ - text attoptions[1]; + text attoptions[FLEXIBLE_ARRAY_MEMBER]; /* Column-level FDW options */ - text attfdwoptions[1]; + text attfdwoptions[FLEXIBLE_ARRAY_MEMBER]; #endif } FormData_pg_attribute; diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index 8b4c35c..9516d5d 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -74,8 +74,9 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ - aclitem relacl[1]; /* access permissions */ - text reloptions[1]; /* access-method-specific options */ + aclitem relacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ + text reloptions[FLEXIBLE_ARRAY_MEMBER]; /* access-method-specific + * options */ #endif } FormData_pg_class; diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 6f32ac8..2100203 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -98,36 +98,36 @@ CATALOG(pg_constraint,2606) * Columns of conrelid that the constraint applies to, if known (this is * NULL for trigger constraints) */ - int16 conkey[1]; + int16 conkey[FLEXIBLE_ARRAY_MEMBER]; /* * If a foreign key, the referenced columns of confrelid */ - int16 confkey[1]; + int16 confkey[FLEXIBLE_ARRAY_MEMBER]; /* * If a foreign key, the OIDs of the PK = FK equality operators for each * column of the constraint */ - Oid conpfeqop[1]; + Oid conpfeqop[FLEXIBLE_ARRAY_MEMBER]; /* * If a foreign key, the OIDs of the PK = PK equality operators for each * column of the constraint (i.e., equality for the referenced columns) */ - Oid conppeqop[1]; + Oid conppeqop[FLEXIBLE_ARRAY_MEMBER]; /* * If a foreign key, the OIDs of the FK = FK equality operators for each * column of the constraint (i.e., equality for the referencing columns) */ - Oid conffeqop[1]; + Oid conffeqop[FLEXIBLE_ARRAY_MEMBER]; /* * If an exclusion constraint, the OIDs of the exclusion operators for * each column of the constraint */ - Oid conexclop[1]; + Oid conexclop[FLEXIBLE_ARRAY_MEMBER]; /* * 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 1045139..92e331e 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -45,7 +45,7 @@ CATALOG(pg_database,1262) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248) BKI_SCHEMA_M Oid dattablespace; /* default table space for this DB */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem datacl[1]; /* access permissions */ + aclitem datacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ #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 9717569..ff931a9 100644 --- a/src/include/catalog/pg_db_role_setting.h +++ b/src/include/catalog/pg_db_role_setting.h @@ -38,7 +38,8 @@ CATALOG(pg_db_role_setting,2964) BKI_SHARED_RELATION BKI_WITHOUT_OIDS Oid setrole; /* role */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text setconfig[1]; /* GUC settings to apply at login */ + text setconfig[FLEXIBLE_ARRAY_MEMBER]; /* 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 0b5c554..dec4e32 100644 --- a/src/include/catalog/pg_default_acl.h +++ b/src/include/catalog/pg_default_acl.h @@ -34,7 +34,8 @@ CATALOG(pg_default_acl,826) char defaclobjtype; /* see DEFACLOBJ_xxx constants below */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem defaclacl[1]; /* permissions to add at CREATE time */ + aclitem defaclacl[FLEXIBLE_ARRAY_MEMBER]; /* 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 ca81a81..bb6c1aa 100644 --- a/src/include/catalog/pg_event_trigger.h +++ b/src/include/catalog/pg_event_trigger.h @@ -38,7 +38,8 @@ CATALOG(pg_event_trigger,3466) * session_replication_role */ #ifdef CATALOG_VARLEN - text evttags[1]; /* command TAGs this event trigger targets */ + text evttags[FLEXIBLE_ARRAY_MEMBER]; /* 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 f45d6cb..ff54dbc 100644 --- a/src/include/catalog/pg_extension.h +++ b/src/include/catalog/pg_extension.h @@ -38,8 +38,10 @@ CATALOG(pg_extension,3079) #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* extversion should never be null, but the others can be. */ text extversion; /* extension version name */ - Oid extconfig[1]; /* dumpable configuration tables */ - text extcondition[1]; /* WHERE clauses for config tables */ + Oid extconfig[FLEXIBLE_ARRAY_MEMBER]; /* dumpable configuration + * tables */ + text extcondition[FLEXIBLE_ARRAY_MEMBER]; /* 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 1c7db04..091ea38 100644 --- a/src/include/catalog/pg_foreign_data_wrapper.h +++ b/src/include/catalog/pg_foreign_data_wrapper.h @@ -36,8 +36,8 @@ CATALOG(pg_foreign_data_wrapper,2328) Oid fdwvalidator; /* option validation function, or 0 if none */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem fdwacl[1]; /* access permissions */ - text fdwoptions[1]; /* FDW options */ + aclitem fdwacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ + text fdwoptions[FLEXIBLE_ARRAY_MEMBER]; /* 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 7ac6fd9..3c28d57 100644 --- a/src/include/catalog/pg_foreign_server.h +++ b/src/include/catalog/pg_foreign_server.h @@ -35,8 +35,8 @@ CATALOG(pg_foreign_server,1417) #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[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ + text srvoptions[FLEXIBLE_ARRAY_MEMBER]; /* 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 2e6b947..727214c 100644 --- a/src/include/catalog/pg_foreign_table.h +++ b/src/include/catalog/pg_foreign_table.h @@ -32,7 +32,7 @@ CATALOG(pg_foreign_table,3118) BKI_WITHOUT_OIDS Oid ftserver; /* OID of foreign server */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text ftoptions[1]; /* FDW-specific options */ + text ftoptions[FLEXIBLE_ARRAY_MEMBER]; /* FDW-specific options */ #endif } FormData_pg_foreign_table; diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h index b82cca2..c7b10fc 100644 --- a/src/include/catalog/pg_language.h +++ b/src/include/catalog/pg_language.h @@ -39,7 +39,7 @@ CATALOG(pg_language,2612) Oid lanvalidator; /* Optional validation function */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem lanacl[1]; /* Access privileges */ + aclitem lanacl[FLEXIBLE_ARRAY_MEMBER]; /* Access privileges */ #endif } FormData_pg_language; diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h index 033f7bd..85658d2 100644 --- a/src/include/catalog/pg_largeobject_metadata.h +++ b/src/include/catalog/pg_largeobject_metadata.h @@ -33,7 +33,7 @@ CATALOG(pg_largeobject_metadata,2995) Oid lomowner; /* OID of the largeobject owner */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem lomacl[1]; /* access permissions */ + aclitem lomacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ #endif } FormData_pg_largeobject_metadata; diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index 2c8887c..e1258a8 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -39,7 +39,7 @@ CATALOG(pg_namespace,2615) Oid nspowner; #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem nspacl[1]; + aclitem nspacl[FLEXIBLE_ARRAY_MEMBER]; #endif } FormData_pg_namespace; diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h index c5e6554..def9cea 100644 --- a/src/include/catalog/pg_pltemplate.h +++ b/src/include/catalog/pg_pltemplate.h @@ -39,7 +39,7 @@ CATALOG(pg_pltemplate,1136) BKI_SHARED_RELATION BKI_WITHOUT_OIDS text tmplinline; /* name of anonymous-block handler, or NULL */ text tmplvalidator; /* name of validator function, or NULL */ text tmpllibrary; /* path of shared library */ - aclitem tmplacl[1]; /* access privileges for template */ + aclitem tmplacl[FLEXIBLE_ARRAY_MEMBER]; /* access privileges for template */ #endif } FormData_pg_pltemplate; diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h index ae71f3f..87b1b5f 100644 --- a/src/include/catalog/pg_policy.h +++ b/src/include/catalog/pg_policy.h @@ -25,7 +25,8 @@ CATALOG(pg_policy,3256) char polcmd; /* One of ACL_*_CHR, or '*' for all */ #ifdef CATALOG_VARLEN - Oid polroles[1]; /* Roles associated with policy, not-NULL */ + Oid polroles[FLEXIBLE_ARRAY_MEMBER]; /* Roles associated + * with policy, 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 9edfdb8..1efae3f 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -61,15 +61,19 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81) BKI_SCHEMA_MACRO oidvector proargtypes; /* parameter types (excludes OUT params) */ #ifdef CATALOG_VARLEN - Oid proallargtypes[1]; /* all param types (NULL if IN only) */ - char proargmodes[1]; /* parameter modes (NULL if IN only) */ - text proargnames[1]; /* parameter names (NULL if no names) */ + Oid proallargtypes[FLEXIBLE_ARRAY_MEMBER]; /* all param types + * (NULL if IN only) */ + char proargmodes[FLEXIBLE_ARRAY_MEMBER]; /* parameter modes + * (NULL if IN only) */ + text proargnames[FLEXIBLE_ARRAY_MEMBER]; /* parameter names + * (NULL if no names) */ pg_node_tree proargdefaults;/* list of expression trees for argument * defaults (NULL if none) */ text prosrc; /* procedure source text */ text probin; /* secondary procedure info (can be NULL) */ - text proconfig[1]; /* procedure-local GUC settings */ - aclitem proacl[1]; /* access permissions */ + text proconfig[FLEXIBLE_ARRAY_MEMBER]; /* procedure-local GUC + * settings */ + aclitem proacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ #endif } FormData_pg_proc; diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h index 62a00fe..a9c695a 100644 --- a/src/include/catalog/pg_statistic.h +++ b/src/include/catalog/pg_statistic.h @@ -97,11 +97,11 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS Oid staop5; #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[FLEXIBLE_ARRAY_MEMBER]; + float4 stanumbers2[FLEXIBLE_ARRAY_MEMBER]; + float4 stanumbers3[FLEXIBLE_ARRAY_MEMBER]; + float4 stanumbers4[FLEXIBLE_ARRAY_MEMBER]; + float4 stanumbers5[FLEXIBLE_ARRAY_MEMBER]; /* * Values in these arrays are values of the column's data type, or of some diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index 24b1d8f..3868d0b 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -34,8 +34,9 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION Oid spcowner; /* owner of tablespace */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem spcacl[1]; /* access permissions */ - text spcoptions[1]; /* per-tablespace options */ + aclitem spcacl[FLEXIBLE_ARRAY_MEMBER]; /* access permissions */ + text spcoptions[FLEXIBLE_ARRAY_MEMBER]; /* per-tablespace + * options */ #endif } FormData_pg_tablespace; diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 0a900dd..cda6a22 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -221,7 +221,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * Access permissions */ - aclitem typacl[1]; + aclitem typacl[FLEXIBLE_ARRAY_MEMBER]; #endif } FormData_pg_type; diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h index 3e76e99..5237be3 100644 --- a/src/include/catalog/pg_user_mapping.h +++ b/src/include/catalog/pg_user_mapping.h @@ -33,7 +33,7 @@ CATALOG(pg_user_mapping,1418) Oid umserver; /* server of this mapping */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text umoptions[1]; /* user mapping options */ + text umoptions[FLEXIBLE_ARRAY_MEMBER]; /* user mapping options */ #endif } FormData_pg_user_mapping; -- 2.3.0
From ad8f54cdb5776146f17d1038bb295b5f13b549f1 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@otacoo.com> Date: Mon, 16 Feb 2015 03:53:38 +0900 Subject: [PATCH 3/3] Update varlena in c.h to use FLEXIBLE_ARRAY_MEMBER Places using a variable-length variable not at the end of a structure are changed with workaround, without impacting what those features do. --- src/backend/access/heap/tuptoaster.c | 16 ++++++------ src/backend/storage/large_object/inv_api.c | 40 ++++++++++++++---------------- src/include/c.h | 2 +- src/include/catalog/pg_authid.h | 8 +++--- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index f8c1401..a8f178c 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -1365,12 +1365,7 @@ toast_save_datum(Relation rel, Datum value, CommandId mycid = GetCurrentCommandId(true); struct varlena *result; struct varatt_external toast_pointer; - struct - { - struct varlena hdr; - char data[TOAST_MAX_CHUNK_SIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } chunk_data; + struct varlena *chunk_data; int32 chunk_size; int32 chunk_seq = 0; char *data_p; @@ -1381,6 +1376,9 @@ toast_save_datum(Relation rel, Datum value, Assert(!VARATT_IS_EXTERNAL(value)); + chunk_data = (struct varlena *) + palloc(MAXALIGN(TOAST_MAX_CHUNK_SIZE + VARHDRSZ)); + /* * Open the toast relation and its indexes. We can use the index to check * uniqueness of the OID we assign to the toasted item, even though it has @@ -1523,7 +1521,7 @@ toast_save_datum(Relation rel, Datum value, * Initialize constant parts of the tuple data */ t_values[0] = ObjectIdGetDatum(toast_pointer.va_valueid); - t_values[2] = PointerGetDatum(&chunk_data); + t_values[2] = PointerGetDatum(chunk_data); t_isnull[0] = false; t_isnull[1] = false; t_isnull[2] = false; @@ -1546,8 +1544,8 @@ toast_save_datum(Relation rel, Datum value, * Build a tuple and store it */ t_values[1] = Int32GetDatum(chunk_seq++); - SET_VARSIZE(&chunk_data, chunk_size + VARHDRSZ); - memcpy(VARDATA(&chunk_data), data_p, chunk_size); + SET_VARSIZE(chunk_data, chunk_size + VARHDRSZ); + memcpy(VARDATA(chunk_data), data_p, chunk_size); toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull); heap_insert(toastrel, toasttup, mycid, options, NULL); diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index a19c401..b44fae7 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -562,13 +562,8 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) bool neednextpage; bytea *datafield; bool pfreeit; - struct - { - bytea hdr; - char data[LOBLKSIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } workbuf; - char *workb = VARDATA(&workbuf.hdr); + bytea *workbuf; + char *workb; HeapTuple newtup; Datum values[Natts_pg_largeobject]; bool nulls[Natts_pg_largeobject]; @@ -591,6 +586,9 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) errmsg("invalid large object write request size: %d", nbytes))); + workbuf = (bytea *) palloc(MAXALIGN(LOBLKSIZE + VARHDRSZ)); + workb = VARDATA(workbuf); + open_lo_relation(); indstate = CatalogOpenIndexes(lo_heap_r); @@ -664,7 +662,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) off += n; /* compute valid length of new page */ len = (len >= off) ? len : off; - SET_VARSIZE(&workbuf.hdr, len + VARHDRSZ); + SET_VARSIZE(workbuf, len + VARHDRSZ); /* * Form and insert updated tuple @@ -672,7 +670,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); memset(replace, false, sizeof(replace)); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); replace[Anum_pg_largeobject_data - 1] = true; newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r), values, nulls, replace); @@ -708,7 +706,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) obj_desc->offset += n; /* compute valid length of new page */ len = off + n; - SET_VARSIZE(&workbuf.hdr, len + VARHDRSZ); + SET_VARSIZE(workbuf, len + VARHDRSZ); /* * Form and insert updated tuple @@ -717,7 +715,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes) memset(nulls, false, sizeof(nulls)); values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id); values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); newtup = heap_form_tuple(lo_heap_r->rd_att, values, nulls); simple_heap_insert(lo_heap_r, newtup); CatalogIndexInsert(indstate, newtup); @@ -748,13 +746,8 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) SysScanDesc sd; HeapTuple oldtuple; Form_pg_largeobject olddata; - struct - { - bytea hdr; - char data[LOBLKSIZE]; /* make struct big enough */ - int32 align_it; /* ensure struct is aligned well enough */ - } workbuf; - char *workb = VARDATA(&workbuf.hdr); + bytea *workbuf; + char *workb; HeapTuple newtup; Datum values[Natts_pg_largeobject]; bool nulls[Natts_pg_largeobject]; @@ -776,6 +769,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) errmsg_internal("invalid large object truncation target: " INT64_FORMAT, len))); + workbuf = (bytea *) palloc(MAXALIGN(LOBLKSIZE + VARHDRSZ)); + workb = VARDATA(workbuf); + open_lo_relation(); indstate = CatalogOpenIndexes(lo_heap_r); @@ -834,7 +830,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) MemSet(workb + pagelen, 0, off - pagelen); /* compute length of new page */ - SET_VARSIZE(&workbuf.hdr, off + VARHDRSZ); + SET_VARSIZE(workbuf, off + VARHDRSZ); /* * Form and insert updated tuple @@ -842,7 +838,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); memset(replace, false, sizeof(replace)); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); replace[Anum_pg_largeobject_data - 1] = true; newtup = heap_modify_tuple(oldtuple, RelationGetDescr(lo_heap_r), values, nulls, replace); @@ -873,7 +869,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) MemSet(workb, 0, off); /* compute length of new page */ - SET_VARSIZE(&workbuf.hdr, off + VARHDRSZ); + SET_VARSIZE(workbuf, off + VARHDRSZ); /* * Form and insert new tuple @@ -882,7 +878,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len) memset(nulls, false, sizeof(nulls)); values[Anum_pg_largeobject_loid - 1] = ObjectIdGetDatum(obj_desc->id); values[Anum_pg_largeobject_pageno - 1] = Int32GetDatum(pageno); - values[Anum_pg_largeobject_data - 1] = PointerGetDatum(&workbuf); + values[Anum_pg_largeobject_data - 1] = PointerGetDatum(workbuf); newtup = heap_form_tuple(lo_heap_r->rd_att, values, nulls); simple_heap_insert(lo_heap_r, newtup); CatalogIndexInsert(indstate, newtup); diff --git a/src/include/c.h b/src/include/c.h index bbd0d53..36ec468 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -391,7 +391,7 @@ typedef struct struct varlena { char vl_len_[4]; /* Do not touch this field directly! */ - char vl_dat[1]; + char vl_dat[FLEXIBLE_ARRAY_MEMBER]; }; #define VARHDRSZ ((int32) sizeof(int32)) diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index e01e6aa..d8789a5 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -56,8 +56,10 @@ CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MAC int32 rolconnlimit; /* max connections allowed (-1=no limit) */ /* remaining fields may be null; use heap_getattr to read them! */ - text rolpassword; /* password, if any */ timestamptz rolvaliduntil; /* password expiration time, if any */ +#ifdef CATALOG_VARLEN + text rolpassword; /* password, if any */ +#endif } FormData_pg_authid; #undef timestamptz @@ -85,8 +87,8 @@ typedef FormData_pg_authid *Form_pg_authid; #define Anum_pg_authid_rolreplication 8 #define Anum_pg_authid_rolbypassrls 9 #define Anum_pg_authid_rolconnlimit 10 -#define Anum_pg_authid_rolpassword 11 -#define Anum_pg_authid_rolvaliduntil 12 +#define Anum_pg_authid_rolvaliduntil 11 +#define Anum_pg_authid_rolpassword 12 /* ---------------- * initial contents of pg_authid -- 2.3.0
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers