diff options
author | Pavan Deolasee | 2015-05-05 09:19:18 +0000 |
---|---|---|
committer | Pavan Deolasee | 2015-05-05 09:19:18 +0000 |
commit | 73fa25c67cbfa24c03e28c96bf356f2592671730 (patch) | |
tree | 10ded7e26abd78d93658cb72fc5cb9d4672eff2a /src/include | |
parent | da4d108859bcd7a308ca75aba54281e32968822c (diff) | |
parent | 4a9ab6d8619817f9e3989c99b65140e19041dab7 (diff) |
Merge branch 'XL_MASTER_MERGE_9_4' into XL_NEW_MASTER
Conflicts:
src/test/regress/expected/aggregates.out
src/test/regress/expected/create_index.out
src/test/regress/expected/inherit.out
src/test/regress/expected/join.out
src/test/regress/expected/window.out
src/test/regress/expected/with.out
Diffstat (limited to 'src/include')
477 files changed, 11729 insertions, 4522 deletions
diff --git a/src/include/.gitignore b/src/include/.gitignore index fa285a1605..49d108dbed 100644 --- a/src/include/.gitignore +++ b/src/include/.gitignore @@ -1,5 +1,6 @@ /stamp-h +/stamp-ext-h /pg_config.h +/pg_config_ext.h /pg_config_os.h /dynloader.h - diff --git a/src/include/Makefile b/src/include/Makefile index 74de25eb3e..62e54a3be1 100644 --- a/src/include/Makefile +++ b/src/include/Makefile @@ -13,24 +13,25 @@ top_builddir = ../.. include $(top_builddir)/src/Makefile.global -all: pg_config.h pg_config_os.h +all: pg_config.h pg_config_ext.h pg_config_os.h # Subdirectories containing headers for server-side dev -SUBDIRS = access bootstrap catalog commands datatype executor foreign lib libpq mb \ - nodes optimizer parser pgxc postmaster regex replication rewrite storage \ - tcop snowball snowball/libstemmer tsearch tsearch/dicts utils \ - port port/win32 port/win32_msvc port/win32_msvc/sys \ - port/win32/arpa port/win32/netinet port/win32/sys \ - portability gtm +SUBDIRS = access bootstrap catalog commands common datatype executor foreign \ + lib libpq mb nodes optimizer parser postmaster regex replication \ + rewrite storage tcop snowball snowball/libstemmer tsearch \ + tsearch/dicts utils port port/win32 port/win32_msvc \ + port/win32_msvc/sys port/win32/arpa port/win32/netinet \ + port/win32/sys portability gtm # Install all headers install: all installdirs # These headers are needed by the public headers of the interfaces. $(INSTALL_DATA) $(srcdir)/postgres_ext.h '$(DESTDIR)$(includedir)' $(INSTALL_DATA) $(srcdir)/libpq/libpq-fs.h '$(DESTDIR)$(includedir)/libpq' - $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)' - $(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)' + $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir)' + $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir)' + $(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir)' $(INSTALL_DATA) $(srcdir)/pg_config_manual.h '$(DESTDIR)$(includedir)' # These headers are needed by the not-so-public headers of the interfaces. $(INSTALL_DATA) $(srcdir)/c.h '$(DESTDIR)$(includedir_internal)' @@ -38,8 +39,9 @@ install: all installdirs $(INSTALL_DATA) $(srcdir)/postgres_fe.h '$(DESTDIR)$(includedir_internal)' $(INSTALL_DATA) $(srcdir)/libpq/pqcomm.h '$(DESTDIR)$(includedir_internal)/libpq' # These headers are needed for server-side development - $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)' - $(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) pg_config.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) pg_config_ext.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) pg_config_os.h '$(DESTDIR)$(includedir_server)' $(INSTALL_DATA) utils/errcodes.h '$(DESTDIR)$(includedir_server)/utils' $(INSTALL_DATA) utils/fmgroids.h '$(DESTDIR)$(includedir_server)/utils' # We don't use INSTALL_DATA for performance reasons --- there are a lot of files @@ -62,7 +64,7 @@ installdirs: uninstall: - rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h) + rm -f $(addprefix '$(DESTDIR)$(includedir)'/, pg_config.h pg_config_ext.h pg_config_os.h pg_config_manual.h postgres_ext.h libpq/libpq-fs.h) rm -f $(addprefix '$(DESTDIR)$(includedir_internal)'/, c.h port.h postgres_fe.h libpq/pqcomm.h) # heuristic... rm -rf $(addprefix '$(DESTDIR)$(includedir_server)'/, $(SUBDIRS) *.h) @@ -72,7 +74,4 @@ clean: rm -f utils/fmgroids.h utils/errcodes.h parser/gram.h utils/probes.h catalog/schemapg.h distclean maintainer-clean: clean - rm -f pg_config.h dynloader.h pg_config_os.h stamp-h - -maintainer-check: - cd catalog && ./duplicate_oids + rm -f pg_config.h pg_config_ext.h pg_config_os.h dynloader.h stamp-h stamp-ext-h diff --git a/src/include/access/attnum.h b/src/include/access/attnum.h index 80a5faf4c7..ae7be34e81 100644 --- a/src/include/access/attnum.h +++ b/src/include/access/attnum.h @@ -4,7 +4,7 @@ * POSTGRES attribute number definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/attnum.h @@ -16,7 +16,7 @@ /* - * user defined attribute numbers start at 1. -ay 2/95 + * user defined attribute numbers start at 1. -ay 2/95 */ typedef int16 AttrNumber; diff --git a/src/include/access/clog.h b/src/include/access/clog.h index bed3b8cf26..66a6d17f18 100644 --- a/src/include/access/clog.h +++ b/src/include/access/clog.h @@ -3,7 +3,7 @@ * * PostgreSQL transaction-commit-log manager * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/clog.h diff --git a/src/include/access/genam.h b/src/include/access/genam.h index ec18976d43..d99158fb39 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -4,7 +4,7 @@ * POSTGRES generalized index access method definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/genam.h @@ -91,7 +91,7 @@ typedef struct SysScanDescData *SysScanDesc; * blocking to see if a conflicting transaction commits. * * For deferrable unique constraints, UNIQUE_CHECK_PARTIAL is specified at - * insertion time. The index AM should test if the tuple is unique, but + * insertion time. The index AM should test if the tuple is unique, but * should not throw error, block, or prevent the insertion if the tuple * appears not to be unique. We'll recheck later when it is time for the * constraint to be enforced. The AM must return true if the tuple is @@ -100,7 +100,7 @@ typedef struct SysScanDescData *SysScanDesc; * * When it is time to recheck the deferred constraint, a pseudo-insertion * call is made with UNIQUE_CHECK_EXISTING. The tuple is already in the - * index in this case, so it should not be inserted again. Rather, just + * index in this case, so it should not be inserted again. Rather, just * check for conflicting live tuples (possibly blocking). */ typedef enum IndexUniqueCheck diff --git a/src/include/access/gin.h b/src/include/access/gin.h index 36e490a6f3..4cda0ecbab 100644 --- a/src/include/access/gin.h +++ b/src/include/access/gin.h @@ -2,7 +2,7 @@ * gin.h * Public header file for Generalized Inverted Index access method. * - * Copyright (c) 2006-2012, PostgreSQL Global Development Group + * Copyright (c) 2006-2014, PostgreSQL Global Development Group * * src/include/access/gin.h *-------------------------------------------------------------------------- @@ -23,7 +23,8 @@ #define GIN_EXTRACTQUERY_PROC 3 #define GIN_CONSISTENT_PROC 4 #define GIN_COMPARE_PARTIAL_PROC 5 -#define GINNProcs 5 +#define GIN_TRICONSISTENT_PROC 6 +#define GINNProcs 6 /* * searchMode settings for extractQueryFn. @@ -46,6 +47,23 @@ typedef struct GinStatsData int32 ginVersion; } GinStatsData; +/* + * A ternary value used by tri-consistent functions. + * + * For convenience, this is compatible with booleans. A boolean can be + * safely cast to a GinTernaryValue. + */ +typedef char GinTernaryValue; + +#define GIN_FALSE 0 /* item is not present / does not match */ +#define GIN_TRUE 1 /* item is present / matches */ +#define GIN_MAYBE 2 /* don't know if item is present / don't know + * if matches */ + +#define DatumGetGinTernaryValue(X) ((GinTernaryValue)(X)) +#define GinTernaryValueGetDatum(X) ((Datum)(X)) +#define PG_RETURN_GIN_TERNARY_VALUE(x) return GinTernaryValueGetDatum(x) + /* GUC parameter */ extern PGDLLIMPORT int GinFuzzySearchLimit; @@ -58,6 +76,5 @@ extern void gin_redo(XLogRecPtr lsn, XLogRecord *record); extern void gin_desc(StringInfo buf, uint8 xl_info, char *rec); extern void gin_xlog_startup(void); extern void gin_xlog_cleanup(void); -extern bool gin_safe_restartpoint(void); #endif /* GIN_H */ diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index e56a92358c..3baa9f5e1a 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -2,7 +2,7 @@ * gin_private.h * header file for postgres inverted index access method implementation. * - * Copyright (c) 2006-2012, PostgreSQL Global Development Group + * Copyright (c) 2006-2014, PostgreSQL Global Development Group * * src/include/access/gin_private.h *-------------------------------------------------------------------------- @@ -19,7 +19,7 @@ /* - * Page opaque data in a inverted index page. + * Page opaque data in an inverted index page. * * Note: GIN does not include a page ID word as do the other index types. * This is OK because the opaque data is only 8 bytes and so can be reliably @@ -32,9 +32,7 @@ typedef struct GinPageOpaqueData { BlockNumber rightlink; /* next page if any */ - OffsetNumber maxoff; /* number entries on GIN_DATA page: number of - * heap ItemPointers on GIN_DATA|GIN_LEAF page - * or number of PostingItems on GIN_DATA & + OffsetNumber maxoff; /* number of PostingItems on GIN_DATA & * ~GIN_LEAF page. On GIN_LIST page, number of * heap tuples. */ uint16 flags; /* see bit definitions below */ @@ -48,6 +46,9 @@ typedef GinPageOpaqueData *GinPageOpaque; #define GIN_META (1 << 3) #define GIN_LIST (1 << 4) #define GIN_LIST_FULLROW (1 << 5) /* makes sense only on GIN_LIST page */ +#define GIN_INCOMPLETE_SPLIT (1 << 6) /* page was split, but parent not + * updated */ +#define GIN_COMPRESSED (1 << 7) /* Page numbers of fixed-location pages */ #define GIN_METAPAGE_BLKNO (0) @@ -87,7 +88,12 @@ typedef struct GinMetaPageData * GIN version number (ideally this should have been at the front, but too * late now. Don't move it!) * - * Currently 1 (for indexes initialized in 9.1 or later) + * Currently 2 (for indexes initialized in 9.4 or later) + * + * Version 1 (indexes initialized in version 9.1, 9.2 or 9.3), is + * compatible, but may contain uncompressed posting tree (leaf) pages and + * posting lists. They will be converted to compressed format when + * modified. * * Version 0 (indexes initialized in 9.0 or before) is compatible but may * be missing null entries, including both null keys and placeholders. @@ -96,7 +102,7 @@ typedef struct GinMetaPageData int32 ginVersion; } GinMetaPageData; -#define GIN_CURRENT_VERSION 1 +#define GIN_CURRENT_VERSION 2 #define GinPageGetMeta(p) \ ((GinMetaPageData *) PageGetContents(p)) @@ -115,15 +121,18 @@ typedef struct GinMetaPageData #define GinPageSetList(page) ( GinPageGetOpaque(page)->flags |= GIN_LIST ) #define GinPageHasFullRow(page) ( GinPageGetOpaque(page)->flags & GIN_LIST_FULLROW ) #define GinPageSetFullRow(page) ( GinPageGetOpaque(page)->flags |= GIN_LIST_FULLROW ) +#define GinPageIsCompressed(page) ( GinPageGetOpaque(page)->flags & GIN_COMPRESSED ) +#define GinPageSetCompressed(page) ( GinPageGetOpaque(page)->flags |= GIN_COMPRESSED ) #define GinPageIsDeleted(page) ( GinPageGetOpaque(page)->flags & GIN_DELETED) #define GinPageSetDeleted(page) ( GinPageGetOpaque(page)->flags |= GIN_DELETED) #define GinPageSetNonDeleted(page) ( GinPageGetOpaque(page)->flags &= ~GIN_DELETED) +#define GinPageIsIncompleteSplit(page) ( GinPageGetOpaque(page)->flags & GIN_INCOMPLETE_SPLIT) #define GinPageRightMost(page) ( GinPageGetOpaque(page)->rightlink == InvalidBlockNumber) /* - * We use our own ItemPointerGet(BlockNumber|GetOffsetNumber) + * We use our own ItemPointerGet(BlockNumber|OffsetNumber) * to avoid Asserts, since sometimes the ip_posid isn't "valid" */ #define GinItemPointerGetBlockNumber(pointer) \ @@ -195,7 +204,7 @@ typedef signed char GinNullCategory; */ #define GinCategoryOffset(itup,ginstate) \ (IndexInfoFindDataOffset((itup)->t_info) + \ - ((ginstate)->oneCol ? 0 : sizeof(int2))) + ((ginstate)->oneCol ? 0 : sizeof(int16))) #define GinGetNullCategory(itup,ginstate) \ (*((GinNullCategory *) ((char*)(itup) + GinCategoryOffset(itup,ginstate)))) #define GinSetNullCategory(itup,ginstate,c) \ @@ -211,13 +220,16 @@ typedef signed char GinNullCategory; #define GinSetPostingTree(itup, blkno) ( GinSetNPosting((itup),GIN_TREE_POSTING), ItemPointerSetBlockNumber(&(itup)->t_tid, blkno) ) #define GinGetPostingTree(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid) -#define GinGetPostingOffset(itup) GinItemPointerGetBlockNumber(&(itup)->t_tid) -#define GinSetPostingOffset(itup,n) ItemPointerSetBlockNumber(&(itup)->t_tid,n) -#define GinGetPosting(itup) ((ItemPointer) ((char*)(itup) + GinGetPostingOffset(itup))) +#define GIN_ITUP_COMPRESSED (1 << 31) +#define GinGetPostingOffset(itup) (GinItemPointerGetBlockNumber(&(itup)->t_tid) & (~GIN_ITUP_COMPRESSED)) +#define GinSetPostingOffset(itup,n) ItemPointerSetBlockNumber(&(itup)->t_tid,(n)|GIN_ITUP_COMPRESSED) +#define GinGetPosting(itup) ((Pointer) ((char*)(itup) + GinGetPostingOffset(itup))) +#define GinItupIsCompressed(itup) (GinItemPointerGetBlockNumber(&(itup)->t_tid) & GIN_ITUP_COMPRESSED) #define GinMaxItemSize \ - MAXALIGN_DOWN(((BLCKSZ - SizeOfPageHeaderData - \ - MAXALIGN(sizeof(GinPageOpaqueData))) / 3 - sizeof(ItemIdData))) + Min(INDEX_SIZE_MASK, \ + MAXALIGN_DOWN(((BLCKSZ - SizeOfPageHeaderData - \ + MAXALIGN(sizeof(GinPageOpaqueData))) / 6 - sizeof(ItemIdData)))) /* * Access macros for non-leaf entry tuples @@ -228,27 +240,67 @@ typedef signed char GinNullCategory; /* * Data (posting tree) pages + * + * Posting tree pages don't store regular tuples. Non-leaf pages contain + * PostingItems, which are pairs of ItemPointers and child block numbers. + * Leaf pages contain GinPostingLists and an uncompressed array of item + * pointers. + * + * In a leaf page, the compressed posting lists are stored after the regular + * page header, one after each other. Although we don't store regular tuples, + * pd_lower is used to indicate the end of the posting lists. After that, free + * space follows. This layout is compatible with the "standard" heap and + * index page layout described in bufpage.h, so that we can e.g set buffer_std + * when writing WAL records. + * + * In the special space is the GinPageOpaque struct. */ +#define GinDataLeafPageGetPostingList(page) \ + (GinPostingList *) ((PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))) +#define GinDataLeafPageGetPostingListSize(page) \ + (((PageHeader) page)->pd_lower - MAXALIGN(SizeOfPageHeaderData) - MAXALIGN(sizeof(ItemPointerData))) + +#define GinDataLeafPageIsEmpty(page) \ + (GinPageIsCompressed(page) ? (GinDataLeafPageGetPostingListSize(page) == 0) : (GinPageGetOpaque(page)->maxoff < FirstOffsetNumber)) + +#define GinDataLeafPageGetFreeSpace(page) PageGetExactFreeSpace(page) + #define GinDataPageGetRightBound(page) ((ItemPointer) PageGetContents(page)) +/* + * Pointer to the data portion of a posting tree page. For internal pages, + * that's the beginning of the array of PostingItems. For compressed leaf + * pages, the first compressed posting list. For uncompressed (pre-9.4) leaf + * pages, it's the beginning of the ItemPointer array. + */ #define GinDataPageGetData(page) \ (PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData))) -#define GinSizeOfDataPageItem(page) \ - (GinPageIsLeaf(page) ? sizeof(ItemPointerData) : sizeof(PostingItem)) -#define GinDataPageGetItem(page,i) \ - (GinDataPageGetData(page) + ((i)-1) * GinSizeOfDataPageItem(page)) +/* non-leaf pages contain PostingItems */ +#define GinDataPageGetPostingItem(page, i) \ + ((PostingItem *) (GinDataPageGetData(page) + ((i)-1) * sizeof(PostingItem))) + +/* + * Note: there is no GinDataPageGetDataSize macro, because before version + * 9.4, we didn't set pd_lower on data pages. There can be pages in the index + * that were binary-upgraded from earlier versions and still have an invalid + * pd_lower, so we cannot trust it in general. Compressed posting tree leaf + * pages are new in 9.4, however, so we can trust them; see + * GinDataLeafPageGetPostingListSize. + */ +#define GinDataPageSetDataSize(page, size) \ + { \ + Assert(size <= GinDataPageMaxDataSize); \ + ((PageHeader) page)->pd_lower = (size) + MAXALIGN(SizeOfPageHeaderData) + MAXALIGN(sizeof(ItemPointerData)); \ + } -#define GinDataPageGetFreeSpace(page) \ +#define GinNonLeafDataPageGetFreeSpace(page) \ + (GinDataPageMaxDataSize - \ + GinPageGetOpaque(page)->maxoff * sizeof(PostingItem)) + +#define GinDataPageMaxDataSize \ (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \ - MAXALIGN(sizeof(ItemPointerData)) \ - - GinPageGetOpaque(page)->maxoff * GinSizeOfDataPageItem(page) \ - MAXALIGN(sizeof(GinPageOpaqueData))) -#define GinMaxLeafDataItems \ - ((BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - \ - MAXALIGN(sizeof(ItemPointerData)) - \ - MAXALIGN(sizeof(GinPageOpaqueData))) \ - / sizeof(ItemPointerData)) - /* * List pages */ @@ -305,6 +357,7 @@ typedef struct GinState FmgrInfo extractValueFn[INDEX_MAX_KEYS]; FmgrInfo extractQueryFn[INDEX_MAX_KEYS]; FmgrInfo consistentFn[INDEX_MAX_KEYS]; + FmgrInfo triConsistentFn[INDEX_MAX_KEYS]; FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */ /* canPartialMatch[i] is true if comparePartialFn[i] is valid */ bool canPartialMatch[INDEX_MAX_KEYS]; @@ -312,6 +365,23 @@ typedef struct GinState Oid supportCollation[INDEX_MAX_KEYS]; } GinState; + +/* + * A compressed posting list. + * + * Note: This requires 2-byte alignment. + */ +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) */ +} GinPostingList; + +#define SizeOfGinPostingList(plist) (offsetof(GinPostingList, bytes) + SHORTALIGN((plist)->nbytes) ) +#define GinNextPostingListSegment(cur) ((GinPostingList *) (((char *) (cur)) + SizeOfGinPostingList((cur)))) + + /* XLog stuff */ #define XLOG_GIN_CREATE_INDEX 0x00 @@ -322,28 +392,84 @@ typedef struct ginxlogCreatePostingTree { RelFileNode node; BlockNumber blkno; - uint32 nitem; - /* follows list of heap's ItemPointer */ + uint32 size; + /* A compressed posting list follows */ } ginxlogCreatePostingTree; #define XLOG_GIN_INSERT 0x20 -typedef struct ginxlogInsert +/* + * The format of the insertion record varies depending on the page type. + * ginxlogInsert is the common part between all variants. + */ +typedef struct { RelFileNode node; BlockNumber blkno; - BlockNumber updateBlkno; + uint16 flags; /* GIN_SPLIT_ISLEAF and/or GIN_SPLIT_ISDATA */ + + /* + * FOLLOWS: + * + * 1. if not leaf page, block numbers of the left and right child pages + * whose split this insertion finishes. As BlockIdData[2] (beware of + * adding fields before this that would make them not 16-bit aligned) + * + * 2. an ginxlogInsertEntry or ginxlogRecompressDataLeaf struct, depending + * on tree type. + * + * NB: the below structs are only 16-bit aligned when appended to a + * ginxlogInsert struct! Beware of adding fields to them that require + * stricter alignment. + */ +} ginxlogInsert; + +typedef struct +{ OffsetNumber offset; bool isDelete; - bool isData; - bool isLeaf; - OffsetNumber nitem; + IndexTupleData tuple; /* variable length */ +} ginxlogInsertEntry; + + +typedef struct +{ + uint16 nactions; + + /* Variable number of 'actions' follow */ +} ginxlogRecompressDataLeaf; + +/* + * Note: this struct is currently not used in code, and only acts as + * documentation. The WAL record format is as specified here, but the code + * uses straight access through a Pointer and memcpy to read/write these. + */ +typedef struct +{ + uint8 segno; /* segment this action applies to */ + char type; /* action type (see below) */ /* - * follows: tuples or ItemPointerData or PostingItem or list of - * ItemPointerData + * Action-specific data follows. For INSERT and REPLACE actions that is a + * GinPostingList struct. For ADDITEMS, a uint16 for the number of items + * added, followed by the items themselves as ItemPointers. DELETE actions + * have no further data. */ -} ginxlogInsert; +} ginxlogSegmentAction; + +/* Action types */ +#define GIN_SEGMENT_UNMODIFIED 0 /* no action (not used in WAL records) */ +#define GIN_SEGMENT_DELETE 1 /* a whole segment is removed */ +#define GIN_SEGMENT_INSERT 2 /* a whole segment is added */ +#define GIN_SEGMENT_REPLACE 3 /* a segment is replaced */ +#define GIN_SEGMENT_ADDITEMS 4 /* items are added to existing segment */ + +typedef struct +{ + OffsetNumber offset; + PostingItem newitem; +} ginxlogInsertDataInternal; + #define XLOG_GIN_SPLIT 0x30 @@ -351,33 +477,83 @@ typedef struct ginxlogSplit { RelFileNode node; BlockNumber lblkno; - BlockNumber rootBlkno; BlockNumber rblkno; - BlockNumber rrlink; + BlockNumber rrlink; /* right link, or root's blocknumber if root + * split */ + BlockNumber leftChildBlkno; /* valid on a non-leaf split */ + BlockNumber rightChildBlkno; + uint16 flags; + + /* follows: one of the following structs */ +} ginxlogSplit; + +/* + * Flags used in ginxlogInsert and ginxlogSplit records + */ +#define GIN_INSERT_ISDATA 0x01 /* for both insert and split records */ +#define GIN_INSERT_ISLEAF 0x02 /* .. */ +#define GIN_SPLIT_ROOT 0x04 /* only for split records */ + +typedef struct +{ OffsetNumber separator; OffsetNumber nitem; - bool isData; - bool isLeaf; - bool isRootSplit; + /* FOLLOWS: IndexTuples */ +} ginxlogSplitEntry; + +typedef struct +{ + uint16 lsize; + uint16 rsize; + ItemPointerData lrightbound; /* new right bound of left page */ + ItemPointerData rrightbound; /* new right bound of right page */ - BlockNumber leftChildBlkno; - BlockNumber updateBlkno; + /* FOLLOWS: new compressed posting lists of left and right page */ + char newdata[1]; +} ginxlogSplitDataLeaf; - ItemPointerData rightbound; /* used only in posting tree */ - /* follows: list of tuple or ItemPointerData or PostingItem */ -} ginxlogSplit; +typedef struct +{ + OffsetNumber separator; + OffsetNumber nitem; + ItemPointerData rightbound; + /* FOLLOWS: array of PostingItems */ +} ginxlogSplitDataInternal; + +/* + * Vacuum simply WAL-logs the whole page, when anything is modified. This + * functionally identical heap_newpage records, but is kept separate for + * debugging purposes. (When inspecting the WAL stream, it's easier to see + * what's going on when GIN vacuum records are marked as such, not as heap + * records.) This is currently only used for entry tree leaf pages. + */ #define XLOG_GIN_VACUUM_PAGE 0x40 typedef struct ginxlogVacuumPage { RelFileNode node; BlockNumber blkno; - OffsetNumber nitem; - /* follows content of page */ + uint16 hole_offset; /* number of bytes before "hole" */ + uint16 hole_length; /* number of bytes in "hole" */ + /* entire page contents (minus the hole) follow at end of record */ } ginxlogVacuumPage; +/* + * Vacuuming posting tree leaf page is WAL-logged like recompression caused + * by insertion. + */ +#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE 0x90 + +typedef struct ginxlogVacuumDataLeafPage +{ + RelFileNode node; + BlockNumber blkno; + + ginxlogRecompressDataLeaf data; +} ginxlogVacuumDataLeafPage; + #define XLOG_GIN_DELETE_PAGE 0x50 typedef struct ginxlogDeletePage @@ -464,6 +640,7 @@ typedef struct GinBtreeStack BlockNumber blkno; Buffer buffer; OffsetNumber off; + ItemPointerData iptr; /* predictNumber contains predicted number of pages on current level */ uint32 predictNumber; struct GinBtreeStack *parent; @@ -471,87 +648,108 @@ typedef struct GinBtreeStack typedef struct GinBtreeData *GinBtree; +/* Return codes for GinBtreeData.placeToPage method */ +typedef enum +{ + UNMODIFIED, + INSERTED, + SPLIT +} GinPlaceToPageRC; + typedef struct GinBtreeData { /* search methods */ BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *); + BlockNumber (*getLeftMostChild) (GinBtree, Page); bool (*isMoveRight) (GinBtree, Page); bool (*findItem) (GinBtree, GinBtreeStack *); /* insert methods */ OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber); - BlockNumber (*getLeftMostPage) (GinBtree, Page); - bool (*isEnoughSpace) (GinBtree, Buffer, OffsetNumber); - void (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **); - Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **); - void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer); + GinPlaceToPageRC (*placeToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, XLogRecData **, Page *, Page *); + void *(*prepareDownlink) (GinBtree, Buffer); + void (*fillRoot) (GinBtree, Page, BlockNumber, Page, BlockNumber, Page); bool isData; - bool searchMode; Relation index; + BlockNumber rootBlkno; GinState *ginstate; /* not valid in a data scan */ bool fullScan; bool isBuild; - BlockNumber rightblkno; - - /* Entry options */ + /* Search key for Entry tree */ OffsetNumber entryAttnum; Datum entryKey; GinNullCategory entryCategory; - IndexTuple entry; - bool isDelete; - /* Data (posting tree) options */ + /* Search key for data tree (posting tree) */ + ItemPointerData itemptr; +} GinBtreeData; + +/* This represents a tuple to be inserted to entry tree. */ +typedef struct +{ + IndexTuple entry; /* tuple to insert */ + bool isDelete; /* delete old tuple at same offset? */ +} GinBtreeEntryInsertData; + +/* + * This represents an itempointer, or many itempointers, to be inserted to + * a data (posting tree) leaf page + */ +typedef struct +{ ItemPointerData *items; uint32 nitem; uint32 curitem; +} GinBtreeDataLeafInsertData; - PostingItem pitem; -} GinBtreeData; +/* + * For internal data (posting tree) pages, the insertion payload is a + * PostingItem + */ -extern GinBtreeStack *ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno); -extern GinBtreeStack *ginFindLeafPage(GinBtree btree, GinBtreeStack *stack); +extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode); +extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode); extern void freeGinBtreeStack(GinBtreeStack *stack); extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack, - GinStatsData *buildStats); -extern void ginFindParents(GinBtree btree, GinBtreeStack *stack, BlockNumber rootBlkno); + void *insertdata, GinStatsData *buildStats); /* ginentrypage.c */ extern IndexTuple GinFormTuple(GinState *ginstate, OffsetNumber attnum, Datum key, GinNullCategory category, - ItemPointerData *ipd, uint32 nipd, bool errorTooBig); -extern void GinShortenTuple(IndexTuple itup, uint32 nipd); + Pointer data, Size dataSize, int nipd, bool errorTooBig); extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, Datum key, GinNullCategory category, GinState *ginstate); -extern void ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf); -extern IndexTuple ginPageGetLinkItup(Buffer buf); +extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); +extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, + IndexTuple itup, int *nitems); /* gindatapage.c */ -extern int ginCompareItemPointers(ItemPointer a, ItemPointer b); -extern uint32 ginMergeItemPointers(ItemPointerData *dst, - ItemPointerData *a, uint32 na, - ItemPointerData *b, uint32 nb); - -extern void GinDataPageAddItem(Page page, void *data, OffsetNumber offset); +extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast); +extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm); +extern BlockNumber createPostingTree(Relation index, + ItemPointerData *items, uint32 nitems, + GinStatsData *buildStats); +extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset); extern void GinPageDeletePostingItem(Page page, OffsetNumber offset); - -typedef struct -{ - GinBtreeData btree; - GinBtreeStack *stack; -} GinPostingTreeScan; - -extern GinPostingTreeScan *ginPrepareScanPostingTree(Relation index, - BlockNumber rootBlkno, bool searchMode); -extern void ginInsertItemPointers(GinPostingTreeScan *gdi, +extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats); -extern Buffer ginScanBeginPostingTree(GinPostingTreeScan *gdi); -extern void ginDataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf); -extern void ginPrepareDataScan(GinBtree btree, Relation index); +extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno); +extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); +extern void ginPrepareDataScan(GinBtree btree, Relation index, BlockNumber rootBlkno); + +/* + * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers + * and ginVacuumPostingTreeLeaf and as an opaque struct, so we need a forward + * declaration for it. + */ +typedef struct GinVacuumState GinVacuumState; + +extern void ginVacuumPostingTreeLeaf(Relation rel, Buffer buf, GinVacuumState *gvs); /* ginscan.c */ @@ -568,7 +766,7 @@ extern void ginPrepareDataScan(GinBtree btree, Relation index); * * In each GinScanKeyData, nentries is the true number of entries, while * nuserentries is the number that extractQueryFn returned (which is what - * we report to consistentFn). The "user" entries must come first. + * we report to consistentFn). The "user" entries must come first. */ typedef struct GinScanKeyData *GinScanKey; @@ -584,8 +782,26 @@ typedef struct GinScanKeyData /* array of GinScanEntry pointers, one per extracted search condition */ GinScanEntry *scanEntry; + /* + * At least one of the entries in requiredEntries must be present for a + * tuple to match the overall qual. + * + * additionalEntries contains entries that are needed by the consistent + * function to decide if an item matches, but are not sufficient to + * satisfy the qual without entries from requiredEntries. + */ + GinScanEntry *requiredEntries; + int nrequired; + GinScanEntry *additionalEntries; + int nadditional; + /* array of check flags, reported to consistentFn */ bool *entryRes; + bool (*boolConsistentFn) (GinScanKey key); + GinTernaryValue (*triConsistentFn) (GinScanKey key); + FmgrInfo *consistentFmgrInfo; + FmgrInfo *triConsistentFmgrInfo; + Oid collation; /* other data needed for calling consistentFn */ Datum query; @@ -634,12 +850,13 @@ typedef struct GinScanEntryData /* used for Posting list and one page in Posting tree */ ItemPointerData *list; - uint32 nlist; + int nlist; OffsetNumber offset; bool isFinished; bool reduceResult; uint32 predictNumberResult; + GinBtreeData btree; } GinScanEntryData; typedef struct GinScanOpaqueData @@ -669,9 +886,14 @@ extern void ginNewScanKey(IndexScanDesc scan); /* ginget.c */ extern Datum gingetbitmap(PG_FUNCTION_ARGS); +/* ginlogic.c */ +extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key); + /* ginvacuum.c */ extern Datum ginbulkdelete(PG_FUNCTION_ARGS); extern Datum ginvacuumcleanup(PG_FUNCTION_ARGS); +extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs, + ItemPointerData *items, int nitem, int *nremaining); /* ginbulk.c */ typedef struct GinEntryAccumulator @@ -724,4 +946,40 @@ extern void ginHeapTupleFastCollect(GinState *ginstate, extern void ginInsertCleanup(GinState *ginstate, bool vac_delay, IndexBulkDeleteResult *stats); +/* ginpostinglist.c */ + +extern GinPostingList *ginCompressPostingList(const ItemPointer ptrs, int nptrs, + int maxsize, int *nwritten); +extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int totalsize, TIDBitmap *tbm); + +extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *ptr, int len, int *ndecoded); +extern ItemPointer ginPostingListDecode(GinPostingList *ptr, int *ndecoded); +extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, + ItemPointerData *b, uint32 nb, + int *nmerged); + +/* + * Merging the results of several gin scans compares item pointers a lot, + * so we want this to be inlined. But if the compiler doesn't support that, + * fall back on the non-inline version from itemptr.c. See STATIC_IF_INLINE in + * c.h. + */ +#ifdef PG_USE_INLINE +static inline int +ginCompareItemPointers(ItemPointer a, ItemPointer b) +{ + uint64 ia = (uint64) a->ip_blkid.bi_hi << 32 | (uint64) a->ip_blkid.bi_lo << 16 | a->ip_posid; + uint64 ib = (uint64) b->ip_blkid.bi_hi << 32 | (uint64) b->ip_blkid.bi_lo << 16 | b->ip_posid; + + if (ia == ib) + return 0; + else if (ia > ib) + return 1; + else + return -1; +} +#else +#define ginCompareItemPointers(a, b) ItemPointerCompare(a, b) +#endif /* PG_USE_INLINE */ + #endif /* GIN_PRIVATE_H */ diff --git a/src/include/access/gist.h b/src/include/access/gist.h index ed57bb7f93..ef5aed4d3e 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -6,7 +6,7 @@ * changes should be made with care. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gist.h @@ -65,9 +65,15 @@ typedef XLogRecPtr GistNSN; +/* + * For on-disk compatibility with pre-9.3 servers, NSN is stored as two + * 32-bit fields on disk, same as LSNs. + */ +typedef PageXLogRecPtr PageGistNSN; + typedef struct GISTPageOpaqueData { - GistNSN nsn; /* this value must change on page split */ + PageGistNSN nsn; /* this value must change on page split */ BlockNumber rightlink; /* next page if any */ uint16 flags; /* see bit definitions above */ uint16 gist_page_id; /* for identification of GiST indexes */ @@ -85,11 +91,30 @@ typedef GISTPageOpaqueData *GISTPageOpaque; /* * This is the Split Vector to be returned by the PickSplit method. - * PickSplit should check spl_(r|l)datum_exists. If it is 'true', - * that corresponding spl_(r|l)datum already defined and - * PickSplit should use that value. PickSplit should always set - * spl_(r|l)datum_exists to false: GiST will check value to - * control supporting this feature by PickSplit... + * PickSplit should fill the indexes of tuples to go to the left side into + * spl_left[], and those to go to the right into spl_right[] (note the method + * is responsible for palloc'ing both of these arrays!). The tuple counts + * go into spl_nleft/spl_nright, and spl_ldatum/spl_rdatum must be set to + * the union keys for each side. + * + * If spl_ldatum_exists and spl_rdatum_exists are true, then we are performing + * a "secondary split" using a non-first index column. In this case some + * decisions have already been made about a page split, and the set of tuples + * being passed to PickSplit is just the tuples about which we are undecided. + * spl_ldatum/spl_rdatum then contain the union keys for the tuples already + * chosen to go left or right. Ideally the PickSplit method should take those + * keys into account while deciding what to do with the remaining tuples, ie + * it should try to "build out" from those unions so as to minimally expand + * them. If it does so, it should union the given tuples' keys into the + * existing spl_ldatum/spl_rdatum values rather than just setting those values + * from scratch, and then set spl_ldatum_exists/spl_rdatum_exists to false to + * show it has done this. + * + * If the PickSplit method fails to clear spl_ldatum_exists/spl_rdatum_exists, + * the core GiST code will make its own decision about how to merge the + * secondary-split results with the previously-chosen tuples, and will then + * recompute the union keys from scratch. This is a workable though often not + * optimal approach. */ typedef struct GIST_SPLITVEC { @@ -137,6 +162,9 @@ typedef struct GISTENTRY #define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT) #define GistClearFollowRight(page) ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT) +#define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn)) +#define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val)) + /* * Vector of GISTENTRY structs; user-defined methods union and picksplit * take it as one of their arguments diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 9af9a0cf8c..089c679421 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -4,7 +4,7 @@ * private declarations for GiST -- declarations related to the * internal implementation of GiST, not the public API * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gist_private.h @@ -22,6 +22,21 @@ #include "utils/rbtree.h" #include "utils/hsearch.h" +/* + * Maximum number of "halves" a page can be split into in one operation. + * Typically a split produces 2 halves, but can be more if keys have very + * different lengths, or when inserting multiple keys in one operation (as + * when inserting downlinks to an internal node). There is no theoretical + * limit on this, but in practice if you get more than a handful page halves + * in one split, there's something wrong with the opclass implementation. + * GIST_MAX_SPLIT_PAGES is an arbitrary limit on that, used to size some + * local arrays used during split. Note that there is also a limit on the + * number of buffers that can be held locked at a time, MAX_SIMUL_LWLOCKS, + * so if you raise this higher than that limit, you'll just get a different + * error. + */ +#define GIST_MAX_SPLIT_PAGES 75 + /* Buffer lock modes */ #define GIST_SHARE BUFFER_LOCK_SHARE #define GIST_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE @@ -167,7 +182,7 @@ typedef GISTScanOpaqueData *GISTScanOpaque; #define XLOG_GIST_PAGE_SPLIT 0x30 /* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */ #define XLOG_GIST_CREATE_INDEX 0x50 -#define XLOG_GIST_PAGE_DELETE 0x60 + /* #define XLOG_GIST_PAGE_DELETE 0x60 */ /* not used anymore */ typedef struct gistxlogPageUpdate { @@ -211,12 +226,6 @@ typedef struct gistxlogPage int num; /* number of index tuples following */ } gistxlogPage; -typedef struct gistxlogPageDelete -{ - RelFileNode node; - BlockNumber blkno; -} gistxlogPageDelete; - /* SplitedPageLayout - gistSplit function result */ typedef struct SplitedPageLayout { @@ -254,20 +263,21 @@ typedef struct GISTInsertStack struct GISTInsertStack *parent; } GISTInsertStack; +/* Working state and results for multi-column split logic in gistsplit.c */ typedef struct GistSplitVector { - GIST_SPLITVEC splitVector; /* to/from PickSplit method */ + GIST_SPLITVEC splitVector; /* passed to/from user PickSplit method */ Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in - * spl_left */ + * splitVector.spl_left */ bool spl_lisnull[INDEX_MAX_KEYS]; Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in - * spl_right */ + * splitVector.spl_right */ bool spl_risnull[INDEX_MAX_KEYS]; - bool *spl_equiv; /* equivalent tuples which can be freely - * distributed between left and right pages */ + bool *spl_dontcare; /* flags tuples which could go to either side + * of the split for zero penalty */ } GistSplitVector; typedef struct @@ -430,7 +440,8 @@ typedef struct extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, - IndexTuple *itup, int ntup, OffsetNumber oldoffnum, + IndexTuple *itup, int ntup, + OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markleftchild); @@ -505,7 +516,7 @@ extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, extern float gistpenalty(GISTSTATE *giststate, int attno, GISTENTRY *key1, bool isNull1, GISTENTRY *key2, bool isNull2); -extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, int startkey, +extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, Datum *attr, bool *isnull); extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b); extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, @@ -516,7 +527,7 @@ extern void gistMakeUnionKey(GISTSTATE *giststate, int attno, GISTENTRY *entry2, bool isnull2, Datum *dst, bool *dstisnull); -extern XLogRecPtr GetXLogRecPtrForTemp(void); +extern XLogRecPtr gistGetFakeLSN(Relation rel); /* gistvacuum.c */ extern Datum gistbulkdelete(PG_FUNCTION_ARGS); @@ -525,7 +536,7 @@ extern Datum gistvacuumcleanup(PG_FUNCTION_ARGS); /* gistsplit.c */ extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate, - GistSplitVector *v, GistEntryVector *entryvec, + GistSplitVector *v, int attno); /* gistbuild.c */ diff --git a/src/include/access/gistscan.h b/src/include/access/gistscan.h index 4950370f04..92515f88c7 100644 --- a/src/include/access/gistscan.h +++ b/src/include/access/gistscan.h @@ -4,7 +4,7 @@ * routines defined in access/gist/gistscan.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gistscan.h diff --git a/src/include/access/hash.h b/src/include/access/hash.h index 726970b762..318add9c4c 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -4,7 +4,7 @@ * header file for postgres hash access method implementation * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/hash.h @@ -185,7 +185,7 @@ typedef HashMetaPageData *HashMetaPage; #define ALL_SET ((uint32) ~0) /* - * Bitmap pages do not contain tuples. They do contain the standard + * Bitmap pages do not contain tuples. They do contain the standard * page headers and trailers; however, everything in between is a * giant bit array. The number of bits that fit on a page obviously * depends on the page size and the header/trailer overhead. We require @@ -334,7 +334,7 @@ extern bool _hash_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir); /* hashsort.c */ typedef struct HSpool HSpool; /* opaque struct in hashsort.c */ -extern HSpool *_h_spoolinit(Relation index, uint32 num_buckets); +extern HSpool *_h_spoolinit(Relation heap, Relation index, uint32 num_buckets); extern void _h_spooldestroy(HSpool *hspool); extern void _h_spool(IndexTuple itup, HSpool *hspool); extern void _h_indexbuild(HSpool *hspool); diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 026a19fa74..493839f60e 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -4,7 +4,7 @@ * POSTGRES heap access method definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/heapam.h @@ -16,8 +16,8 @@ #include "access/sdir.h" #include "access/skey.h" -#include "access/xlog.h" #include "nodes/primnodes.h" +#include "storage/bufpage.h" #include "storage/lock.h" #include "utils/relcache.h" #include "utils/snapshot.h" @@ -26,15 +26,50 @@ /* "options" flag bits for heap_insert */ #define HEAP_INSERT_SKIP_WAL 0x0001 #define HEAP_INSERT_SKIP_FSM 0x0002 +#define HEAP_INSERT_FROZEN 0x0004 typedef struct BulkInsertStateData *BulkInsertState; -typedef enum +/* + * Possible lock modes for a tuple. + */ +typedef enum LockTupleMode { - LockTupleShared, + /* SELECT FOR KEY SHARE */ + LockTupleKeyShare, + /* SELECT FOR SHARE */ + LockTupleShare, + /* SELECT FOR NO KEY UPDATE, and UPDATEs that don't modify key columns */ + LockTupleNoKeyExclusive, + /* SELECT FOR UPDATE, UPDATEs that modify key columns, and DELETE */ LockTupleExclusive } LockTupleMode; +#define MaxLockTupleMode LockTupleExclusive + +/* + * When heap_update, heap_delete, or heap_lock_tuple fail because the target + * tuple is already outdated, they fill in this struct to provide information + * to the caller about what happened. + * ctid is the target's ctid link: it is the same as the target's TID if the + * target was deleted, or the location of the replacement tuple if the target + * was updated. + * xmax is the outdating transaction's XID. If the caller wants to visit the + * replacement tuple, it must check that this matches before believing the + * replacement is really a match. + * cmax is the outdating command's CID, but only when the failure code is + * HeapTupleSelfUpdated (i.e., something in the current transaction outdated + * the tuple); otherwise cmax is zero. (We make this restriction because + * HeapTupleHeaderGetCmax doesn't work for tuples outdated in other + * transactions.) + */ +typedef struct HeapUpdateFailureData +{ + ItemPointerData ctid; + TransactionId xmax; + CommandId cmax; +} HeapUpdateFailureData; + /* ---------------- * function prototypes for heap access method @@ -70,6 +105,8 @@ typedef struct HeapScanDescData *HeapScanDesc; extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot, int nkeys, ScanKey key); +extern HeapScanDesc heap_beginscan_catalog(Relation relation, int nkeys, + ScanKey key); extern HeapScanDesc heap_beginscan_strat(Relation relation, Snapshot snapshot, int nkeys, ScanKey key, bool allow_strat, bool allow_sync); @@ -100,20 +137,21 @@ extern Oid heap_insert(Relation relation, HeapTuple tup, CommandId cid, extern void heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, CommandId cid, int options, BulkInsertState bistate); extern HTSU_Result heap_delete(Relation relation, ItemPointer tid, - ItemPointer ctid, TransactionId *update_xmax, - CommandId cid, Snapshot crosscheck, bool wait); + CommandId cid, Snapshot crosscheck, bool wait, + HeapUpdateFailureData *hufd); extern HTSU_Result heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, - ItemPointer ctid, TransactionId *update_xmax, - CommandId cid, Snapshot crosscheck, bool wait); + CommandId cid, Snapshot crosscheck, bool wait, + HeapUpdateFailureData *hufd, LockTupleMode *lockmode); extern HTSU_Result heap_lock_tuple(Relation relation, HeapTuple tuple, - Buffer *buffer, ItemPointer ctid, - TransactionId *update_xmax, CommandId cid, - LockTupleMode mode, bool nowait); + CommandId cid, LockTupleMode mode, bool nowait, + bool follow_update, + Buffer *buffer, HeapUpdateFailureData *hufd); extern void heap_inplace_update(Relation relation, HeapTuple tuple); -extern bool heap_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid); +extern bool heap_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid, + TransactionId cutoff_multi); extern bool heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid, - Buffer buf); + MultiXactId cutoff_multi, Buffer buf); extern Oid simple_heap_insert(Relation relation, HeapTuple tup); extern void simple_heap_delete(Relation relation, ItemPointer tid); @@ -125,29 +163,8 @@ extern void heap_restrpos(HeapScanDesc scan); extern void heap_sync(Relation relation); -extern void heap_redo(XLogRecPtr lsn, XLogRecord *rptr); -extern void heap_desc(StringInfo buf, uint8 xl_info, char *rec); -extern void heap2_redo(XLogRecPtr lsn, XLogRecord *rptr); -extern void heap2_desc(StringInfo buf, uint8 xl_info, char *rec); - -extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode, - TransactionId latestRemovedXid); -extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer, - OffsetNumber *redirected, int nredirected, - OffsetNumber *nowdead, int ndead, - OffsetNumber *nowunused, int nunused, - TransactionId latestRemovedXid); -extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, - TransactionId cutoff_xid, - OffsetNumber *offsets, int offcnt); -extern XLogRecPtr log_heap_visible(RelFileNode rnode, BlockNumber block, - Buffer vm_buffer, TransactionId cutoff_xid); -extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, - BlockNumber blk, Page page); - /* in heap/pruneheap.c */ -extern void heap_page_prune_opt(Relation relation, Buffer buffer, - TransactionId OldestXmin); +extern void heap_page_prune_opt(Relation relation, Buffer buffer); extern int heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, bool report_stats, TransactionId *latestRemovedXid); diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h new file mode 100644 index 0000000000..cfdd1ffbef --- /dev/null +++ b/src/include/access/heapam_xlog.h @@ -0,0 +1,398 @@ +/*------------------------------------------------------------------------- + * + * heapam_xlog.h + * POSTGRES heap access XLOG definitions. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/heapam_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef HEAPAM_XLOG_H +#define HEAPAM_XLOG_H + +#include "access/htup.h" +#include "access/xlog.h" +#include "storage/bufpage.h" +#include "storage/relfilenode.h" +#include "utils/relcache.h" + + +/* + * WAL record definitions for heapam.c's WAL operations + * + * XLOG allows to store some information in high 4 bits of log + * record xl_info field. We use 3 for opcode and one for init bit. + */ +#define XLOG_HEAP_INSERT 0x00 +#define XLOG_HEAP_DELETE 0x10 +#define XLOG_HEAP_UPDATE 0x20 +/* 0x030 is free, was XLOG_HEAP_MOVE */ +#define XLOG_HEAP_HOT_UPDATE 0x40 +#define XLOG_HEAP_NEWPAGE 0x50 +#define XLOG_HEAP_LOCK 0x60 +#define XLOG_HEAP_INPLACE 0x70 + +#define XLOG_HEAP_OPMASK 0x70 +/* + * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE, + * or MULTI_INSERT, we can (and we do) restore entire page in redo + */ +#define XLOG_HEAP_INIT_PAGE 0x80 +/* + * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes + * are associated with RM_HEAP2_ID, but are not logically different from + * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to + * these, too. + */ +#define XLOG_HEAP2_REWRITE 0x00 +#define XLOG_HEAP2_CLEAN 0x10 +#define XLOG_HEAP2_FREEZE_PAGE 0x20 +#define XLOG_HEAP2_CLEANUP_INFO 0x30 +#define XLOG_HEAP2_VISIBLE 0x40 +#define XLOG_HEAP2_MULTI_INSERT 0x50 +#define XLOG_HEAP2_LOCK_UPDATED 0x60 +#define XLOG_HEAP2_NEW_CID 0x70 + +/* + * xl_heap_* ->flag values, 8 bits are available. + */ +/* PD_ALL_VISIBLE was cleared */ +#define XLOG_HEAP_ALL_VISIBLE_CLEARED (1<<0) +/* PD_ALL_VISIBLE was cleared in the 2nd page */ +#define XLOG_HEAP_NEW_ALL_VISIBLE_CLEARED (1<<1) +#define XLOG_HEAP_CONTAINS_OLD_TUPLE (1<<2) +#define XLOG_HEAP_CONTAINS_OLD_KEY (1<<3) +#define XLOG_HEAP_CONTAINS_NEW_TUPLE (1<<4) +#define XLOG_HEAP_PREFIX_FROM_OLD (1<<5) +#define XLOG_HEAP_SUFFIX_FROM_OLD (1<<6) + +/* convenience macro for checking whether any form of old tuple was logged */ +#define XLOG_HEAP_CONTAINS_OLD \ + (XLOG_HEAP_CONTAINS_OLD_TUPLE | XLOG_HEAP_CONTAINS_OLD_KEY) + +/* + * All what we need to find changed tuple + * + * NB: on most machines, sizeof(xl_heaptid) will include some trailing pad + * bytes for alignment. We don't want to store the pad space in the XLOG, + * so use SizeOfHeapTid for space calculations. Similar comments apply for + * the other xl_FOO structs. + */ +typedef struct xl_heaptid +{ + RelFileNode node; + ItemPointerData tid; /* changed tuple id */ +} xl_heaptid; + +#define SizeOfHeapTid (offsetof(xl_heaptid, tid) + SizeOfIptrData) + +/* This is what we need to know about delete */ +typedef struct xl_heap_delete +{ + xl_heaptid target; /* deleted tuple id */ + TransactionId xmax; /* xmax of the deleted tuple */ + uint8 infobits_set; /* infomask bits */ + uint8 flags; +} xl_heap_delete; + +#define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8)) + +/* + * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted + * or updated tuple in WAL; we can save a few bytes by reconstructing the + * fields that are available elsewhere in the WAL record, or perhaps just + * plain needn't be reconstructed. These are the fields we must store. + * NOTE: t_hoff could be recomputed, but we may as well store it because + * it will come for free due to alignment considerations. + */ +typedef struct xl_heap_header +{ + uint16 t_infomask2; + uint16 t_infomask; + uint8 t_hoff; +} xl_heap_header; + +#define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8)) + +/* + * Variant of xl_heap_header that contains the length of the tuple, which is + * useful if the length of the tuple cannot be computed using the overall + * record length. E.g. because there are several tuples inside a single + * record. + */ +typedef struct xl_heap_header_len +{ + uint16 t_len; + xl_heap_header header; +} xl_heap_header_len; + +#define SizeOfHeapHeaderLen (offsetof(xl_heap_header_len, header) + SizeOfHeapHeader) + +/* This is what we need to know about insert */ +typedef struct xl_heap_insert +{ + xl_heaptid target; /* inserted tuple id */ + uint8 flags; + /* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */ +} xl_heap_insert; + +#define SizeOfHeapInsert (offsetof(xl_heap_insert, flags) + sizeof(uint8)) + +/* + * This is what we need to know about a multi-insert. The record consists of + * xl_heap_multi_insert header, followed by a xl_multi_insert_tuple and tuple + * data for each tuple. 'offsets' array is omitted if the whole page is + * reinitialized (XLOG_HEAP_INIT_PAGE) + */ +typedef struct xl_heap_multi_insert +{ + RelFileNode node; + BlockNumber blkno; + uint8 flags; + uint16 ntuples; + OffsetNumber offsets[1]; + + /* TUPLE DATA (xl_multi_insert_tuples) FOLLOW AT END OF STRUCT */ +} xl_heap_multi_insert; + +#define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets) + +typedef struct xl_multi_insert_tuple +{ + uint16 datalen; /* size of tuple data that follows */ + uint16 t_infomask2; + uint16 t_infomask; + uint8 t_hoff; + /* TUPLE DATA FOLLOWS AT END OF STRUCT */ +} xl_multi_insert_tuple; + +#define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8)) + +/* This is what we need to know about update|hot_update */ +typedef struct xl_heap_update +{ + xl_heaptid target; /* deleted tuple id */ + TransactionId old_xmax; /* xmax of the old tuple */ + TransactionId new_xmax; /* xmax of the new tuple */ + ItemPointerData newtid; /* new inserted tuple id */ + uint8 old_infobits_set; /* infomask bits to set on old tuple */ + uint8 flags; + + /* + * If XLOG_HEAP_PREFIX_FROM_OLD or XLOG_HEAP_SUFFIX_FROM_OLD flags are + * set, the prefix and/or suffix come next, as one or two uint16s. + * + * After that, xl_heap_header_len and new tuple data follow. The new + * tuple data and length don't include the prefix and suffix, which are + * copied from the old tuple on replay. The new tuple data is omitted if + * a full-page image of the page was taken (unless the + * XLOG_HEAP_CONTAINS_NEW_TUPLE flag is set, in which case it's included + * anyway). + * + * If XLOG_HEAP_CONTAINS_OLD_TUPLE or XLOG_HEAP_CONTAINS_OLD_KEY flags are + * set, another xl_heap_header_len struct and tuple data for the old tuple + * follows. + */ +} xl_heap_update; + +#define SizeOfHeapUpdate (offsetof(xl_heap_update, flags) + sizeof(uint8)) + +/* + * This is what we need to know about vacuum page cleanup/redirect + * + * The array of OffsetNumbers following the fixed part of the record contains: + * * for each redirected item: the item offset, then the offset redirected to + * * for each now-dead item: the item offset + * * for each now-unused item: the item offset + * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused. + * Note that nunused is not explicitly stored, but may be found by reference + * to the total record length. + */ +typedef struct xl_heap_clean +{ + RelFileNode node; + BlockNumber block; + TransactionId latestRemovedXid; + uint16 nredirected; + uint16 ndead; + /* OFFSET NUMBERS FOLLOW */ +} xl_heap_clean; + +#define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16)) + +/* + * Cleanup_info is required in some cases during a lazy VACUUM. + * Used for reporting the results of HeapTupleHeaderAdvanceLatestRemovedXid() + * see vacuumlazy.c for full explanation + */ +typedef struct xl_heap_cleanup_info +{ + RelFileNode node; + TransactionId latestRemovedXid; +} xl_heap_cleanup_info; + +#define SizeOfHeapCleanupInfo (sizeof(xl_heap_cleanup_info)) + +/* This is for replacing a page's contents in toto */ +/* NB: this is used for indexes as well as heaps */ +typedef struct xl_heap_newpage +{ + RelFileNode node; + ForkNumber forknum; + BlockNumber blkno; /* location of new page */ + uint16 hole_offset; /* number of bytes before "hole" */ + uint16 hole_length; /* number of bytes in "hole" */ + /* entire page contents (minus the hole) follow at end of record */ +} xl_heap_newpage; + +#define SizeOfHeapNewpage (offsetof(xl_heap_newpage, hole_length) + sizeof(uint16)) + +/* flags for infobits_set */ +#define XLHL_XMAX_IS_MULTI 0x01 +#define XLHL_XMAX_LOCK_ONLY 0x02 +#define XLHL_XMAX_EXCL_LOCK 0x04 +#define XLHL_XMAX_KEYSHR_LOCK 0x08 +#define XLHL_KEYS_UPDATED 0x10 + +/* This is what we need to know about lock */ +typedef struct xl_heap_lock +{ + xl_heaptid target; /* locked tuple id */ + TransactionId locking_xid; /* might be a MultiXactId not xid */ + int8 infobits_set; /* infomask and infomask2 bits to set */ +} xl_heap_lock; + +#define SizeOfHeapLock (offsetof(xl_heap_lock, infobits_set) + sizeof(int8)) + +/* This is what we need to know about locking an updated version of a row */ +typedef struct xl_heap_lock_updated +{ + xl_heaptid target; + TransactionId xmax; + uint8 infobits_set; +} xl_heap_lock_updated; + +#define SizeOfHeapLockUpdated (offsetof(xl_heap_lock_updated, infobits_set) + sizeof(uint8)) + +/* This is what we need to know about in-place update */ +typedef struct xl_heap_inplace +{ + xl_heaptid target; /* updated tuple id */ + /* TUPLE DATA FOLLOWS AT END OF STRUCT */ +} xl_heap_inplace; + +#define SizeOfHeapInplace (offsetof(xl_heap_inplace, target) + SizeOfHeapTid) + +/* + * This struct represents a 'freeze plan', which is what we need to know about + * a single tuple being frozen during vacuum. + */ +/* 0x01 was XLH_FREEZE_XMIN */ +#define XLH_FREEZE_XVAC 0x02 +#define XLH_INVALID_XVAC 0x04 + +typedef struct xl_heap_freeze_tuple +{ + TransactionId xmax; + OffsetNumber offset; + uint16 t_infomask2; + uint16 t_infomask; + uint8 frzflags; +} xl_heap_freeze_tuple; + +/* + * This is what we need to know about a block being frozen during vacuum + */ +typedef struct xl_heap_freeze_page +{ + RelFileNode node; + BlockNumber block; + TransactionId cutoff_xid; + uint16 ntuples; + xl_heap_freeze_tuple tuples[FLEXIBLE_ARRAY_MEMBER]; +} xl_heap_freeze_page; + +#define SizeOfHeapFreezePage offsetof(xl_heap_freeze_page, tuples) + +/* This is what we need to know about setting a visibility map bit */ +typedef struct xl_heap_visible +{ + RelFileNode node; + BlockNumber block; + TransactionId cutoff_xid; +} xl_heap_visible; + +#define SizeOfHeapVisible (offsetof(xl_heap_visible, cutoff_xid) + sizeof(TransactionId)) + +typedef struct xl_heap_new_cid +{ + /* + * store toplevel xid so we don't have to merge cids from different + * transactions + */ + TransactionId top_xid; + CommandId cmin; + CommandId cmax; + + /* + * don't really need the combocid since we have the actual values right in + * this struct, but the padding makes it free and its useful for + * debugging. + */ + CommandId combocid; + + /* + * Store the relfilenode/ctid pair to facilitate lookups. + */ + xl_heaptid target; +} xl_heap_new_cid; + +#define SizeOfHeapNewCid (offsetof(xl_heap_new_cid, target) + SizeOfHeapTid) + +/* logical rewrite xlog record header */ +typedef struct xl_heap_rewrite_mapping +{ + TransactionId mapped_xid; /* xid that might need to see the row */ + Oid mapped_db; /* DbOid or InvalidOid for shared rels */ + Oid mapped_rel; /* Oid of the mapped relation */ + off_t offset; /* How far have we written so far */ + uint32 num_mappings; /* Number of in-memory mappings */ + XLogRecPtr start_lsn; /* Insert LSN at begin of rewrite */ +} xl_heap_rewrite_mapping; + +extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple, + TransactionId *latestRemovedXid); + +extern void heap_redo(XLogRecPtr lsn, XLogRecord *rptr); +extern void heap_desc(StringInfo buf, uint8 xl_info, char *rec); +extern void heap2_redo(XLogRecPtr lsn, XLogRecord *rptr); +extern void heap2_desc(StringInfo buf, uint8 xl_info, char *rec); +extern void heap_xlog_logical_rewrite(XLogRecPtr lsn, XLogRecord *r); + +extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode, + TransactionId latestRemovedXid); +extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer, + OffsetNumber *redirected, int nredirected, + OffsetNumber *nowdead, int ndead, + OffsetNumber *nowunused, int nunused, + TransactionId latestRemovedXid); +extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, + TransactionId cutoff_xid, xl_heap_freeze_tuple *tuples, + int ntuples); +extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, + TransactionId cutoff_xid, + TransactionId cutoff_multi, + xl_heap_freeze_tuple *frz); +extern void heap_execute_freeze_tuple(HeapTupleHeader tuple, + xl_heap_freeze_tuple *xlrec_tp); +extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer, + Buffer vm_buffer, TransactionId cutoff_xid); +extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, + BlockNumber blk, Page page, bool page_std); +extern XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std); + +#endif /* HEAPAM_XLOG_H */ diff --git a/src/include/access/hio.h b/src/include/access/hio.h index a3f8a457b8..422fe3403a 100644 --- a/src/include/access/hio.h +++ b/src/include/access/hio.h @@ -4,7 +4,7 @@ * POSTGRES heap access method input/output definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/hio.h diff --git a/src/include/access/htup.h b/src/include/access/htup.h index fbb802e4c9..be3ef236e1 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/htup.h @@ -19,470 +19,15 @@ #ifndef HTUP_H #define HTUP_H -#include "access/tupdesc.h" -#include "access/tupmacs.h" -#include "storage/bufpage.h" #include "storage/itemptr.h" -#include "storage/relfilenode.h" -/* - * MaxTupleAttributeNumber limits the number of (user) columns in a tuple. - * The key limit on this value is that the size of the fixed overhead for - * a tuple, plus the size of the null-values bitmap (at 1 bit per column), - * plus MAXALIGN alignment, must fit into t_hoff which is uint8. On most - * machines the upper limit without making t_hoff wider would be a little - * over 1700. We use round numbers here and for MaxHeapAttributeNumber - * so that alterations in HeapTupleHeaderData layout won't change the - * supported max number of columns. - */ -#define MaxTupleAttributeNumber 1664 /* 8 * 208 */ - -/* - * MaxHeapAttributeNumber limits the number of (user) columns in a table. - * This should be somewhat less than MaxTupleAttributeNumber. It must be - * at least one less, else we will fail to do UPDATEs on a maximal-width - * table (because UPDATE has to form working tuples that include CTID). - * In practice we want some additional daylight so that we can gracefully - * support operations that add hidden "resjunk" columns, for example - * SELECT * FROM wide_table ORDER BY foo, bar, baz. - * In any case, depending on column data types you will likely be running - * into the disk-block-based limit on overall tuple size if you have more - * than a thousand or so columns. TOAST won't help. - */ -#define MaxHeapAttributeNumber 1600 /* 8 * 200 */ - -/* - * Heap tuple header. To avoid wasting space, the fields should be - * laid out in such a way as to avoid structure padding. - * - * Datums of composite types (row types) share the same general structure - * as on-disk tuples, so that the same routines can be used to build and - * examine them. However the requirements are slightly different: a Datum - * does not need any transaction visibility information, and it does need - * a length word and some embedded type information. We can achieve this - * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple - * with the fields needed in the Datum case. Typically, all tuples built - * in-memory will be initialized with the Datum fields; but when a tuple is - * about to be inserted in a table, the transaction fields will be filled, - * overwriting the datum fields. - * - * The overall structure of a heap tuple looks like: - * fixed fields (HeapTupleHeaderData struct) - * nulls bitmap (if HEAP_HASNULL is set in t_infomask) - * alignment padding (as needed to make user data MAXALIGN'd) - * object ID (if HEAP_HASOID is set in t_infomask) - * user data fields - * - * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three - * physical fields. Xmin and Xmax are always really stored, but Cmin, Cmax - * and Xvac share a field. This works because we know that Cmin and Cmax - * are only interesting for the lifetime of the inserting and deleting - * transaction respectively. If a tuple is inserted and deleted in the same - * transaction, we store a "combo" command id that can be mapped to the real - * cmin and cmax, but only by use of local state within the originating - * backend. See combocid.c for more details. Meanwhile, Xvac is only set by - * old-style VACUUM FULL, which does not have any command sub-structure and so - * does not need either Cmin or Cmax. (This requires that old-style VACUUM - * FULL never try to move a tuple whose Cmin or Cmax is still interesting, - * ie, an insert-in-progress or delete-in-progress tuple.) - * - * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid - * is initialized with its own TID (location). If the tuple is ever updated, - * its t_ctid is changed to point to the replacement version of the tuple. - * Thus, a tuple is the latest version of its row iff XMAX is invalid or - * t_ctid points to itself (in which case, if XMAX is valid, the tuple is - * either locked or deleted). One can follow the chain of t_ctid links - * to find the newest version of the row. Beware however that VACUUM might - * erase the pointed-to (newer) tuple before erasing the pointing (older) - * tuple. Hence, when following a t_ctid link, it is necessary to check - * to see if the referenced slot is empty or contains an unrelated tuple. - * Check that the referenced tuple has XMIN equal to the referencing tuple's - * XMAX to verify that it is actually the descendant version and not an - * unrelated tuple stored into a slot recently freed by VACUUM. If either - * check fails, one may assume that there is no live descendant version. - * - * Following the fixed header fields, the nulls bitmap is stored (beginning - * at t_bits). The bitmap is *not* stored if t_infomask shows that there - * are no nulls in the tuple. If an OID field is present (as indicated by - * t_infomask), then it is stored just before the user data, which begins at - * the offset shown by t_hoff. Note that t_hoff must be a multiple of - * MAXALIGN. - */ - -typedef struct HeapTupleFields -{ - TransactionId t_xmin; /* inserting xact ID */ - TransactionId t_xmax; /* deleting or locking xact ID */ - - union - { - CommandId t_cid; /* inserting or deleting command ID, or both */ - TransactionId t_xvac; /* old-style VACUUM FULL xact ID */ - } t_field3; -} HeapTupleFields; - -typedef struct DatumTupleFields -{ - int32 datum_len_; /* varlena header (do not touch directly!) */ - - int32 datum_typmod; /* -1, or identifier of a record type */ - - Oid datum_typeid; /* composite type OID, or RECORDOID */ - - /* - * Note: field ordering is chosen with thought that Oid might someday - * widen to 64 bits. - */ -} DatumTupleFields; - -typedef struct HeapTupleHeaderData -{ - union - { - HeapTupleFields t_heap; - DatumTupleFields t_datum; - } t_choice; - - ItemPointerData t_ctid; /* current TID of this or newer tuple */ - - /* Fields below here must match MinimalTupleData! */ - - uint16 t_infomask2; /* number of attributes + various flags */ +/* typedefs and forward declarations for structs defined in htup_details.h */ - uint16 t_infomask; /* various flag bits, see below */ - - uint8 t_hoff; /* sizeof header incl. bitmap, padding */ - - /* ^ - 23 bytes - ^ */ - - bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ - - /* MORE DATA FOLLOWS AT END OF STRUCT */ -} HeapTupleHeaderData; +typedef struct HeapTupleHeaderData HeapTupleHeaderData; typedef HeapTupleHeaderData *HeapTupleHeader; -/* - * information stored in t_infomask: - */ -#define HEAP_HASNULL 0x0001 /* has null attribute(s) */ -#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */ -#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */ -#define HEAP_HASOID 0x0008 /* has an object-id field */ -/* bit 0x0010 is available */ -#define HEAP_COMBOCID 0x0020 /* t_cid is a combo cid */ -#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ -#define HEAP_XMAX_SHARED_LOCK 0x0080 /* xmax is shared locker */ -/* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */ -#define HEAP_IS_LOCKED (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_SHARED_LOCK) -#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */ -#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ -#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */ -#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */ -#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId */ -#define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */ -#define HEAP_MOVED_OFF 0x4000 /* moved to another place by pre-9.0 - * VACUUM FULL; kept for binary - * upgrade support */ -#define HEAP_MOVED_IN 0x8000 /* moved from another place by pre-9.0 - * VACUUM FULL; kept for binary - * upgrade support */ -#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) - -#define HEAP_XACT_MASK 0xFFE0 /* visibility-related bits */ - -/* - * information stored in t_infomask2: - */ -#define HEAP_NATTS_MASK 0x07FF /* 11 bits for number of attributes */ -/* bits 0x3800 are available */ -#define HEAP_HOT_UPDATED 0x4000 /* tuple was HOT-updated */ -#define HEAP_ONLY_TUPLE 0x8000 /* this is heap-only tuple */ - -#define HEAP2_XACT_MASK 0xC000 /* visibility-related bits */ - -/* - * HEAP_TUPLE_HAS_MATCH is a temporary flag used during hash joins. It is - * only used in tuples that are in the hash table, and those don't need - * any visibility information, so we can overlay it on a visibility flag - * instead of using up a dedicated bit. - */ -#define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */ - -/* - * HeapTupleHeader accessor macros - * - * Note: beware of multiple evaluations of "tup" argument. But the Set - * macros evaluate their other argument only once. - */ - -#define HeapTupleHeaderGetXmin(tup) \ -( \ - (tup)->t_choice.t_heap.t_xmin \ -) - -#define HeapTupleHeaderSetXmin(tup, xid) \ -( \ - (tup)->t_choice.t_heap.t_xmin = (xid) \ -) - -#define HeapTupleHeaderGetXmax(tup) \ -( \ - (tup)->t_choice.t_heap.t_xmax \ -) - -#define HeapTupleHeaderSetXmax(tup, xid) \ -( \ - (tup)->t_choice.t_heap.t_xmax = (xid) \ -) - -/* - * HeapTupleHeaderGetRawCommandId will give you what's in the header whether - * it is useful or not. Most code should use HeapTupleHeaderGetCmin or - * HeapTupleHeaderGetCmax instead, but note that those Assert that you can - * get a legitimate result, ie you are in the originating transaction! - */ -#define HeapTupleHeaderGetRawCommandId(tup) \ -( \ - (tup)->t_choice.t_heap.t_field3.t_cid \ -) - -/* SetCmin is reasonably simple since we never need a combo CID */ -#define HeapTupleHeaderSetCmin(tup, cid) \ -do { \ - Assert(!((tup)->t_infomask & HEAP_MOVED)); \ - (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ - (tup)->t_infomask &= ~HEAP_COMBOCID; \ -} while (0) - -/* SetCmax must be used after HeapTupleHeaderAdjustCmax; see combocid.c */ -#define HeapTupleHeaderSetCmax(tup, cid, iscombo) \ -do { \ - Assert(!((tup)->t_infomask & HEAP_MOVED)); \ - (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ - if (iscombo) \ - (tup)->t_infomask |= HEAP_COMBOCID; \ - else \ - (tup)->t_infomask &= ~HEAP_COMBOCID; \ -} while (0) - -#define HeapTupleHeaderGetXvac(tup) \ -( \ - ((tup)->t_infomask & HEAP_MOVED) ? \ - (tup)->t_choice.t_heap.t_field3.t_xvac \ - : \ - InvalidTransactionId \ -) - -#define HeapTupleHeaderSetXvac(tup, xid) \ -do { \ - Assert((tup)->t_infomask & HEAP_MOVED); \ - (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \ -} while (0) - -#define HeapTupleHeaderGetDatumLength(tup) \ - VARSIZE(tup) - -#define HeapTupleHeaderSetDatumLength(tup, len) \ - SET_VARSIZE(tup, len) - -#define HeapTupleHeaderGetTypeId(tup) \ -( \ - (tup)->t_choice.t_datum.datum_typeid \ -) - -#define HeapTupleHeaderSetTypeId(tup, typeid) \ -( \ - (tup)->t_choice.t_datum.datum_typeid = (typeid) \ -) - -#define HeapTupleHeaderGetTypMod(tup) \ -( \ - (tup)->t_choice.t_datum.datum_typmod \ -) - -#define HeapTupleHeaderSetTypMod(tup, typmod) \ -( \ - (tup)->t_choice.t_datum.datum_typmod = (typmod) \ -) - -#define HeapTupleHeaderGetOid(tup) \ -( \ - ((tup)->t_infomask & HEAP_HASOID) ? \ - *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ - : \ - InvalidOid \ -) - -#define HeapTupleHeaderSetOid(tup, oid) \ -do { \ - Assert((tup)->t_infomask & HEAP_HASOID); \ - *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \ -} while (0) - -/* - * Note that we stop considering a tuple HOT-updated as soon as it is known - * aborted or the would-be updating transaction is known aborted. For best - * efficiency, check tuple visibility before using this macro, so that the - * INVALID bits will be as up to date as possible. - */ -#define HeapTupleHeaderIsHotUpdated(tup) \ -( \ - ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \ - ((tup)->t_infomask & (HEAP_XMIN_INVALID | HEAP_XMAX_INVALID)) == 0 \ -) - -#define HeapTupleHeaderSetHotUpdated(tup) \ -( \ - (tup)->t_infomask2 |= HEAP_HOT_UPDATED \ -) - -#define HeapTupleHeaderClearHotUpdated(tup) \ -( \ - (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \ -) - -#define HeapTupleHeaderIsHeapOnly(tup) \ -( \ - (tup)->t_infomask2 & HEAP_ONLY_TUPLE \ -) - -#define HeapTupleHeaderSetHeapOnly(tup) \ -( \ - (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \ -) - -#define HeapTupleHeaderClearHeapOnly(tup) \ -( \ - (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \ -) - -#define HeapTupleHeaderHasMatch(tup) \ -( \ - (tup)->t_infomask2 & HEAP_TUPLE_HAS_MATCH \ -) - -#define HeapTupleHeaderSetMatch(tup) \ -( \ - (tup)->t_infomask2 |= HEAP_TUPLE_HAS_MATCH \ -) - -#define HeapTupleHeaderClearMatch(tup) \ -( \ - (tup)->t_infomask2 &= ~HEAP_TUPLE_HAS_MATCH \ -) - -#define HeapTupleHeaderGetNatts(tup) \ - ((tup)->t_infomask2 & HEAP_NATTS_MASK) - -#define HeapTupleHeaderSetNatts(tup, natts) \ -( \ - (tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \ -) - - -/* - * BITMAPLEN(NATTS) - - * Computes size of null bitmap given number of data columns. - */ -#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8) - -/* - * MaxHeapTupleSize is the maximum allowed size of a heap tuple, including - * header and MAXALIGN alignment padding. Basically it's BLCKSZ minus the - * other stuff that has to be on a disk page. Since heap pages use no - * "special space", there's no deduction for that. - * - * NOTE: we allow for the ItemId that must point to the tuple, ensuring that - * an otherwise-empty page can indeed hold a tuple of this size. Because - * ItemIds and tuples have different alignment requirements, don't assume that - * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page. - */ -#define MaxHeapTupleSize (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))) - -/* - * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can - * fit on one heap page. (Note that indexes could have more, because they - * use a smaller tuple header.) We arrive at the divisor because each tuple - * must be maxaligned, and it must have an associated item pointer. - * - * Note: with HOT, there could theoretically be more line pointers (not actual - * tuples) than this on a heap page. However we constrain the number of line - * pointers to this anyway, to avoid excessive line-pointer bloat and not - * require increases in the size of work arrays. - */ -#define MaxHeapTuplesPerPage \ - ((int) ((BLCKSZ - SizeOfPageHeaderData) / \ - (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData)))) - -/* - * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of - * data fields of char(n) and similar types. It need not have anything - * directly to do with the *actual* upper limit of varlena values, which - * is currently 1Gb (see TOAST structures in postgres.h). I've set it - * at 10Mb which seems like a reasonable number --- tgl 8/6/00. - */ -#define MaxAttrSize (10 * 1024 * 1024) - - -/* - * MinimalTuple is an alternative representation that is used for transient - * tuples inside the executor, in places where transaction status information - * is not required, the tuple rowtype is known, and shaving off a few bytes - * is worthwhile because we need to store many tuples. The representation - * is chosen so that tuple access routines can work with either full or - * minimal tuples via a HeapTupleData pointer structure. The access routines - * see no difference, except that they must not access the transaction status - * or t_ctid fields because those aren't there. - * - * For the most part, MinimalTuples should be accessed via TupleTableSlot - * routines. These routines will prevent access to the "system columns" - * and thereby prevent accidental use of the nonexistent fields. - * - * MinimalTupleData contains a length word, some padding, and fields matching - * HeapTupleHeaderData beginning with t_infomask2. The padding is chosen so - * that offsetof(t_infomask2) is the same modulo MAXIMUM_ALIGNOF in both - * structs. This makes data alignment rules equivalent in both cases. - * - * When a minimal tuple is accessed via a HeapTupleData pointer, t_data is - * set to point MINIMAL_TUPLE_OFFSET bytes before the actual start of the - * minimal tuple --- that is, where a full tuple matching the minimal tuple's - * data would start. This trick is what makes the structs seem equivalent. - * - * Note that t_hoff is computed the same as in a full tuple, hence it includes - * the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however. - * - * MINIMAL_TUPLE_DATA_OFFSET is the offset to the first useful (non-pad) data - * other than the length word. tuplesort.c and tuplestore.c use this to avoid - * writing the padding to disk. - */ -#define MINIMAL_TUPLE_OFFSET \ - ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF) -#define MINIMAL_TUPLE_PADDING \ - ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF) -#define MINIMAL_TUPLE_DATA_OFFSET \ - offsetof(MinimalTupleData, t_infomask2) - -typedef struct MinimalTupleData -{ - uint32 t_len; /* actual length of minimal tuple */ - - char mt_padding[MINIMAL_TUPLE_PADDING]; - - /* Fields below here must match HeapTupleHeaderData! */ - - uint16 t_infomask2; /* number of attributes + various flags */ - - uint16 t_infomask; /* various flag bits, see below */ - - uint8 t_hoff; /* sizeof header incl. bitmap, padding */ - - /* ^ - 23 bytes - ^ */ - - bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ - - /* MORE DATA FOLLOWS AT END OF STRUCT */ -} MinimalTupleData; +typedef struct MinimalTupleData MinimalTupleData; typedef MinimalTupleData *MinimalTuple; @@ -505,12 +50,12 @@ typedef MinimalTupleData *MinimalTuple; * This is the output format of heap_form_tuple and related routines. * * * Separately allocated tuple: t_data points to a palloc'd chunk that - * is not adjacent to the HeapTupleData. (This case is deprecated since + * is not adjacent to the HeapTupleData. (This case is deprecated since * it's difficult to tell apart from case #1. It should be used only in * limited contexts where the code knows that case #1 will never apply.) * * * Separately allocated minimal tuple: t_data points MINIMAL_TUPLE_OFFSET - * bytes before the start of a MinimalTuple. As with the previous case, + * bytes before the start of a MinimalTuple. As with the previous case, * this can't be told apart from case #1 by inspection; code setting up * or destroying this representation has to know what it's doing. * @@ -534,11 +79,6 @@ typedef HeapTupleData *HeapTuple; #define HEAPTUPLESIZE MAXALIGN(sizeof(HeapTupleData)) -/* - * GETSTRUCT - given a HeapTuple pointer, return address of the user data - */ -#define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff) - #ifdef XCP /* * Represents a DataRow message received from a remote node. @@ -560,396 +100,13 @@ typedef RemoteDataRowData *RemoteDataRow; */ #define HeapTupleIsValid(tuple) PointerIsValid(tuple) -#define HeapTupleHasNulls(tuple) \ - (((tuple)->t_data->t_infomask & HEAP_HASNULL) != 0) - -#define HeapTupleNoNulls(tuple) \ - (!((tuple)->t_data->t_infomask & HEAP_HASNULL)) - -#define HeapTupleHasVarWidth(tuple) \ - (((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH) != 0) - -#define HeapTupleAllFixed(tuple) \ - (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH)) - -#define HeapTupleHasExternal(tuple) \ - (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) - -#define HeapTupleIsHotUpdated(tuple) \ - HeapTupleHeaderIsHotUpdated((tuple)->t_data) - -#define HeapTupleSetHotUpdated(tuple) \ - HeapTupleHeaderSetHotUpdated((tuple)->t_data) - -#define HeapTupleClearHotUpdated(tuple) \ - HeapTupleHeaderClearHotUpdated((tuple)->t_data) - -#define HeapTupleIsHeapOnly(tuple) \ - HeapTupleHeaderIsHeapOnly((tuple)->t_data) - -#define HeapTupleSetHeapOnly(tuple) \ - HeapTupleHeaderSetHeapOnly((tuple)->t_data) - -#define HeapTupleClearHeapOnly(tuple) \ - HeapTupleHeaderClearHeapOnly((tuple)->t_data) - -#define HeapTupleGetOid(tuple) \ - HeapTupleHeaderGetOid((tuple)->t_data) - -#define HeapTupleSetOid(tuple, oid) \ - HeapTupleHeaderSetOid((tuple)->t_data, (oid)) - - -/* - * WAL record definitions for heapam.c's WAL operations - * - * XLOG allows to store some information in high 4 bits of log - * record xl_info field. We use 3 for opcode and one for init bit. - */ -#define XLOG_HEAP_INSERT 0x00 -#define XLOG_HEAP_DELETE 0x10 -#define XLOG_HEAP_UPDATE 0x20 -/* 0x030 is free, was XLOG_HEAP_MOVE */ -#define XLOG_HEAP_HOT_UPDATE 0x40 -#define XLOG_HEAP_NEWPAGE 0x50 -#define XLOG_HEAP_LOCK 0x60 -#define XLOG_HEAP_INPLACE 0x70 - -#define XLOG_HEAP_OPMASK 0x70 -/* - * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE, - * or MULTI_INSERT, we can (and we do) restore entire page in redo - */ -#define XLOG_HEAP_INIT_PAGE 0x80 -/* - * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes - * are associated with RM_HEAP2_ID, but are not logically different from - * the ones above associated with RM_HEAP_ID. XLOG_HEAP_OPMASK applies to - * these, too. - */ -#define XLOG_HEAP2_FREEZE 0x00 -#define XLOG_HEAP2_CLEAN 0x10 -/* 0x20 is free, was XLOG_HEAP2_CLEAN_MOVE */ -#define XLOG_HEAP2_CLEANUP_INFO 0x30 -#define XLOG_HEAP2_VISIBLE 0x40 -#define XLOG_HEAP2_MULTI_INSERT 0x50 - -/* - * All what we need to find changed tuple - * - * NB: on most machines, sizeof(xl_heaptid) will include some trailing pad - * bytes for alignment. We don't want to store the pad space in the XLOG, - * so use SizeOfHeapTid for space calculations. Similar comments apply for - * the other xl_FOO structs. - */ -typedef struct xl_heaptid -{ - RelFileNode node; - ItemPointerData tid; /* changed tuple id */ -} xl_heaptid; - -#define SizeOfHeapTid (offsetof(xl_heaptid, tid) + SizeOfIptrData) - -/* This is what we need to know about delete */ -typedef struct xl_heap_delete -{ - xl_heaptid target; /* deleted tuple id */ - bool all_visible_cleared; /* PD_ALL_VISIBLE was cleared */ -} xl_heap_delete; - -#define SizeOfHeapDelete (offsetof(xl_heap_delete, all_visible_cleared) + sizeof(bool)) - -/* - * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted - * or updated tuple in WAL; we can save a few bytes by reconstructing the - * fields that are available elsewhere in the WAL record, or perhaps just - * plain needn't be reconstructed. These are the fields we must store. - * NOTE: t_hoff could be recomputed, but we may as well store it because - * it will come for free due to alignment considerations. - */ -typedef struct xl_heap_header -{ - uint16 t_infomask2; - uint16 t_infomask; - uint8 t_hoff; -} xl_heap_header; - -#define SizeOfHeapHeader (offsetof(xl_heap_header, t_hoff) + sizeof(uint8)) - -/* This is what we need to know about insert */ -typedef struct xl_heap_insert -{ - xl_heaptid target; /* inserted tuple id */ - bool all_visible_cleared; /* PD_ALL_VISIBLE was cleared */ - /* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */ -} xl_heap_insert; - -#define SizeOfHeapInsert (offsetof(xl_heap_insert, all_visible_cleared) + sizeof(bool)) - -/* - * This is what we need to know about a multi-insert. The record consists of - * xl_heap_multi_insert header, followed by a xl_multi_insert_tuple and tuple - * data for each tuple. 'offsets' array is omitted if the whole page is - * reinitialized (XLOG_HEAP_INIT_PAGE) - */ -typedef struct xl_heap_multi_insert -{ - RelFileNode node; - BlockNumber blkno; - bool all_visible_cleared; - uint16 ntuples; - OffsetNumber offsets[1]; - - /* TUPLE DATA (xl_multi_insert_tuples) FOLLOW AT END OF STRUCT */ -} xl_heap_multi_insert; - -#define SizeOfHeapMultiInsert offsetof(xl_heap_multi_insert, offsets) - -typedef struct xl_multi_insert_tuple -{ - uint16 datalen; /* size of tuple data that follows */ - uint16 t_infomask2; - uint16 t_infomask; - uint8 t_hoff; - /* TUPLE DATA FOLLOWS AT END OF STRUCT */ -} xl_multi_insert_tuple; - -#define SizeOfMultiInsertTuple (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8)) - -/* This is what we need to know about update|hot_update */ -typedef struct xl_heap_update -{ - xl_heaptid target; /* deleted tuple id */ - ItemPointerData newtid; /* new inserted tuple id */ - bool all_visible_cleared; /* PD_ALL_VISIBLE was cleared */ - bool new_all_visible_cleared; /* same for the page of newtid */ - /* NEW TUPLE xl_heap_header AND TUPLE DATA FOLLOWS AT END OF STRUCT */ -} xl_heap_update; - -#define SizeOfHeapUpdate (offsetof(xl_heap_update, new_all_visible_cleared) + sizeof(bool)) - -/* - * This is what we need to know about vacuum page cleanup/redirect - * - * The array of OffsetNumbers following the fixed part of the record contains: - * * for each redirected item: the item offset, then the offset redirected to - * * for each now-dead item: the item offset - * * for each now-unused item: the item offset - * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused. - * Note that nunused is not explicitly stored, but may be found by reference - * to the total record length. - */ -typedef struct xl_heap_clean -{ - RelFileNode node; - BlockNumber block; - TransactionId latestRemovedXid; - uint16 nredirected; - uint16 ndead; - /* OFFSET NUMBERS FOLLOW */ -} xl_heap_clean; - -#define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16)) - -/* - * Cleanup_info is required in some cases during a lazy VACUUM. - * Used for reporting the results of HeapTupleHeaderAdvanceLatestRemovedXid() - * see vacuumlazy.c for full explanation - */ -typedef struct xl_heap_cleanup_info -{ - RelFileNode node; - TransactionId latestRemovedXid; -} xl_heap_cleanup_info; - -#define SizeOfHeapCleanupInfo (sizeof(xl_heap_cleanup_info)) - -/* This is for replacing a page's contents in toto */ -/* NB: this is used for indexes as well as heaps */ -typedef struct xl_heap_newpage -{ - RelFileNode node; - ForkNumber forknum; - BlockNumber blkno; /* location of new page */ - /* entire page contents follow at end of record */ -} xl_heap_newpage; - -#define SizeOfHeapNewpage (offsetof(xl_heap_newpage, blkno) + sizeof(BlockNumber)) - -/* This is what we need to know about lock */ -typedef struct xl_heap_lock -{ - xl_heaptid target; /* locked tuple id */ - TransactionId locking_xid; /* might be a MultiXactId not xid */ - bool xid_is_mxact; /* is it? */ - bool shared_lock; /* shared or exclusive row lock? */ -} xl_heap_lock; - -#define SizeOfHeapLock (offsetof(xl_heap_lock, shared_lock) + sizeof(bool)) - -/* This is what we need to know about in-place update */ -typedef struct xl_heap_inplace -{ - xl_heaptid target; /* updated tuple id */ - /* TUPLE DATA FOLLOWS AT END OF STRUCT */ -} xl_heap_inplace; - -#define SizeOfHeapInplace (offsetof(xl_heap_inplace, target) + SizeOfHeapTid) - -/* This is what we need to know about tuple freezing during vacuum */ -typedef struct xl_heap_freeze -{ - RelFileNode node; - BlockNumber block; - TransactionId cutoff_xid; - /* TUPLE OFFSET NUMBERS FOLLOW AT THE END */ -} xl_heap_freeze; - -#define SizeOfHeapFreeze (offsetof(xl_heap_freeze, cutoff_xid) + sizeof(TransactionId)) - -/* This is what we need to know about setting a visibility map bit */ -typedef struct xl_heap_visible -{ - RelFileNode node; - BlockNumber block; - TransactionId cutoff_xid; -} xl_heap_visible; - -#define SizeOfHeapVisible (offsetof(xl_heap_visible, cutoff_xid) + sizeof(TransactionId)) - -extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple, - TransactionId *latestRemovedXid); - /* HeapTupleHeader functions implemented in utils/time/combocid.c */ extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup); extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup); extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup, - CommandId *cmax, - bool *iscombo); - -/* ---------------- - * fastgetattr - * - * Fetch a user attribute's value as a Datum (might be either a - * value, or a pointer into the data area of the tuple). - * - * This must not be used when a system attribute might be requested. - * Furthermore, the passed attnum MUST be valid. Use heap_getattr() - * instead, if in doubt. - * - * This gets called many times, so we macro the cacheable and NULL - * lookups, and call nocachegetattr() for the rest. - * ---------------- - */ - -#if !defined(DISABLE_COMPLEX_MACRO) - -#define fastgetattr(tup, attnum, tupleDesc, isnull) \ -( \ - AssertMacro((attnum) > 0), \ - (*(isnull) = false), \ - HeapTupleNoNulls(tup) ? \ - ( \ - (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \ - ( \ - fetchatt((tupleDesc)->attrs[(attnum)-1], \ - (char *) (tup)->t_data + (tup)->t_data->t_hoff + \ - (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \ - ) \ - : \ - nocachegetattr((tup), (attnum), (tupleDesc)) \ - ) \ - : \ - ( \ - att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \ - ( \ - (*(isnull) = true), \ - (Datum)NULL \ - ) \ - : \ - ( \ - nocachegetattr((tup), (attnum), (tupleDesc)) \ - ) \ - ) \ -) -#else /* defined(DISABLE_COMPLEX_MACRO) */ - -extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, - bool *isnull); -#endif /* defined(DISABLE_COMPLEX_MACRO) */ - - -/* ---------------- - * heap_getattr - * - * Extract an attribute of a heap tuple and return it as a Datum. - * This works for either system or user attributes. The given attnum - * is properly range-checked. - * - * If the field in question has a NULL value, we return a zero Datum - * and set *isnull == true. Otherwise, we set *isnull == false. - * - * <tup> is the pointer to the heap tuple. <attnum> is the attribute - * number of the column (field) caller wants. <tupleDesc> is a - * pointer to the structure describing the row and all its fields. - * ---------------- - */ -#define heap_getattr(tup, attnum, tupleDesc, isnull) \ - ( \ - ((attnum) > 0) ? \ - ( \ - ((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \ - ( \ - (*(isnull) = true), \ - (Datum)NULL \ - ) \ - : \ - fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \ - ) \ - : \ - heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \ - ) - -/* prototypes for functions in common/heaptuple.c */ -extern Size heap_compute_data_size(TupleDesc tupleDesc, - Datum *values, bool *isnull); -extern void heap_fill_tuple(TupleDesc tupleDesc, - Datum *values, bool *isnull, - char *data, Size data_size, - uint16 *infomask, bits8 *bit); -extern bool heap_attisnull(HeapTuple tup, int attnum); -extern Datum nocachegetattr(HeapTuple tup, int attnum, - TupleDesc att); -extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, - bool *isnull); -extern HeapTuple heap_copytuple(HeapTuple tuple); -extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest); -extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, - Datum *values, bool *isnull); -extern HeapTuple heap_modify_tuple(HeapTuple tuple, - TupleDesc tupleDesc, - Datum *replValues, - bool *replIsnull, - bool *doReplace); -extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, - Datum *values, bool *isnull); + CommandId *cmax, bool *iscombo); -/* these three are deprecated versions of the three above: */ -extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor, - Datum *values, char *nulls); -extern HeapTuple heap_modifytuple(HeapTuple tuple, - TupleDesc tupleDesc, - Datum *replValues, - char *replNulls, - char *replActions); -extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc, - Datum *values, char *nulls); -extern void heap_freetuple(HeapTuple htup); -extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, - Datum *values, bool *isnull); -extern void heap_free_minimal_tuple(MinimalTuple mtup); -extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup); -extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup); -extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup); +/* Prototype for HeapTupleHeader accessors in heapam.c */ +extern TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple); #endif /* HTUP_H */ diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h new file mode 100644 index 0000000000..294d21bd18 --- /dev/null +++ b/src/include/access/htup_details.h @@ -0,0 +1,765 @@ +/*------------------------------------------------------------------------- + * + * htup_details.h + * POSTGRES heap tuple header definitions. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/htup_details.h + * + *------------------------------------------------------------------------- + */ +#ifndef HTUP_DETAILS_H +#define HTUP_DETAILS_H + +#include "access/htup.h" +#include "access/tupdesc.h" +#include "access/tupmacs.h" +#include "access/transam.h" +#include "storage/bufpage.h" + +/* + * MaxTupleAttributeNumber limits the number of (user) columns in a tuple. + * The key limit on this value is that the size of the fixed overhead for + * a tuple, plus the size of the null-values bitmap (at 1 bit per column), + * plus MAXALIGN alignment, must fit into t_hoff which is uint8. On most + * machines the upper limit without making t_hoff wider would be a little + * over 1700. We use round numbers here and for MaxHeapAttributeNumber + * so that alterations in HeapTupleHeaderData layout won't change the + * supported max number of columns. + */ +#define MaxTupleAttributeNumber 1664 /* 8 * 208 */ + +/* + * MaxHeapAttributeNumber limits the number of (user) columns in a table. + * This should be somewhat less than MaxTupleAttributeNumber. It must be + * at least one less, else we will fail to do UPDATEs on a maximal-width + * table (because UPDATE has to form working tuples that include CTID). + * In practice we want some additional daylight so that we can gracefully + * support operations that add hidden "resjunk" columns, for example + * SELECT * FROM wide_table ORDER BY foo, bar, baz. + * In any case, depending on column data types you will likely be running + * into the disk-block-based limit on overall tuple size if you have more + * than a thousand or so columns. TOAST won't help. + */ +#define MaxHeapAttributeNumber 1600 /* 8 * 200 */ + +/* + * Heap tuple header. To avoid wasting space, the fields should be + * laid out in such a way as to avoid structure padding. + * + * Datums of composite types (row types) share the same general structure + * as on-disk tuples, so that the same routines can be used to build and + * examine them. However the requirements are slightly different: a Datum + * does not need any transaction visibility information, and it does need + * a length word and some embedded type information. We can achieve this + * by overlaying the xmin/cmin/xmax/cmax/xvac fields of a heap tuple + * with the fields needed in the Datum case. Typically, all tuples built + * in-memory will be initialized with the Datum fields; but when a tuple is + * about to be inserted in a table, the transaction fields will be filled, + * overwriting the datum fields. + * + * The overall structure of a heap tuple looks like: + * fixed fields (HeapTupleHeaderData struct) + * nulls bitmap (if HEAP_HASNULL is set in t_infomask) + * alignment padding (as needed to make user data MAXALIGN'd) + * object ID (if HEAP_HASOID is set in t_infomask) + * user data fields + * + * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three + * physical fields. Xmin and Xmax are always really stored, but Cmin, Cmax + * and Xvac share a field. This works because we know that Cmin and Cmax + * are only interesting for the lifetime of the inserting and deleting + * transaction respectively. If a tuple is inserted and deleted in the same + * transaction, we store a "combo" command id that can be mapped to the real + * cmin and cmax, but only by use of local state within the originating + * backend. See combocid.c for more details. Meanwhile, Xvac is only set by + * old-style VACUUM FULL, which does not have any command sub-structure and so + * does not need either Cmin or Cmax. (This requires that old-style VACUUM + * FULL never try to move a tuple whose Cmin or Cmax is still interesting, + * ie, an insert-in-progress or delete-in-progress tuple.) + * + * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid + * is initialized with its own TID (location). If the tuple is ever updated, + * its t_ctid is changed to point to the replacement version of the tuple. + * Thus, a tuple is the latest version of its row iff XMAX is invalid or + * t_ctid points to itself (in which case, if XMAX is valid, the tuple is + * either locked or deleted). One can follow the chain of t_ctid links + * to find the newest version of the row. Beware however that VACUUM might + * erase the pointed-to (newer) tuple before erasing the pointing (older) + * tuple. Hence, when following a t_ctid link, it is necessary to check + * to see if the referenced slot is empty or contains an unrelated tuple. + * Check that the referenced tuple has XMIN equal to the referencing tuple's + * XMAX to verify that it is actually the descendant version and not an + * unrelated tuple stored into a slot recently freed by VACUUM. If either + * check fails, one may assume that there is no live descendant version. + * + * Following the fixed header fields, the nulls bitmap is stored (beginning + * at t_bits). The bitmap is *not* stored if t_infomask shows that there + * are no nulls in the tuple. If an OID field is present (as indicated by + * t_infomask), then it is stored just before the user data, which begins at + * the offset shown by t_hoff. Note that t_hoff must be a multiple of + * MAXALIGN. + */ + +typedef struct HeapTupleFields +{ + TransactionId t_xmin; /* inserting xact ID */ + TransactionId t_xmax; /* deleting or locking xact ID */ + + union + { + CommandId t_cid; /* inserting or deleting command ID, or both */ + TransactionId t_xvac; /* old-style VACUUM FULL xact ID */ + } t_field3; +} HeapTupleFields; + +typedef struct DatumTupleFields +{ + int32 datum_len_; /* varlena header (do not touch directly!) */ + + int32 datum_typmod; /* -1, or identifier of a record type */ + + Oid datum_typeid; /* composite type OID, or RECORDOID */ + + /* + * Note: field ordering is chosen with thought that Oid might someday + * widen to 64 bits. + */ +} DatumTupleFields; + +struct HeapTupleHeaderData +{ + union + { + HeapTupleFields t_heap; + DatumTupleFields t_datum; + } t_choice; + + ItemPointerData t_ctid; /* current TID of this or newer tuple */ + + /* Fields below here must match MinimalTupleData! */ + + uint16 t_infomask2; /* number of attributes + various flags */ + + uint16 t_infomask; /* various flag bits, see below */ + + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ + + /* ^ - 23 bytes - ^ */ + + bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ + + /* MORE DATA FOLLOWS AT END OF STRUCT */ +}; + +/* typedef appears in tupbasics.h */ + +/* + * information stored in t_infomask: + */ +#define HEAP_HASNULL 0x0001 /* has null attribute(s) */ +#define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */ +#define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */ +#define HEAP_HASOID 0x0008 /* has an object-id field */ +#define HEAP_XMAX_KEYSHR_LOCK 0x0010 /* xmax is a key-shared locker */ +#define HEAP_COMBOCID 0x0020 /* t_cid is a combo cid */ +#define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ +#define HEAP_XMAX_LOCK_ONLY 0x0080 /* xmax, if valid, is only a locker */ + + /* xmax is a shared locker */ +#define HEAP_XMAX_SHR_LOCK (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK) + +#define HEAP_LOCK_MASK (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \ + HEAP_XMAX_KEYSHR_LOCK) +#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed */ +#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ +#define HEAP_XMIN_FROZEN (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID) +#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */ +#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */ +#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId */ +#define HEAP_UPDATED 0x2000 /* this is UPDATEd version of row */ +#define HEAP_MOVED_OFF 0x4000 /* moved to another place by pre-9.0 + * VACUUM FULL; kept for binary + * upgrade support */ +#define HEAP_MOVED_IN 0x8000 /* moved from another place by pre-9.0 + * VACUUM FULL; kept for binary + * upgrade support */ +#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) + +#define HEAP_XACT_MASK 0xFFF0 /* visibility-related bits */ + +/* + * A tuple is only locked (i.e. not updated by its Xmax) if the + * HEAP_XMAX_LOCK_ONLY bit is set; or, for pg_upgrade's sake, if the Xmax is + * not a multi and the EXCL_LOCK bit is set. + * + * See also HeapTupleHeaderIsOnlyLocked, which also checks for a possible + * aborted updater transaction. + * + * Beware of multiple evaluations of the argument. + */ +#define HEAP_XMAX_IS_LOCKED_ONLY(infomask) \ + (((infomask) & HEAP_XMAX_LOCK_ONLY) || \ + (((infomask) & (HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK)) == HEAP_XMAX_EXCL_LOCK)) + +/* + * Use these to test whether a particular lock is applied to a tuple + */ +#define HEAP_XMAX_IS_SHR_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_SHR_LOCK) +#define HEAP_XMAX_IS_EXCL_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_EXCL_LOCK) +#define HEAP_XMAX_IS_KEYSHR_LOCKED(infomask) \ + (((infomask) & HEAP_LOCK_MASK) == HEAP_XMAX_KEYSHR_LOCK) + +/* turn these all off when Xmax is to change */ +#define HEAP_XMAX_BITS (HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | \ + HEAP_XMAX_IS_MULTI | HEAP_LOCK_MASK | HEAP_XMAX_LOCK_ONLY) + +/* + * information stored in t_infomask2: + */ +#define HEAP_NATTS_MASK 0x07FF /* 11 bits for number of attributes */ +/* bits 0x1800 are available */ +#define HEAP_KEYS_UPDATED 0x2000 /* tuple was updated and key cols + * modified, or tuple deleted */ +#define HEAP_HOT_UPDATED 0x4000 /* tuple was HOT-updated */ +#define HEAP_ONLY_TUPLE 0x8000 /* this is heap-only tuple */ + +#define HEAP2_XACT_MASK 0xE000 /* visibility-related bits */ + +/* + * HEAP_TUPLE_HAS_MATCH is a temporary flag used during hash joins. It is + * only used in tuples that are in the hash table, and those don't need + * any visibility information, so we can overlay it on a visibility flag + * instead of using up a dedicated bit. + */ +#define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */ + +/* + * HeapTupleHeader accessor macros + * + * Note: beware of multiple evaluations of "tup" argument. But the Set + * macros evaluate their other argument only once. + */ + +/* + * HeapTupleHeaderGetRawXmin returns the "raw" xmin field, which is the xid + * originally used to insert the tuple. However, the tuple might actually + * be frozen (via HeapTupleHeaderSetXminFrozen) in which case the tuple's xmin + * is visible to every snapshot. Prior to PostgreSQL 9.4, we actually changed + * the xmin to FrozenTransactionId, and that value may still be encountered + * on disk. + */ +#define HeapTupleHeaderGetRawXmin(tup) \ +( \ + (tup)->t_choice.t_heap.t_xmin \ +) + +#define HeapTupleHeaderGetXmin(tup) \ +( \ + HeapTupleHeaderXminFrozen(tup) ? \ + FrozenTransactionId : HeapTupleHeaderGetRawXmin(tup) \ +) + +#define HeapTupleHeaderSetXmin(tup, xid) \ +( \ + (tup)->t_choice.t_heap.t_xmin = (xid) \ +) + +#define HeapTupleHeaderXminCommitted(tup) \ +( \ + (tup)->t_infomask & HEAP_XMIN_COMMITTED \ +) + +#define HeapTupleHeaderXminInvalid(tup) \ +( \ + ((tup)->t_infomask & (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)) == \ + HEAP_XMIN_INVALID \ +) + +#define HeapTupleHeaderXminFrozen(tup) \ +( \ + ((tup)->t_infomask & (HEAP_XMIN_FROZEN)) == HEAP_XMIN_FROZEN \ +) + +#define HeapTupleHeaderSetXminCommitted(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_COMMITTED) \ +) + +#define HeapTupleHeaderSetXminInvalid(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminCommitted(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_INVALID) \ +) + +#define HeapTupleHeaderSetXminFrozen(tup) \ +( \ + AssertMacro(!HeapTupleHeaderXminInvalid(tup)), \ + ((tup)->t_infomask |= HEAP_XMIN_FROZEN) \ +) + +/* + * HeapTupleHeaderGetRawXmax gets you the raw Xmax field. To find out the Xid + * that updated a tuple, you might need to resolve the MultiXactId if certain + * bits are set. HeapTupleHeaderGetUpdateXid checks those bits and takes care + * to resolve the MultiXactId if necessary. This might involve multixact I/O, + * so it should only be used if absolutely necessary. + */ +#define HeapTupleHeaderGetUpdateXid(tup) \ +( \ + (!((tup)->t_infomask & HEAP_XMAX_INVALID) && \ + ((tup)->t_infomask & HEAP_XMAX_IS_MULTI) && \ + !((tup)->t_infomask & HEAP_XMAX_LOCK_ONLY)) ? \ + HeapTupleGetUpdateXid(tup) \ + : \ + HeapTupleHeaderGetRawXmax(tup) \ +) + +#define HeapTupleHeaderGetRawXmax(tup) \ +( \ + (tup)->t_choice.t_heap.t_xmax \ +) + +#define HeapTupleHeaderSetXmax(tup, xid) \ +( \ + (tup)->t_choice.t_heap.t_xmax = (xid) \ +) + +/* + * HeapTupleHeaderGetRawCommandId will give you what's in the header whether + * it is useful or not. Most code should use HeapTupleHeaderGetCmin or + * HeapTupleHeaderGetCmax instead, but note that those Assert that you can + * get a legitimate result, ie you are in the originating transaction! + */ +#define HeapTupleHeaderGetRawCommandId(tup) \ +( \ + (tup)->t_choice.t_heap.t_field3.t_cid \ +) + +/* SetCmin is reasonably simple since we never need a combo CID */ +#define HeapTupleHeaderSetCmin(tup, cid) \ +do { \ + Assert(!((tup)->t_infomask & HEAP_MOVED)); \ + (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ + (tup)->t_infomask &= ~HEAP_COMBOCID; \ +} while (0) + +/* SetCmax must be used after HeapTupleHeaderAdjustCmax; see combocid.c */ +#define HeapTupleHeaderSetCmax(tup, cid, iscombo) \ +do { \ + Assert(!((tup)->t_infomask & HEAP_MOVED)); \ + (tup)->t_choice.t_heap.t_field3.t_cid = (cid); \ + if (iscombo) \ + (tup)->t_infomask |= HEAP_COMBOCID; \ + else \ + (tup)->t_infomask &= ~HEAP_COMBOCID; \ +} while (0) + +#define HeapTupleHeaderGetXvac(tup) \ +( \ + ((tup)->t_infomask & HEAP_MOVED) ? \ + (tup)->t_choice.t_heap.t_field3.t_xvac \ + : \ + InvalidTransactionId \ +) + +#define HeapTupleHeaderSetXvac(tup, xid) \ +do { \ + Assert((tup)->t_infomask & HEAP_MOVED); \ + (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \ +} while (0) + +#define HeapTupleHeaderGetDatumLength(tup) \ + VARSIZE(tup) + +#define HeapTupleHeaderSetDatumLength(tup, len) \ + SET_VARSIZE(tup, len) + +#define HeapTupleHeaderGetTypeId(tup) \ +( \ + (tup)->t_choice.t_datum.datum_typeid \ +) + +#define HeapTupleHeaderSetTypeId(tup, typeid) \ +( \ + (tup)->t_choice.t_datum.datum_typeid = (typeid) \ +) + +#define HeapTupleHeaderGetTypMod(tup) \ +( \ + (tup)->t_choice.t_datum.datum_typmod \ +) + +#define HeapTupleHeaderSetTypMod(tup, typmod) \ +( \ + (tup)->t_choice.t_datum.datum_typmod = (typmod) \ +) + +#define HeapTupleHeaderGetOid(tup) \ +( \ + ((tup)->t_infomask & HEAP_HASOID) ? \ + *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ + : \ + InvalidOid \ +) + +#define HeapTupleHeaderSetOid(tup, oid) \ +do { \ + Assert((tup)->t_infomask & HEAP_HASOID); \ + *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \ +} while (0) + +/* + * Note that we stop considering a tuple HOT-updated as soon as it is known + * aborted or the would-be updating transaction is known aborted. For best + * efficiency, check tuple visibility before using this macro, so that the + * INVALID bits will be as up to date as possible. + */ +#define HeapTupleHeaderIsHotUpdated(tup) \ +( \ + ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \ + ((tup)->t_infomask & HEAP_XMAX_INVALID) == 0 && \ + !HeapTupleHeaderXminInvalid(tup) \ +) + +#define HeapTupleHeaderSetHotUpdated(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderClearHotUpdated(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderIsHeapOnly(tup) \ +( \ + (tup)->t_infomask2 & HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderSetHeapOnly(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderClearHeapOnly(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderHasMatch(tup) \ +( \ + (tup)->t_infomask2 & HEAP_TUPLE_HAS_MATCH \ +) + +#define HeapTupleHeaderSetMatch(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_TUPLE_HAS_MATCH \ +) + +#define HeapTupleHeaderClearMatch(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_TUPLE_HAS_MATCH \ +) + +#define HeapTupleHeaderGetNatts(tup) \ + ((tup)->t_infomask2 & HEAP_NATTS_MASK) + +#define HeapTupleHeaderSetNatts(tup, natts) \ +( \ + (tup)->t_infomask2 = ((tup)->t_infomask2 & ~HEAP_NATTS_MASK) | (natts) \ +) + +#define HeapTupleHeaderHasExternal(tup) \ + (((tup)->t_infomask & HEAP_HASEXTERNAL) != 0) + + +/* + * BITMAPLEN(NATTS) - + * Computes size of null bitmap given number of data columns. + */ +#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8) + +/* + * MaxHeapTupleSize is the maximum allowed size of a heap tuple, including + * header and MAXALIGN alignment padding. Basically it's BLCKSZ minus the + * other stuff that has to be on a disk page. Since heap pages use no + * "special space", there's no deduction for that. + * + * NOTE: we allow for the ItemId that must point to the tuple, ensuring that + * an otherwise-empty page can indeed hold a tuple of this size. Because + * ItemIds and tuples have different alignment requirements, don't assume that + * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page. + */ +#define MaxHeapTupleSize (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))) + +/* + * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can + * fit on one heap page. (Note that indexes could have more, because they + * use a smaller tuple header.) We arrive at the divisor because each tuple + * must be maxaligned, and it must have an associated item pointer. + * + * Note: with HOT, there could theoretically be more line pointers (not actual + * tuples) than this on a heap page. However we constrain the number of line + * pointers to this anyway, to avoid excessive line-pointer bloat and not + * require increases in the size of work arrays. + */ +#define MaxHeapTuplesPerPage \ + ((int) ((BLCKSZ - SizeOfPageHeaderData) / \ + (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData)))) + +/* + * MaxAttrSize is a somewhat arbitrary upper limit on the declared size of + * data fields of char(n) and similar types. It need not have anything + * directly to do with the *actual* upper limit of varlena values, which + * is currently 1Gb (see TOAST structures in postgres.h). I've set it + * at 10Mb which seems like a reasonable number --- tgl 8/6/00. + */ +#define MaxAttrSize (10 * 1024 * 1024) + + +/* + * MinimalTuple is an alternative representation that is used for transient + * tuples inside the executor, in places where transaction status information + * is not required, the tuple rowtype is known, and shaving off a few bytes + * is worthwhile because we need to store many tuples. The representation + * is chosen so that tuple access routines can work with either full or + * minimal tuples via a HeapTupleData pointer structure. The access routines + * see no difference, except that they must not access the transaction status + * or t_ctid fields because those aren't there. + * + * For the most part, MinimalTuples should be accessed via TupleTableSlot + * routines. These routines will prevent access to the "system columns" + * and thereby prevent accidental use of the nonexistent fields. + * + * MinimalTupleData contains a length word, some padding, and fields matching + * HeapTupleHeaderData beginning with t_infomask2. The padding is chosen so + * that offsetof(t_infomask2) is the same modulo MAXIMUM_ALIGNOF in both + * structs. This makes data alignment rules equivalent in both cases. + * + * When a minimal tuple is accessed via a HeapTupleData pointer, t_data is + * set to point MINIMAL_TUPLE_OFFSET bytes before the actual start of the + * minimal tuple --- that is, where a full tuple matching the minimal tuple's + * data would start. This trick is what makes the structs seem equivalent. + * + * Note that t_hoff is computed the same as in a full tuple, hence it includes + * the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however. + * + * MINIMAL_TUPLE_DATA_OFFSET is the offset to the first useful (non-pad) data + * other than the length word. tuplesort.c and tuplestore.c use this to avoid + * writing the padding to disk. + */ +#define MINIMAL_TUPLE_OFFSET \ + ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF) +#define MINIMAL_TUPLE_PADDING \ + ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF) +#define MINIMAL_TUPLE_DATA_OFFSET \ + offsetof(MinimalTupleData, t_infomask2) + +struct MinimalTupleData +{ + uint32 t_len; /* actual length of minimal tuple */ + + char mt_padding[MINIMAL_TUPLE_PADDING]; + + /* Fields below here must match HeapTupleHeaderData! */ + + uint16 t_infomask2; /* number of attributes + various flags */ + + uint16 t_infomask; /* various flag bits, see below */ + + uint8 t_hoff; /* sizeof header incl. bitmap, padding */ + + /* ^ - 23 bytes - ^ */ + + bits8 t_bits[1]; /* bitmap of NULLs -- VARIABLE LENGTH */ + + /* MORE DATA FOLLOWS AT END OF STRUCT */ +}; + +/* typedef appears in htup.h */ + + +/* + * GETSTRUCT - given a HeapTuple pointer, return address of the user data + */ +#define GETSTRUCT(TUP) ((char *) ((TUP)->t_data) + (TUP)->t_data->t_hoff) + +/* + * Accessor macros to be used with HeapTuple pointers. + */ + +#define HeapTupleHasNulls(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASNULL) != 0) + +#define HeapTupleNoNulls(tuple) \ + (!((tuple)->t_data->t_infomask & HEAP_HASNULL)) + +#define HeapTupleHasVarWidth(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH) != 0) + +#define HeapTupleAllFixed(tuple) \ + (!((tuple)->t_data->t_infomask & HEAP_HASVARWIDTH)) + +#define HeapTupleHasExternal(tuple) \ + (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) + +#define HeapTupleIsHotUpdated(tuple) \ + HeapTupleHeaderIsHotUpdated((tuple)->t_data) + +#define HeapTupleSetHotUpdated(tuple) \ + HeapTupleHeaderSetHotUpdated((tuple)->t_data) + +#define HeapTupleClearHotUpdated(tuple) \ + HeapTupleHeaderClearHotUpdated((tuple)->t_data) + +#define HeapTupleIsHeapOnly(tuple) \ + HeapTupleHeaderIsHeapOnly((tuple)->t_data) + +#define HeapTupleSetHeapOnly(tuple) \ + HeapTupleHeaderSetHeapOnly((tuple)->t_data) + +#define HeapTupleClearHeapOnly(tuple) \ + HeapTupleHeaderClearHeapOnly((tuple)->t_data) + +#define HeapTupleGetOid(tuple) \ + HeapTupleHeaderGetOid((tuple)->t_data) + +#define HeapTupleSetOid(tuple, oid) \ + HeapTupleHeaderSetOid((tuple)->t_data, (oid)) + + +/* ---------------- + * fastgetattr + * + * Fetch a user attribute's value as a Datum (might be either a + * value, or a pointer into the data area of the tuple). + * + * This must not be used when a system attribute might be requested. + * Furthermore, the passed attnum MUST be valid. Use heap_getattr() + * instead, if in doubt. + * + * This gets called many times, so we macro the cacheable and NULL + * lookups, and call nocachegetattr() for the rest. + * ---------------- + */ + +#if !defined(DISABLE_COMPLEX_MACRO) + +#define fastgetattr(tup, attnum, tupleDesc, isnull) \ +( \ + AssertMacro((attnum) > 0), \ + (*(isnull) = false), \ + HeapTupleNoNulls(tup) ? \ + ( \ + (tupleDesc)->attrs[(attnum)-1]->attcacheoff >= 0 ? \ + ( \ + fetchatt((tupleDesc)->attrs[(attnum)-1], \ + (char *) (tup)->t_data + (tup)->t_data->t_hoff + \ + (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \ + ) \ + : \ + nocachegetattr((tup), (attnum), (tupleDesc)) \ + ) \ + : \ + ( \ + att_isnull((attnum)-1, (tup)->t_data->t_bits) ? \ + ( \ + (*(isnull) = true), \ + (Datum)NULL \ + ) \ + : \ + ( \ + nocachegetattr((tup), (attnum), (tupleDesc)) \ + ) \ + ) \ +) +#else /* defined(DISABLE_COMPLEX_MACRO) */ + +extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, + bool *isnull); +#endif /* defined(DISABLE_COMPLEX_MACRO) */ + + +/* ---------------- + * heap_getattr + * + * Extract an attribute of a heap tuple and return it as a Datum. + * This works for either system or user attributes. The given attnum + * is properly range-checked. + * + * If the field in question has a NULL value, we return a zero Datum + * and set *isnull == true. Otherwise, we set *isnull == false. + * + * <tup> is the pointer to the heap tuple. <attnum> is the attribute + * number of the column (field) caller wants. <tupleDesc> is a + * pointer to the structure describing the row and all its fields. + * ---------------- + */ +#define heap_getattr(tup, attnum, tupleDesc, isnull) \ + ( \ + ((attnum) > 0) ? \ + ( \ + ((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \ + ( \ + (*(isnull) = true), \ + (Datum)NULL \ + ) \ + : \ + fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \ + ) \ + : \ + heap_getsysattr((tup), (attnum), (tupleDesc), (isnull)) \ + ) + + +/* prototypes for functions in common/heaptuple.c */ +extern Size heap_compute_data_size(TupleDesc tupleDesc, + Datum *values, bool *isnull); +extern void heap_fill_tuple(TupleDesc tupleDesc, + Datum *values, bool *isnull, + char *data, Size data_size, + uint16 *infomask, bits8 *bit); +extern bool heap_attisnull(HeapTuple tup, int attnum); +extern Datum nocachegetattr(HeapTuple tup, int attnum, + TupleDesc att); +extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, + bool *isnull); +extern HeapTuple heap_copytuple(HeapTuple tuple); +extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest); +extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc); +extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern HeapTuple heap_modify_tuple(HeapTuple tuple, + TupleDesc tupleDesc, + Datum *replValues, + bool *replIsnull, + bool *doReplace); +extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, + Datum *values, bool *isnull); + +/* these three are deprecated versions of the three above: */ +extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor, + Datum *values, char *nulls); +extern HeapTuple heap_modifytuple(HeapTuple tuple, + TupleDesc tupleDesc, + Datum *replValues, + char *replNulls, + char *replActions); +extern void heap_deformtuple(HeapTuple tuple, TupleDesc tupleDesc, + Datum *values, char *nulls); +extern void heap_freetuple(HeapTuple htup); +extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, + Datum *values, bool *isnull); +extern void heap_free_minimal_tuple(MinimalTuple mtup); +extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup); +extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup); +extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup); + +#endif /* HTUP_DETAILS_H */ diff --git a/src/include/access/itup.h b/src/include/access/itup.h index 2f04b871a4..de17936b10 100644 --- a/src/include/access/itup.h +++ b/src/include/access/itup.h @@ -4,7 +4,7 @@ * POSTGRES index tuple definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/itup.h @@ -22,7 +22,7 @@ /* * Index tuple header structure * - * All index tuples start with IndexTupleData. If the HasNulls bit is set, + * All index tuples start with IndexTupleData. If the HasNulls bit is set, * this is followed by an IndexAttributeBitMapData. The index attribute * values follow, beginning at a MAXALIGN boundary. * diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h index e20573d01f..80c70748cf 100644 --- a/src/include/access/multixact.h +++ b/src/include/access/multixact.h @@ -3,7 +3,7 @@ * * PostgreSQL multi-transaction-log manager * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/multixact.h @@ -13,15 +13,55 @@ #include "access/xlog.h" + +/* + * The first two MultiXactId values are reserved to store the truncation Xid + * and epoch of the first segment, so we start assigning multixact values from + * 2. + */ #define InvalidMultiXactId ((MultiXactId) 0) #define FirstMultiXactId ((MultiXactId) 1) +#define MaxMultiXactId ((MultiXactId) 0xFFFFFFFF) #define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId) +#define MaxMultiXactOffset ((MultiXactOffset) 0xFFFFFFFF) + /* Number of SLRU buffers to use for multixact */ #define NUM_MXACTOFFSET_BUFFERS 8 #define NUM_MXACTMEMBER_BUFFERS 16 +/* + * Possible multixact lock modes ("status"). The first four modes are for + * tuple locks (FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE); the + * next two are used for update and delete modes. + */ +typedef enum +{ + MultiXactStatusForKeyShare = 0x00, + MultiXactStatusForShare = 0x01, + MultiXactStatusForNoKeyUpdate = 0x02, + MultiXactStatusForUpdate = 0x03, + /* an update that doesn't touch "key" columns */ + MultiXactStatusNoKeyUpdate = 0x04, + /* other updates, and delete */ + MultiXactStatusUpdate = 0x05 +} MultiXactStatus; + +#define MaxMultiXactStatus MultiXactStatusUpdate + +/* does a status value correspond to a tuple update? */ +#define ISUPDATE_from_mxstatus(status) \ + ((status) > MultiXactStatusForUpdate) + + +typedef struct MultiXactMember +{ + TransactionId xid; + MultiXactStatus status; +} MultiXactMember; + + /* ---------------- * multixact-related XLOG entries * ---------------- @@ -35,21 +75,30 @@ typedef struct xl_multixact_create { MultiXactId mid; /* new MultiXact's ID */ MultiXactOffset moff; /* its starting offset in members file */ - int32 nxids; /* number of member XIDs */ - TransactionId xids[1]; /* VARIABLE LENGTH ARRAY */ + int32 nmembers; /* number of member XIDs */ + MultiXactMember members[FLEXIBLE_ARRAY_MEMBER]; } xl_multixact_create; -#define MinSizeOfMultiXactCreate offsetof(xl_multixact_create, xids) +#define SizeOfMultiXactCreate (offsetof(xl_multixact_create, members)) + +extern MultiXactId MultiXactIdCreate(TransactionId xid1, + MultiXactStatus status1, TransactionId xid2, + MultiXactStatus status2); +extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid, + MultiXactStatus status); +extern MultiXactId MultiXactIdCreateFromMembers(int nmembers, + MultiXactMember *members); -extern MultiXactId MultiXactIdCreate(TransactionId xid1, TransactionId xid2); -extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid); +extern MultiXactId ReadNextMultiXactId(void); extern bool MultiXactIdIsRunning(MultiXactId multi); -extern bool MultiXactIdIsCurrent(MultiXactId multi); -extern void MultiXactIdWait(MultiXactId multi); -extern bool ConditionalMultiXactIdWait(MultiXactId multi); extern void MultiXactIdSetOldestMember(void); -extern int GetMultiXactIdMembers(MultiXactId multi, TransactionId **xids); +extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **xids, + bool allow_old); +extern bool MultiXactHasRunningRemoteMembers(MultiXactId multi); +extern bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2); +extern bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, + MultiXactId multi2); extern void AtEOXact_MultiXact(void); extern void AtPrepare_MultiXact(void); @@ -59,15 +108,23 @@ extern Size MultiXactShmemSize(void); extern void MultiXactShmemInit(void); extern void BootStrapMultiXact(void); extern void StartupMultiXact(void); +extern void TrimMultiXact(void); extern void ShutdownMultiXact(void); +extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, + Oid oldest_datoid); extern void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId *nextMulti, - MultiXactOffset *nextMultiOffset); + MultiXactOffset *nextMultiOffset, + MultiXactId *oldestMulti, + Oid *oldestMultiDB); extern void CheckPointMultiXact(void); +extern MultiXactId GetOldestMultiXactId(void); +extern void TruncateMultiXact(MultiXactId cutoff_multi); extern void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset); extern void MultiXactAdvanceNextMXact(MultiXactId minMulti, MultiXactOffset minMultiOffset); +extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB); extern void multixact_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len); @@ -78,5 +135,7 @@ extern void multixact_twophase_postabort(TransactionId xid, uint16 info, extern void multixact_redo(XLogRecPtr lsn, XLogRecord *record); extern void multixact_desc(StringInfo buf, uint8 xl_info, char *rec); +extern char *mxid_to_string(MultiXactId multi, int nmembers, + MultiXactMember *members); #endif /* MULTIXACT_H */ diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index f23ac3559a..f2817590c4 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -4,7 +4,7 @@ * header file for postgres btree access method implementation. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/nbtree.h @@ -36,9 +36,9 @@ typedef uint16 BTCycleId; * and status. If the page is deleted, we replace the level with the * next-transaction-ID value indicating when it is safe to reclaim the page. * - * We also store a "vacuum cycle ID". When a page is split while VACUUM is + * We also store a "vacuum cycle ID". When a page is split while VACUUM is * processing the index, a nonzero value associated with the VACUUM run is - * stored into both halves of the split page. (If VACUUM is not running, + * stored into both halves of the split page. (If VACUUM is not running, * both pages receive zero cycleids.) This allows VACUUM to detect whether * a page was split since it started, with a small probability of false match * if the page was last split some exact multiple of MAX_BT_CYCLE_ID VACUUMs @@ -73,9 +73,10 @@ typedef BTPageOpaqueData *BTPageOpaque; #define BTP_HALF_DEAD (1 << 4) /* empty, but still in tree */ #define BTP_SPLIT_END (1 << 5) /* rightmost page of split group */ #define BTP_HAS_GARBAGE (1 << 6) /* page has LP_DEAD tuples */ +#define BTP_INCOMPLETE_SPLIT (1 << 7) /* right sibling's downlink is missing */ /* - * The max allowed value of a cycle ID is a bit less than 64K. This is + * The max allowed value of a cycle ID is a bit less than 64K. This is * for convenience of pg_filedump and similar utilities: we want to use * the last 2 bytes of special space as an index type indicator, and * restricting cycle ID lets btree use that space for vacuum cycle IDs @@ -178,6 +179,7 @@ typedef struct BTMetaPageData #define P_ISHALFDEAD(opaque) ((opaque)->btpo_flags & BTP_HALF_DEAD) #define P_IGNORE(opaque) ((opaque)->btpo_flags & (BTP_DELETED|BTP_HALF_DEAD)) #define P_HAS_GARBAGE(opaque) ((opaque)->btpo_flags & BTP_HAS_GARBAGE) +#define P_INCOMPLETE_SPLIT(opaque) ((opaque)->btpo_flags & BTP_INCOMPLETE_SPLIT) /* * Lehman and Yao's algorithm requires a ``high key'' on every non-rightmost @@ -215,11 +217,10 @@ typedef struct BTMetaPageData #define XLOG_BTREE_SPLIT_L_ROOT 0x50 /* add tuple with split of root */ #define XLOG_BTREE_SPLIT_R_ROOT 0x60 /* as above, new item on right */ #define XLOG_BTREE_DELETE 0x70 /* delete leaf index tuples for a page */ -#define XLOG_BTREE_DELETE_PAGE 0x80 /* delete an entire page */ -#define XLOG_BTREE_DELETE_PAGE_META 0x90 /* same, and update metapage */ +#define XLOG_BTREE_UNLINK_PAGE 0x80 /* delete a half-dead page */ +#define XLOG_BTREE_UNLINK_PAGE_META 0x90 /* same, and update metapage */ #define XLOG_BTREE_NEWROOT 0xA0 /* new root page */ -#define XLOG_BTREE_DELETE_PAGE_HALF 0xB0 /* page deletion that makes - * parent half-dead */ +#define XLOG_BTREE_MARK_PAGE_HALFDEAD 0xB0 /* mark a leaf as half-dead */ #define XLOG_BTREE_VACUUM 0xC0 /* delete entries on a page during * vacuum */ #define XLOG_BTREE_REUSE_PAGE 0xD0 /* old page is about to be reused from @@ -254,7 +255,7 @@ typedef struct xl_btree_metadata typedef struct xl_btree_insert { xl_btreetid target; /* inserted tuple id */ - /* BlockNumber downlink field FOLLOWS IF NOT XLOG_BTREE_INSERT_LEAF */ + /* BlockNumber finishes_split field FOLLOWS IF NOT XLOG_BTREE_INSERT_LEAF */ /* xl_btree_metadata FOLLOWS IF XLOG_BTREE_INSERT_META */ /* INDEX TUPLE FOLLOWS AT END OF STRUCT */ } xl_btree_insert; @@ -272,9 +273,9 @@ typedef struct xl_btree_insert * Note: the four XLOG_BTREE_SPLIT xl_info codes all use this data record. * The _L and _R variants indicate whether the inserted tuple went into the * left or right split page (and thus, whether newitemoff and the new item - * are stored or not). The _ROOT variants indicate that we are splitting + * are stored or not). The _ROOT variants indicate that we are splitting * the root page, and thus that a newroot record rather than an insert or - * split record should follow. Note that a split record never carries a + * split record should follow. Note that a split record never carries a * metapage update --- we'll do that in the parent-level update. */ typedef struct xl_btree_split @@ -287,19 +288,18 @@ typedef struct xl_btree_split OffsetNumber firstright; /* first item moved to right page */ /* - * If level > 0, BlockIdData downlink follows. (We use BlockIdData rather - * than BlockNumber for alignment reasons: SizeOfBtreeSplit is only 16-bit - * aligned.) + * In the _L variants, next are OffsetNumber newitemoff and the new item. + * (In the _R variants, the new item is one of the right page's tuples.) + * The new item, but not newitemoff, is suppressed if XLogInsert chooses + * to store the left page's whole page image. * * If level > 0, an IndexTuple representing the HIKEY of the left page * follows. We don't need this on leaf pages, because it's the same as - * the leftmost key in the new right page. Also, it's suppressed if + * the leftmost key in the new right page. Also, it's suppressed if * XLogInsert chooses to store the left page's whole page image. * - * In the _L variants, next are OffsetNumber newitemoff and the new item. - * (In the _R variants, the new item is one of the right page's tuples.) - * The new item, but not newitemoff, is suppressed if XLogInsert chooses - * to store the left page's whole page image. + * If level > 0, BlockNumber of the page whose incomplete-split flag this + * insertion clears. (not aligned) * * Last are the right page's tuples in the form used by _bt_restore_page. */ @@ -370,23 +370,51 @@ typedef struct xl_btree_vacuum #define SizeOfBtreeVacuum (offsetof(xl_btree_vacuum, lastBlockVacuumed) + sizeof(BlockNumber)) /* - * This is what we need to know about deletion of a btree page. The target - * identifies the tuple removed from the parent page (note that we remove - * this tuple's downlink and the *following* tuple's key). Note we do not - * store any content for the deleted page --- it is just rewritten as empty - * during recovery, apart from resetting the btpo.xact. + * This is what we need to know about marking an empty branch for deletion. + * The target identifies the tuple removed from the parent page (note that we + * remove this tuple's downlink and the *following* tuple's key). Note that + * the leaf page is empty, so we don't need to store its content --- it is + * just reinitialized during recovery using the rest of the fields. */ -typedef struct xl_btree_delete_page +typedef struct xl_btree_mark_page_halfdead { xl_btreetid target; /* deleted tuple id in parent page */ - BlockNumber deadblk; /* child block being deleted */ - BlockNumber leftblk; /* child block's left sibling, if any */ - BlockNumber rightblk; /* child block's right sibling */ + + /* information needed to recreate the leaf page: */ + BlockNumber leafblk; /* leaf block ultimately being deleted */ + BlockNumber leftblk; /* leaf block's left sibling, if any */ + BlockNumber rightblk; /* leaf block's right sibling */ + BlockNumber topparent; /* topmost internal page in the branch */ +} xl_btree_mark_page_halfdead; + +#define SizeOfBtreeMarkPageHalfDead (offsetof(xl_btree_mark_page_halfdead, topparent) + sizeof(BlockNumber)) + +/* + * This is what we need to know about deletion of a btree page. Note we do + * not store any content for the deleted page --- it is just rewritten as empty + * during recovery, apart from resetting the btpo.xact. + */ +typedef struct xl_btree_unlink_page +{ + RelFileNode node; + BlockNumber deadblk; /* target block being deleted */ + BlockNumber leftsib; /* target block's left sibling, if any */ + BlockNumber rightsib; /* target block's right sibling */ + + /* + * Information needed to recreate the leaf page, when target is an + * internal page. + */ + BlockNumber leafblk; + BlockNumber leafleftsib; + BlockNumber leafrightsib; + BlockNumber topparent; /* next child down in the branch */ + TransactionId btpo_xact; /* value of btpo.xact for use in recovery */ - /* xl_btree_metadata FOLLOWS IF XLOG_BTREE_DELETE_PAGE_META */ -} xl_btree_delete_page; + /* xl_btree_metadata FOLLOWS IF XLOG_BTREE_UNLINK_PAGE_META */ +} xl_btree_unlink_page; -#define SizeOfBtreeDeletePage (offsetof(xl_btree_delete_page, btpo_xact) + sizeof(TransactionId)) +#define SizeOfBtreeUnlinkPage (offsetof(xl_btree_unlink_page, btpo_xact) + sizeof(TransactionId)) /* * New root log record. There are zero tuples if this is to establish an @@ -418,12 +446,12 @@ typedef struct xl_btree_newroot /* * When a new operator class is declared, we require that the user * supply us with an amproc procedure (BTORDER_PROC) for determining - * whether, for two keys a and b, a < b, a = b, or a > b. This routine + * whether, for two keys a and b, a < b, a = b, or a > b. This routine * must return < 0, 0, > 0, respectively, in these three cases. (It must * not return INT_MIN, since we may negate the result before using it.) * * To facilitate accelerated sorting, an operator class may choose to - * offer a second procedure (BTSORTSUPPORT_PROC). For full details, see + * offer a second procedure (BTSORTSUPPORT_PROC). For full details, see * src/include/utils/sortsupport.h. */ @@ -462,7 +490,7 @@ typedef BTStackData *BTStack; * BTScanOpaqueData is the btree-private state needed for an indexscan. * This consists of preprocessed scan keys (see _bt_preprocess_keys() for * details of the preprocessing), information about the current location - * of the scan, and information about the marked location, if any. (We use + * of the scan, and information about the marked location, if any. (We use * BTScanPosData to represent the data needed for each of current and marked * locations.) In addition we can remember some known-killed index entries * that must be marked before we can move off the current page. @@ -470,9 +498,9 @@ typedef BTStackData *BTStack; * Index scans work a page at a time: we pin and read-lock the page, identify * all the matching items on the page and save them in BTScanPosData, then * release the read-lock while returning the items to the caller for - * processing. This approach minimizes lock/unlock traffic. Note that we + * processing. This approach minimizes lock/unlock traffic. Note that we * keep the pin on the index page until the caller is done with all the items - * (this is needed for VACUUM synchronization, see nbtree/README). When we + * (this is needed for VACUUM synchronization, see nbtree/README). When we * are ready to step to the next page, if the caller has told us any of the * items were killed, we re-lock the page to mark them killed, then unlock. * Finally we drop the pin and step to the next page in the appropriate @@ -535,6 +563,7 @@ typedef struct BTArrayKeyInfo { int scan_key; /* index of associated key in arrayKeyData */ int cur_elem; /* index of current element in elem_values */ + int mark_elem; /* index of marked element in elem_values */ int num_elems; /* number of elems in current array value */ Datum *elem_values; /* array of num_elems Datums */ } BTArrayKeyInfo; @@ -583,7 +612,7 @@ typedef BTScanOpaqueData *BTScanOpaque; /* * We use some private sk_flags bits in preprocessed scan keys. We're allowed - * to use bits 16-31 (see skey.h). The uppermost bits are copied from the + * to use bits 16-31 (see skey.h). The uppermost bits are copied from the * index's indoption[] array entry for the index attribute. */ #define SK_BT_REQFWD 0x00010000 /* required to continue forward scan */ @@ -616,8 +645,7 @@ extern Datum btoptions(PG_FUNCTION_ARGS); extern bool _bt_doinsert(Relation rel, IndexTuple itup, IndexUniqueCheck checkUnique, Relation heapRel); extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access); -extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, - BTStack stack, bool is_root, bool is_only); +extern void _bt_finish_split(Relation rel, Buffer bbuf, BTStack stack); /* * prototypes for functions in nbtpage.c @@ -625,6 +653,7 @@ extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, extern void _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level); extern Buffer _bt_getroot(Relation rel, int access); extern Buffer _bt_gettrueroot(Relation rel); +extern int _bt_getrootheight(Relation rel); extern void _bt_checkpage(Relation rel, Buffer buf); extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access); extern Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, @@ -637,7 +666,7 @@ extern void _bt_delitems_delete(Relation rel, Buffer buf, extern void _bt_delitems_vacuum(Relation rel, Buffer buf, OffsetNumber *itemnos, int nitems, BlockNumber lastBlockVacuumed); -extern int _bt_pagedel(Relation rel, Buffer buf, BTStack stack); +extern int _bt_pagedel(Relation rel, Buffer buf); /* * prototypes for functions in nbtsearch.c @@ -646,7 +675,8 @@ extern BTStack _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, Buffer *bufP, int access); extern Buffer _bt_moveright(Relation rel, Buffer buf, int keysz, - ScanKey scankey, bool nextkey, int access); + ScanKey scankey, bool nextkey, bool forupdate, BTStack stack, + int access); extern OffsetNumber _bt_binsrch(Relation rel, Buffer buf, int keysz, ScanKey scankey, bool nextkey); extern int32 _bt_compare(Relation rel, int keysz, ScanKey scankey, @@ -665,6 +695,8 @@ extern void _bt_freestack(BTStack stack); extern void _bt_preprocess_array_keys(IndexScanDesc scan); extern void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir); extern bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir); +extern void _bt_mark_array_keys(IndexScanDesc scan); +extern void _bt_restore_array_keys(IndexScanDesc scan); extern void _bt_preprocess_keys(IndexScanDesc scan); extern IndexTuple _bt_checkkeys(IndexScanDesc scan, Page page, OffsetNumber offnum, @@ -682,7 +714,8 @@ extern void BTreeShmemInit(void); */ typedef struct BTSpool BTSpool; /* opaque type known only within nbtsort.c */ -extern BTSpool *_bt_spoolinit(Relation index, bool isunique, bool isdead); +extern BTSpool *_bt_spoolinit(Relation heap, Relation index, + bool isunique, bool isdead); extern void _bt_spooldestroy(BTSpool *btspool); extern void _bt_spool(IndexTuple itup, BTSpool *btspool); extern void _bt_leafbuild(BTSpool *btspool, BTSpool *spool2); @@ -692,8 +725,5 @@ extern void _bt_leafbuild(BTSpool *btspool, BTSpool *spool2); */ extern void btree_redo(XLogRecPtr lsn, XLogRecord *record); extern void btree_desc(StringInfo buf, uint8 xl_info, char *rec); -extern void btree_xlog_startup(void); -extern void btree_xlog_cleanup(void); -extern bool btree_safe_restartpoint(void); #endif /* NBTREE_H */ diff --git a/src/include/access/printtup.h b/src/include/access/printtup.h index acc58a8ec8..dc28789173 100644 --- a/src/include/access/printtup.h +++ b/src/include/access/printtup.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/printtup.h diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index 42af4a9bbc..81ff3286cf 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -9,7 +9,7 @@ * into a lot of low-level code. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/reloptions.h @@ -20,6 +20,7 @@ #define RELOPTIONS_H #include "access/htup.h" +#include "access/tupdesc.h" #include "nodes/pg_list.h" /* types supported by reloptions */ @@ -196,7 +197,7 @@ typedef struct * "base" is a pointer to the reloptions structure, and "offset" is an integer * variable that must be initialized to sizeof(reloptions structure). This * struct must have been allocated with enough space to hold any string option - * present, including terminating \0 for every option. SET_VARSIZE() must be + * present, including terminating \0 for every option. SET_VARSIZE() must be * called on the struct with this offset as the second argument, after all the * string options have been processed. */ diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 2e967e1d59..8a57698feb 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -4,7 +4,7 @@ * POSTGRES relation scan descriptor definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/relscan.h @@ -16,6 +16,7 @@ #include "access/genam.h" #include "access/heapam.h" +#include "access/htup_details.h" #include "access/itup.h" #include "access/tupdesc.h" @@ -31,6 +32,7 @@ typedef struct HeapScanDescData bool rs_pageatatime; /* verify visibility page-at-a-time? */ bool rs_allow_strat; /* allow or disallow use of access strategy */ bool rs_allow_sync; /* allow or disallow use of syncscan */ + bool rs_temp_snap; /* unregister snapshot at scan end? */ /* state set up at initscan time */ BlockNumber rs_nblocks; /* number of blocks to scan */ @@ -100,6 +102,7 @@ typedef struct SysScanDescData Relation irel; /* NULL if doing heap scan */ HeapScanDesc scan; /* only valid in heap-scan case */ IndexScanDesc iscan; /* only valid in index-scan case */ + Snapshot snapshot; /* snapshot to unregister at end of scan */ } SysScanDescData; #endif /* RELSCAN_H */ diff --git a/src/include/access/rewriteheap.h b/src/include/access/rewriteheap.h index 1f6da613d6..4051c83852 100644 --- a/src/include/access/rewriteheap.h +++ b/src/include/access/rewriteheap.h @@ -3,7 +3,7 @@ * rewriteheap.h * Declarations for heap rewrite support functions * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/access/rewriteheap.h @@ -14,17 +14,44 @@ #define REWRITE_HEAP_H #include "access/htup.h" +#include "storage/itemptr.h" +#include "storage/relfilenode.h" #include "utils/relcache.h" /* struct definition is private to rewriteheap.c */ typedef struct RewriteStateData *RewriteState; -extern RewriteState begin_heap_rewrite(Relation NewHeap, +extern RewriteState begin_heap_rewrite(Relation OldHeap, Relation NewHeap, TransactionId OldestXmin, TransactionId FreezeXid, - bool use_wal); + MultiXactId MultiXactCutoff, bool use_wal); extern void end_heap_rewrite(RewriteState state); extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple, HeapTuple newTuple); extern bool rewrite_heap_dead_tuple(RewriteState state, HeapTuple oldTuple); +/* + * On-Disk data format for an individual logical rewrite mapping. + */ +typedef struct LogicalRewriteMappingData +{ + RelFileNode old_node; + RelFileNode new_node; + ItemPointerData old_tid; + ItemPointerData new_tid; +} LogicalRewriteMappingData; + +/* --- + * The filename consists out of the following, dash separated, + * components: + * 1) database oid or InvalidOid for shared relations + * 2) the oid of the relation + * 3) xid we are mapping for + * 4) upper 32bit of the LSN at which a rewrite started + * 5) lower 32bit of the LSN at which a rewrite started + * 6) xid of the xact performing the mapping + * --- + */ +#define LOGICAL_REWRITE_FORMAT "map-%x-%x-%X_%X-%x-%x" +void CheckPointLogicalRewriteHeap(void); + #endif /* REWRITE_HEAP_H */ diff --git a/src/include/access/rmgr.h b/src/include/access/rmgr.h index 02c50e4dfd..1b577a2050 100644 --- a/src/include/access/rmgr.h +++ b/src/include/access/rmgr.h @@ -13,31 +13,23 @@ typedef uint8 RmgrId; /* * Built-in resource managers * - * Note: RM_MAX_ID could be as much as 255 without breaking the XLOG file - * format, but we keep it small to minimize the size of RmgrTable[]. + * The actual numerical values for each rmgr ID are defined by the order + * of entries in rmgrlist.h. + * + * Note: RM_MAX_ID must fit in RmgrId; widening that type will affect the XLOG + * file format. */ -#define RM_XLOG_ID 0 -#define RM_XACT_ID 1 -#define RM_SMGR_ID 2 -#define RM_CLOG_ID 3 -#define RM_DBASE_ID 4 -#define RM_TBLSPC_ID 5 -#define RM_MULTIXACT_ID 6 -#define RM_RELMAP_ID 7 -#define RM_STANDBY_ID 8 -#define RM_HEAP2_ID 9 -#define RM_HEAP_ID 10 -#define RM_BTREE_ID 11 -#define RM_HASH_ID 12 -#define RM_GIN_ID 13 -#define RM_GIST_ID 14 -#define RM_SEQ_ID 15 -#define RM_SPGIST_ID 16 -#ifdef PGXC -#define RM_BARRIER_ID 17 -#define RM_MAX_ID RM_BARRIER_ID -#else -#define RM_MAX_ID RM_SPGIST_ID -#endif +#define PG_RMGR(symname,name,redo,desc,startup,cleanup) \ + symname, + +typedef enum RmgrIds +{ +#include "access/rmgrlist.h" + RM_NEXT_ID +} RmgrIds; + +#undef PG_RMGR + +#define RM_MAX_ID (RM_NEXT_ID - 1) #endif /* RMGR_H */ diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h new file mode 100644 index 0000000000..f6acd6d68c --- /dev/null +++ b/src/include/access/rmgrlist.h @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------- + * rmgrlist.h + * + * The resource manager list is kept in its own source file for possible + * use by automatic tools. The exact representation of a rmgr is determined + * by the PG_RMGR macro, which is not defined in this file; it can be + * defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/rmgrlist.h + *--------------------------------------------------------------------------- + */ + +/* there is deliberately not an #ifndef RMGRLIST_H here */ + +/* + * List of resource manager entries. Note that order of entries defines the + * numerical values of each rmgr's ID, which is stored in WAL records. New + * entries should be added at the end, to avoid changing IDs of existing + * entries. + * + * Changes to this list possibly need a XLOG_PAGE_MAGIC bump. + */ + +/* symbol name, textual name, redo, desc, startup, cleanup */ +PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, NULL, NULL) +PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, NULL, NULL) +PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, NULL, NULL) +PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, NULL, NULL) +PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, NULL, NULL) +PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, NULL, NULL) +PG_RMGR(RM_MULTIXACT_ID, "MultiXact", multixact_redo, multixact_desc, NULL, NULL) +PG_RMGR(RM_RELMAP_ID, "RelMap", relmap_redo, relmap_desc, NULL, NULL) +PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, NULL, NULL) +PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, NULL, NULL) +PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, NULL, NULL) +PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, NULL, NULL) +PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, NULL, NULL) +PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup) +PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup) +PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, NULL, NULL) +PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup) +#ifdef PGXC +PG_RMGR(RM_BARRIER_ID, "Barrier", barrier_redo, barrier_desc, NULL, NULL) +#endif diff --git a/src/include/access/sdir.h b/src/include/access/sdir.h index d81da29145..ffc3142118 100644 --- a/src/include/access/sdir.h +++ b/src/include/access/sdir.h @@ -4,7 +4,7 @@ * POSTGRES scan direction definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/sdir.h diff --git a/src/include/access/skey.h b/src/include/access/skey.h index d8c978fbaa..bb96808719 100644 --- a/src/include/access/skey.h +++ b/src/include/access/skey.h @@ -4,7 +4,7 @@ * POSTGRES scan key definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/skey.h @@ -42,7 +42,7 @@ typedef uint16 StrategyNumber; /* * A ScanKey represents the application of a comparison operator between - * a table or index column and a constant. When it's part of an array of + * a table or index column and a constant. When it's part of an array of * ScanKeys, the comparison conditions are implicitly ANDed. The index * column is the left argument of the operator, if it's a binary operator. * (The data structure can support unary indexable operators too; in that @@ -115,7 +115,7 @@ typedef ScanKeyData *ScanKey; * must be sorted according to the leading column number. * * The subsidiary ScanKey array appears in logical column order of the row - * comparison, which may be different from index column order. The array + * comparison, which may be different from index column order. The array * elements are like a normal ScanKey array except that: * sk_flags must include SK_ROW_MEMBER, plus SK_ROW_END in the last * element (needed since row header does not include a count) diff --git a/src/include/access/slru.h b/src/include/access/slru.h index 711601ae62..8eb22a4973 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -3,7 +3,7 @@ * slru.h * Simple LRU buffering for transaction status logfiles * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/slru.h @@ -31,7 +31,7 @@ * segment and page numbers in SimpleLruTruncate (see PagePrecedes()). * * Note: slru.c currently assumes that segment file names will be four hex - * digits. This sets a lower bound on the segment size (64K transactions + * digits. This sets a lower bound on the segment size (64K transactions * for 32-bit TransactionIds). */ #define SLRU_PAGES_PER_SEGMENT 32 @@ -55,7 +55,7 @@ typedef enum */ typedef struct SlruSharedData { - LWLockId ControlLock; + LWLock *ControlLock; /* Number of buffers managed by this SLRU structure */ int num_slots; @@ -69,7 +69,7 @@ typedef struct SlruSharedData bool *page_dirty; int *page_number; int *page_lru_count; - LWLockId *buffer_locks; + LWLock **buffer_locks; /* * Optional array of WAL flush LSNs associated with entries in the SLRU @@ -136,7 +136,7 @@ typedef SlruCtlData *SlruCtl; extern Size SimpleLruShmemSize(int nslots, int nlsns); extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, - LWLockId ctllock, const char *subdir); + LWLock *ctllock, const char *subdir); extern int SimpleLruZeroPage(SlruCtl ctl, int pageno); extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid); @@ -145,10 +145,12 @@ extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, extern void SimpleLruWritePage(SlruCtl ctl, int slotno); extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint); extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); +extern bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno); typedef bool (*SlruScanCallback) (SlruCtl ctl, char *filename, int segpage, void *data); extern bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data); +extern void SlruDeleteSegment(SlruCtl ctl, char *filename); /* SlruScanDirectory public callbacks */ extern bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index 50cac280a5..9187b4ac41 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -4,7 +4,7 @@ * Public header file for SP-GiST access method. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/spgist.h diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h index 74267a4390..d092029d8a 100644 --- a/src/include/access/spgist_private.h +++ b/src/include/access/spgist_private.h @@ -4,7 +4,7 @@ * Private declarations for SP-GiST access method. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/spgist_private.h @@ -17,7 +17,8 @@ #include "access/itup.h" #include "access/spgist.h" #include "nodes/tidbitmap.h" -#include "utils/rel.h" +#include "storage/relfilenode.h" +#include "utils/relcache.h" /* Page numbers of fixed-location pages */ @@ -184,7 +185,7 @@ typedef struct SpGistCache /* - * SPGiST tuple types. Note: inner, leaf, and dead tuple structs + * SPGiST tuple types. Note: inner, leaf, and dead tuple structs * must have the same tupstate field in the same position! Real inner and * leaf tuples always have tupstate = LIVE; if the state is something else, * use the SpGistDeadTuple struct to inspect the tuple. @@ -421,10 +422,7 @@ typedef struct spgxlogAddLeaf OffsetNumber offnumParent; uint16 nodeI; - /* - * new leaf tuple follows, on an intalign boundary (replay only needs to - * fetch its size field, so that should be enough alignment) - */ + /* new leaf tuple follows (unaligned!) */ } spgxlogAddLeaf; typedef struct spgxlogMoveLeafs @@ -448,9 +446,7 @@ typedef struct spgxlogMoveLeafs * data follows: * array of deleted tuple numbers, length nMoves * array of inserted tuple numbers, length nMoves + 1 or 1 - * list of leaf tuples, length nMoves + 1 or 1 (must be maxaligned) - * the tuple number arrays are padded to maxalign boundaries so that the - * leaf tuples will be suitably aligned + * list of leaf tuples, length nMoves + 1 or 1 (unaligned!) * * Note: if replaceDead is true then there is only one inserted tuple * number and only one leaf tuple in the data, because we are not copying @@ -462,8 +458,11 @@ typedef struct spgxlogMoveLeafs * Parent page *---------- */ + OffsetNumber offsets[1]; } spgxlogMoveLeafs; +#define SizeOfSpgxlogMoveLeafs offsetof(spgxlogMoveLeafs, offsets) + typedef struct spgxlogAddNode { RelFileNode node; @@ -482,8 +481,7 @@ typedef struct spgxlogAddNode spgxlogState stateSrc; /* - * updated inner tuple follows, on an intalign boundary (replay only needs - * to fetch its size field, so that should be enough alignment) + * updated inner tuple follows (unaligned!) */ } spgxlogAddNode; @@ -499,9 +497,8 @@ typedef struct spgxlogSplitTuple bool newPage; /* need to init that page? */ /* - * new prefix inner tuple follows, then new postfix inner tuple, on - * intalign boundaries (replay only needs to fetch size fields, so that - * should be enough alignment) + * new prefix inner tuple follows, then new postfix inner tuple + * (both are unaligned!) */ } spgxlogSplitTuple; @@ -530,13 +527,11 @@ typedef struct spgxlogPickSplit /*---------- * data follows: - * new inner tuple (assumed to have a maxaligned length) * array of deleted tuple numbers, length nDelete * array of inserted tuple numbers, length nInsert * array of page selector bytes for inserted tuples, length nInsert - * list of leaf tuples, length nInsert (must be maxaligned) - * the tuple number and page selector arrays are padded to maxalign - * boundaries so that the leaf tuples will be suitably aligned + * new inner tuple (unaligned!) + * list of leaf tuples, length nInsert (unaligned!) * * Buffer references in the rdata array are: * Src page (only if not root and not being init'd) @@ -545,8 +540,11 @@ typedef struct spgxlogPickSplit * Parent page (if any; could be same as Inner) *---------- */ + OffsetNumber offsets[1]; } spgxlogPickSplit; +#define SizeOfSpgxlogPickSplit offsetof(spgxlogPickSplit, offsets) + typedef struct spgxlogVacuumLeaf { RelFileNode node; @@ -569,8 +567,11 @@ typedef struct spgxlogVacuumLeaf * tuple numbers to insert in nextOffset links *---------- */ + OffsetNumber offsets[1]; } spgxlogVacuumLeaf; +#define SizeOfSpgxlogVacuumLeaf offsetof(spgxlogVacuumLeaf, offsets) + typedef struct spgxlogVacuumRoot { /* vacuum a root page when it is also a leaf */ @@ -582,8 +583,11 @@ typedef struct spgxlogVacuumRoot spgxlogState stateSrc; /* offsets of tuples to delete follow */ + OffsetNumber offsets[1]; } spgxlogVacuumRoot; +#define SizeOfSpgxlogVacuumRoot offsetof(spgxlogVacuumRoot, offsets) + typedef struct spgxlogVacuumRedirect { RelFileNode node; @@ -591,10 +595,14 @@ typedef struct spgxlogVacuumRedirect BlockNumber blkno; /* block number to clean */ uint16 nToPlaceholder; /* number of redirects to make placeholders */ OffsetNumber firstPlaceholder; /* first placeholder tuple to remove */ + TransactionId newestRedirectXid; /* newest XID of removed redirects */ /* offsets of redirect tuples to make placeholders follow */ + OffsetNumber offsets[1]; } spgxlogVacuumRedirect; +#define SizeOfSpgxlogVacuumRedirect offsetof(spgxlogVacuumRedirect, offsets) + /* * The "flags" argument for SpGistGetBuffer should be either GBUF_LEAF to * get a leaf page, or GBUF_INNER_PARITY(blockNumber) to get an inner @@ -650,7 +658,7 @@ extern void spgPageIndexMultiDelete(SpGistState *state, Page page, OffsetNumber *itemnos, int nitems, int firststate, int reststate, BlockNumber blkno, OffsetNumber offnum); -extern void spgdoinsert(Relation index, SpGistState *state, +extern bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum datum, bool isnull); #endif /* SPGIST_PRIVATE_H */ diff --git a/src/include/access/subtrans.h b/src/include/access/subtrans.h index 72e3470d2b..9eddfa05db 100644 --- a/src/include/access/subtrans.h +++ b/src/include/access/subtrans.h @@ -3,7 +3,7 @@ * * PostgreSQL subtransaction-log manager * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/subtrans.h diff --git a/src/include/access/sysattr.h b/src/include/access/sysattr.h index e4c507b839..8981c8f2c2 100644 --- a/src/include/access/sysattr.h +++ b/src/include/access/sysattr.h @@ -4,7 +4,7 @@ * POSTGRES system attribute definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/sysattr.h @@ -33,5 +33,4 @@ #endif - #endif /* SYSATTR_H */ diff --git a/src/include/access/timeline.h b/src/include/access/timeline.h new file mode 100644 index 0000000000..a5664688ea --- /dev/null +++ b/src/include/access/timeline.h @@ -0,0 +1,44 @@ +/* + * timeline.h + * + * Functions for reading and writing timeline history files. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/timeline.h + */ +#ifndef TIMELINE_H +#define TIMELINE_H + +#include "access/xlogdefs.h" +#include "nodes/pg_list.h" + +/* + * A list of these structs describes the timeline history of the server. Each + * TimeLineHistoryEntry represents a piece of WAL belonging to the history, + * from newest to oldest. All WAL positions between 'begin' and 'end' belong to + * the timeline represented by the entry. Together the 'begin' and 'end' + * pointers of all the entries form a contiguous line from beginning of time + * to infinity. + */ +typedef struct +{ + TimeLineID tli; + XLogRecPtr begin; /* inclusive */ + XLogRecPtr end; /* exclusive, 0 means infinity */ +} TimeLineHistoryEntry; + +extern List *readTimeLineHistory(TimeLineID targetTLI); +extern bool existsTimeLineHistory(TimeLineID probeTLI); +extern TimeLineID findNewestTimeLine(TimeLineID startTLI); +extern void writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, + XLogRecPtr switchpoint, char *reason); +extern void writeTimeLineHistoryFile(TimeLineID tli, char *content, int size); +extern void restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end); +extern bool tliInHistory(TimeLineID tli, List *expectedTLIs); +extern TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history); +extern XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, + TimeLineID *nextTLI); + +#endif /* TIMELINE_H */ diff --git a/src/include/access/transam.h b/src/include/access/transam.h index b9d46e3504..35b74ab5f2 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -71,6 +71,11 @@ (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ (int32) ((id1) - (id2)) < 0) +/* compare two XIDs already known to be normal; this is a macro for speed */ +#define NormalTransactionIdFollows(id1, id2) \ + (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ + (int32) ((id1) - (id2)) > 0) + /* ---------- * Object ID (OID) zero is InvalidOid. * @@ -81,7 +86,7 @@ * using the OID generator. (We start the generator at 10000.) * * OIDs beginning at 16384 are assigned from the OID generator - * during normal multiuser operation. (We force the generator up to + * during normal multiuser operation. (We force the generator up to * 16384 as soon as we are in normal operation.) * * The choices of 10000 and 16384 are completely arbitrary, and can be moved @@ -147,10 +152,6 @@ extern bool TransactionStartedDuringRecovery(void); /* in transam/varsup.c */ extern PGDLLIMPORT VariableCache ShmemVariableCache; -/* in transam/transam.c */ -extern const XLogRecPtr InvalidXLogRecPtr; - - /* * prototypes for functions in transam/transam.c */ diff --git a/src/include/access/tupconvert.h b/src/include/access/tupconvert.h index 7511aa6405..dd4ba127c2 100644 --- a/src/include/access/tupconvert.h +++ b/src/include/access/tupconvert.h @@ -4,7 +4,7 @@ * Tuple conversion support. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupconvert.h @@ -15,6 +15,7 @@ #define TUPCONVERT_H #include "access/htup.h" +#include "access/tupdesc.h" typedef struct TupleConversionMap diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index 953e146d5e..083f4bdc40 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -4,7 +4,7 @@ * POSTGRES tuple descriptor definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupdesc.h @@ -55,7 +55,7 @@ typedef struct tupleConstr * TupleDesc; with the exception that tdhasoid indicates if OID is present. * * If the tupdesc is known to correspond to a named rowtype (such as a table's - * rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise + * rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise * tdtypeid is RECORDOID, and tdtypmod can be either -1 for a fully anonymous * row type, or a value >= 0 to allow the rowtype to be looked up in the * typcache.c type cache. @@ -90,6 +90,9 @@ extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); +extern void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, + TupleDesc src, AttrNumber srcAttno); + extern void FreeTupleDesc(TupleDesc tupdesc); extern void IncrTupleDescRefCount(TupleDesc tupdesc); diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h index 984a049297..ff198fe75e 100644 --- a/src/include/access/tupmacs.h +++ b/src/include/access/tupmacs.h @@ -4,7 +4,7 @@ * Tuple macros used by both index tuples and heap tuples. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupmacs.h @@ -92,7 +92,7 @@ /* * att_align_datum aligns the given offset as needed for a datum of alignment - * requirement attalign and typlen attlen. attdatum is the Datum variable + * requirement attalign and typlen attlen. attdatum is the Datum variable * we intend to pack into a tuple (it's only accessed if we are dealing with * a varlena type). Note that this assumes the Datum will be stored as-is; * callers that are intending to convert non-short varlena datums to short @@ -101,7 +101,7 @@ #define att_align_datum(cur_offset, attalign, attlen, attdatum) \ ( \ ((attlen) == -1 && VARATT_IS_SHORT(DatumGetPointer(attdatum))) ? \ - (intptr_t) (cur_offset) : \ + (uintptr_t) (cur_offset) : \ att_align_nominal(cur_offset, attalign) \ ) @@ -111,18 +111,18 @@ * pointer; when accessing a varlena field we have to "peek" to see if we * are looking at a pad byte or the first byte of a 1-byte-header datum. * (A zero byte must be either a pad byte, or the first byte of a correctly - * aligned 4-byte length word; in either case we can align safely. A non-zero + * aligned 4-byte length word; in either case we can align safely. A non-zero * byte must be either a 1-byte length word, or the first byte of a correctly * aligned 4-byte length word; in either case we need not align.) * * Note: some callers pass a "char *" pointer for cur_offset. This is - * a bit of a hack but should work all right as long as intptr_t is the + * a bit of a hack but should work all right as long as uintptr_t is the * correct width. */ #define att_align_pointer(cur_offset, attalign, attlen, attptr) \ ( \ ((attlen) == -1 && VARATT_NOT_PAD_BYTE(attptr)) ? \ - (intptr_t) (cur_offset) : \ + (uintptr_t) (cur_offset) : \ att_align_nominal(cur_offset, attalign) \ ) @@ -144,7 +144,7 @@ #define att_align_nominal(cur_offset, attalign) \ ( \ ((attalign) == 'i') ? INTALIGN(cur_offset) : \ - (((attalign) == 'c') ? (intptr_t) (cur_offset) : \ + (((attalign) == 'c') ? (uintptr_t) (cur_offset) : \ (((attalign) == 'd') ? DOUBLEALIGN(cur_offset) : \ ( \ AssertMacro((attalign) == 's'), \ diff --git a/src/include/access/tuptoaster.h b/src/include/access/tuptoaster.h index e3dbde0def..d8edd9e987 100644 --- a/src/include/access/tuptoaster.h +++ b/src/include/access/tuptoaster.h @@ -4,7 +4,7 @@ * POSTGRES definitions for external and compressed storage * of variable size attributes. * - * Copyright (c) 2000-2012, PostgreSQL Global Development Group + * Copyright (c) 2000-2014, PostgreSQL Global Development Group * * src/include/access/tuptoaster.h * @@ -13,8 +13,9 @@ #ifndef TUPTOASTER_H #define TUPTOASTER_H -#include "access/htup.h" +#include "access/htup_details.h" #include "utils/relcache.h" +#include "storage/lock.h" /* * This enables de-toasting of index entries. Needed until VACUUM is @@ -59,7 +60,7 @@ * The code will also consider moving MAIN data out-of-line, but only as a * last resort if the previous steps haven't reached the target tuple size. * In this phase we use a different target size, currently equal to the - * largest tuple that will fit on a heap page. This is reasonable since + * largest tuple that will fit on a heap page. This is reasonable since * the user has told us to keep the data in-line if at all possible. */ #define TOAST_TUPLES_PER_PAGE_MAIN 1 @@ -75,7 +76,7 @@ /* * When we store an oversize datum externally, we divide it into chunks - * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must* + * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must* * be small enough that the completed toast-table tuple (including the * ID and sequence fields and all overhead) will fit on a page. * The coding here sets the size on the theory that we want to fit @@ -94,6 +95,36 @@ sizeof(int32) - \ VARHDRSZ) +/* Size of an EXTERNAL datum that contains a standard TOAST pointer */ +#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(struct varatt_external)) + +/* Size of an indirect datum that contains a standard TOAST pointer */ +#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(struct varatt_indirect)) + +/* + * Testing whether an externally-stored value is compressed now requires + * comparing extsize (the actual length of the external data) to rawsize + * (the original uncompressed datum's size). The latter includes VARHDRSZ + * overhead, the former doesn't. We never use compression unless it actually + * saves space, so we expect either equality or less-than. + */ +#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \ + ((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ) + +/* + * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum + * into a local "struct varatt_external" toast pointer. This should be + * just a memcpy, but some versions of gcc seem to produce broken code + * that assumes the datum contents are aligned. Introducing an explicit + * intermediate "varattrib_1b_e *" variable seems to fix it. + */ +#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \ +do { \ + varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \ + Assert(VARATT_IS_EXTERNAL(attre)); \ + Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \ + memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \ +} while (0) /* ---------- * toast_insert_or_update - @@ -153,16 +184,14 @@ extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena * attr, extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc); /* ---------- - * toast_flatten_tuple_attribute - + * toast_flatten_tuple_to_datum - * - * If a Datum is of composite type, "flatten" it to contain no toasted fields. - * This must be invoked on any potentially-composite field that is to be - * inserted into a tuple. Doing this preserves the invariant that toasting - * goes only one level deep in a tuple. + * "Flatten" a tuple containing out-of-line toasted fields into a Datum. * ---------- */ -extern Datum toast_flatten_tuple_attribute(Datum value, - Oid typeId, int32 typeMod); +extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, + uint32 tup_len, + TupleDesc tupleDesc); /* ---------- * toast_compress_datum - @@ -188,4 +217,12 @@ extern Size toast_raw_datum_size(Datum value); */ extern Size toast_datum_size(Datum value); +/* ---------- + * toast_get_valid_index - + * + * Return OID of valid index associated to a toast relation + * ---------- + */ +extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock); + #endif /* TUPTOASTER_H */ diff --git a/src/include/access/twophase.h b/src/include/access/twophase.h index e01385407f..df1b6e334b 100644 --- a/src/include/access/twophase.h +++ b/src/include/access/twophase.h @@ -4,7 +4,7 @@ * Two-phase-commit related declarations. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/twophase.h @@ -14,7 +14,9 @@ #ifndef TWOPHASE_H #define TWOPHASE_H -#include "storage/proc.h" +#include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "storage/lock.h" /* * GlobalTransactionData is defined in twophase.c; other places have no @@ -28,6 +30,9 @@ extern int max_prepared_xacts; extern Size TwoPhaseShmemSize(void); extern void TwoPhaseShmemInit(void); +extern void AtAbort_Twophase(void); +extern void PostPrepare_Twophase(void); + extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid); extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid); diff --git a/src/include/access/twophase_rmgr.h b/src/include/access/twophase_rmgr.h index aed8ba3bac..2b0c521062 100644 --- a/src/include/access/twophase_rmgr.h +++ b/src/include/access/twophase_rmgr.h @@ -4,7 +4,7 @@ * Two-phase-commit resource managers definition * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/twophase_rmgr.h diff --git a/src/include/access/valid.h b/src/include/access/valid.h index ce970e44df..7a83395492 100644 --- a/src/include/access/valid.h +++ b/src/include/access/valid.h @@ -4,7 +4,7 @@ * POSTGRES tuple qualification validity definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/valid.h diff --git a/src/include/access/visibilitymap.h b/src/include/access/visibilitymap.h index 5774e92e15..888705e087 100644 --- a/src/include/access/visibilitymap.h +++ b/src/include/access/visibilitymap.h @@ -4,7 +4,7 @@ * visibility map interface * * - * Portions Copyright (c) 2007-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2007-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/visibilitymap.h @@ -24,8 +24,8 @@ extern void visibilitymap_clear(Relation rel, BlockNumber heapBlk, extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf); extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf); -extern void visibilitymap_set(Relation rel, BlockNumber heapBlk, - XLogRecPtr recptr, Buffer vmbuf, TransactionId cutoff_xid); +extern void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, + XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid); extern bool visibilitymap_test(Relation rel, BlockNumber heapBlk, Buffer *vmbuf); extern BlockNumber visibilitymap_count(Relation rel); extern void visibilitymap_truncate(Relation rel, BlockNumber nheapblocks); diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 127a849c10..6492979e73 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -37,7 +37,7 @@ #define XACT_SERIALIZABLE 3 extern int DefaultXactIsoLevel; -extern int XactIsoLevel; +extern PGDLLIMPORT int XactIsoLevel; /* * We implement three isolation levels internally. @@ -85,7 +85,9 @@ typedef enum { XACT_EVENT_COMMIT, XACT_EVENT_ABORT, - XACT_EVENT_PREPARE + XACT_EVENT_PREPARE, + XACT_EVENT_PRE_COMMIT, + XACT_EVENT_PRE_PREPARE } XactEvent; typedef void (*XactCallback) (XactEvent event, void *arg); @@ -94,7 +96,8 @@ typedef enum { SUBXACT_EVENT_START_SUB, SUBXACT_EVENT_COMMIT_SUB, - SUBXACT_EVENT_ABORT_SUB + SUBXACT_EVENT_ABORT_SUB, + SUBXACT_EVENT_PRE_COMMIT_SUB } SubXactEvent; typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, @@ -244,6 +247,8 @@ extern void SetTopGlobalTransactionId(GlobalTransactionId gxid); #endif extern TransactionId GetStableLatestTransactionId(void); extern SubTransactionId GetCurrentSubTransactionId(void); +extern void MarkCurrentTransactionIdLoggedIfAny(void); +extern bool SubTransactionIsActive(SubTransactionId subxid); extern CommandId GetCurrentCommandId(bool used); extern TimestampTz GetCurrentTransactionStartTimestamp(void); extern TimestampTz GetCurrentStatementStartTimestamp(void); @@ -280,6 +285,7 @@ extern char TransactionBlockStatusCode(void); extern void AbortOutOfAnyTransaction(void); extern void PreventTransactionChain(bool isTopLevel, const char *stmtType); extern void RequireTransactionChain(bool isTopLevel, const char *stmtType); +extern void WarnNoTransactionChain(bool isTopLevel, const char *stmtType); extern bool IsInTransactionChain(bool isTopLevel); extern void RegisterXactCallback(XactCallback callback, void *arg); extern void UnregisterXactCallback(XactCallback callback, void *arg); diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 0a7fee91a2..7a8bce8b13 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -3,7 +3,7 @@ * * PostgreSQL transaction log manager * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlog.h @@ -31,24 +31,25 @@ * where there can be zero to four backup blocks (as signaled by xl_info flag * bits). XLogRecord structs always start on MAXALIGN boundaries in the WAL * files, and we round up SizeOfXLogRecord so that the rmgr data is also - * guaranteed to begin on a MAXALIGN boundary. However, no padding is added + * guaranteed to begin on a MAXALIGN boundary. However, no padding is added * to align BkpBlock structs or backup block data. * * NOTE: xl_len counts only the rmgr data, not the XLogRecord header, - * and also not any backup blocks. xl_tot_len counts everything. Neither + * and also not any backup blocks. xl_tot_len counts everything. Neither * length field is rounded up to an alignment boundary. */ typedef struct XLogRecord { - pg_crc32 xl_crc; /* CRC for this record */ - XLogRecPtr xl_prev; /* ptr to previous record in log */ - TransactionId xl_xid; /* xact id */ uint32 xl_tot_len; /* total len of entire record */ + TransactionId xl_xid; /* xact id */ uint32 xl_len; /* total len of rmgr data */ uint8 xl_info; /* flag bits, see below */ RmgrId xl_rmid; /* resource manager for this record */ + /* 2 bytes of padding here, initialize to zero */ + XLogRecPtr xl_prev; /* ptr to previous record in log */ + pg_crc32 xl_crc; /* CRC for this record */ - /* Depending on MAXALIGN, there are either 2 or 6 wasted bytes here */ + /* If MAXALIGN==8, there are 4 wasted bytes here */ /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ @@ -70,11 +71,7 @@ typedef struct XLogRecord */ #define XLR_BKP_BLOCK_MASK 0x0F /* all info bits used for bkp blocks */ #define XLR_MAX_BKP_BLOCKS 4 -#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> (iblk)) -#define XLR_BKP_BLOCK_1 XLR_SET_BKP_BLOCK(0) /* 0x08 */ -#define XLR_BKP_BLOCK_2 XLR_SET_BKP_BLOCK(1) /* 0x04 */ -#define XLR_BKP_BLOCK_3 XLR_SET_BKP_BLOCK(2) /* 0x02 */ -#define XLR_BKP_BLOCK_4 XLR_SET_BKP_BLOCK(3) /* 0x01 */ +#define XLR_BKP_BLOCK(iblk) (0x08 >> (iblk)) /* iblk in 0..3 */ /* Sync methods */ #define SYNC_METHOD_FSYNC 0 @@ -93,17 +90,17 @@ extern int sync_method; * If buffer is valid then XLOG will check if buffer must be backed up * (ie, whether this is first change of that page since last checkpoint). * If so, the whole page contents are attached to the XLOG record, and XLOG - * sets XLR_BKP_BLOCK_X bit in xl_info. Note that the buffer must be pinned + * sets XLR_BKP_BLOCK(N) bit in xl_info. Note that the buffer must be pinned * and exclusive-locked by the caller, so that it won't change under us. * NB: when the buffer is backed up, we DO NOT insert the data pointed to by * this XLogRecData struct into the XLOG record, since we assume it's present * in the buffer. Therefore, rmgr redo routines MUST pay attention to - * XLR_BKP_BLOCK_X to know what is actually stored in the XLOG record. - * The i'th XLR_BKP_BLOCK bit corresponds to the i'th distinct buffer + * XLR_BKP_BLOCK(N) to know what is actually stored in the XLOG record. + * The N'th XLR_BKP_BLOCK bit corresponds to the N'th distinct buffer * value (ignoring InvalidBuffer) appearing in the rdata chain. * * When buffer is valid, caller must set buffer_std to indicate whether the - * page uses standard pd_lower/pd_upper header fields. If this is true, then + * page uses standard pd_lower/pd_upper header fields. If this is true, then * XLOG is allowed to omit the free space between pd_lower and pd_upper from * the backed-up page image. Note that even when buffer_std is false, the * page MUST have an LSN field as its first eight bytes! @@ -176,11 +173,11 @@ typedef enum RECOVERY_TARGET_UNSET, RECOVERY_TARGET_XID, RECOVERY_TARGET_TIME, - RECOVERY_TARGET_NAME + RECOVERY_TARGET_NAME, #ifdef PGXC - , - RECOVERY_TARGET_BARRIER + RECOVERY_TARGET_BARRIER, #endif + RECOVERY_TARGET_IMMEDIATE } RecoveryTargetType; extern XLogRecPtr XactLastRecEnd; @@ -196,14 +193,17 @@ extern bool XLogArchiveMode; extern char *XLogArchiveCommand; extern bool EnableHotStandby; extern bool fullPageWrites; +extern bool wal_log_hints; extern bool log_checkpoints; +extern int num_xloginsert_locks; /* WAL levels */ typedef enum WalLevel { WAL_LEVEL_MINIMAL = 0, WAL_LEVEL_ARCHIVE, - WAL_LEVEL_HOT_STANDBY + WAL_LEVEL_HOT_STANDBY, + WAL_LEVEL_LOGICAL } WalLevel; extern int wal_level; @@ -216,9 +216,23 @@ extern int wal_level; */ #define XLogIsNeeded() (wal_level >= WAL_LEVEL_ARCHIVE) -/* Do we need to WAL-log information required only for Hot Standby? */ +/* + * Is a full-page image needed for hint bit updates? + * + * Normally, we don't WAL-log hint bit updates, but if checksums are enabled, + * we have to protect them against torn page writes. When you only set + * individual bits on a page, it's still consistent no matter what combination + * of the bits make it to disk, but the checksum wouldn't match. Also WAL-log + * them if forced by wal_log_hints=on. + */ +#define XLogHintBitIsNeeded() (DataChecksumsEnabled() || wal_log_hints) + +/* Do we need to WAL-log information required only for Hot Standby and logical replication? */ #define XLogStandbyInfoActive() (wal_level >= WAL_LEVEL_HOT_STANDBY) +/* Do we need to WAL-log information required only for logical replication? */ +#define XLogLogicalInfoActive() (wal_level >= WAL_LEVEL_LOGICAL) + #ifdef WAL_DEBUG extern bool XLOG_DEBUG; #endif @@ -268,39 +282,47 @@ typedef struct CheckpointStatsData extern CheckpointStatsData CheckpointStats; extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata); +extern bool XLogCheckBufferNeedsBackup(Buffer buffer); extern void XLogFlush(XLogRecPtr RecPtr); extern bool XLogBackgroundFlush(void); extern bool XLogNeedsFlush(XLogRecPtr RecPtr); -extern int XLogFileInit(uint32 log, uint32 seg, - bool *use_existent, bool use_lock); -extern int XLogFileOpen(uint32 log, uint32 seg); +extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock); +extern int XLogFileOpen(XLogSegNo segno); +extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std); -extern void XLogGetLastRemoved(uint32 *log, uint32 *seg); +extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli); +extern XLogSegNo XLogGetLastRemovedSegno(void); extern void XLogSetAsyncXactLSN(XLogRecPtr record); +extern void XLogSetReplicationSlotMinimumLSN(XLogRecPtr lsn); -extern void RestoreBkpBlocks(XLogRecPtr lsn, XLogRecord *record, bool cleanup); +extern Buffer RestoreBackupBlock(XLogRecPtr lsn, XLogRecord *record, + int block_index, + bool get_cleanup_lock, bool keep_buffer); extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record); extern void xlog_desc(StringInfo buf, uint8 xl_info, char *rec); -extern void issue_xlog_fsync(int fd, uint32 log, uint32 seg); +extern void issue_xlog_fsync(int fd, XLogSegNo segno); extern bool RecoveryInProgress(void); extern bool HotStandbyActive(void); +extern bool HotStandbyActiveInReplay(void); extern bool XLogInsertAllowed(void); extern void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream); -extern XLogRecPtr GetXLogReplayRecPtr(XLogRecPtr *restoreLastRecPtr); -extern XLogRecPtr GetStandbyFlushRecPtr(void); +extern XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI); extern XLogRecPtr GetXLogInsertRecPtr(void); extern XLogRecPtr GetXLogWriteRecPtr(void); extern bool RecoveryIsPaused(void); extern void SetRecoveryPause(bool recoveryPause); extern TimestampTz GetLatestXTime(void); extern TimestampTz GetCurrentChunkReplayStartTime(void); +extern char *XLogFileNameP(TimeLineID tli, XLogSegNo segno); extern void UpdateControlFile(void); extern uint64 GetSystemIdentifier(void); +extern bool DataChecksumsEnabled(void); +extern XLogRecPtr GetFakeLSNForUnloggedRel(void); extern Size XLOGShmemSize(void); extern void XLOGShmemInit(void); extern void BootStrapXLOG(void); @@ -316,7 +338,6 @@ extern XLogRecPtr GetRedoRecPtr(void); extern XLogRecPtr GetInsertRecPtr(void); extern XLogRecPtr GetFlushRecPtr(void); extern void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch); -extern TimeLineID GetRecoveryTargetTLI(void); extern bool CheckPromoteSignal(void); extern void WakeupRecovery(void); @@ -325,8 +346,10 @@ extern void SetWalWriterSleeping(bool sleeping); /* * Starting/stopping a base backup */ -extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile); -extern XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive); +extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, + TimeLineID *starttli_p, char **labelfile); +extern XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive, + TimeLineID *stoptli_p); extern void do_pg_abort_backup(void); /* File path names (all relative to $PGDATA) */ diff --git a/src/include/access/xlog_fn.h b/src/include/access/xlog_fn.h new file mode 100644 index 0000000000..b361db4f1f --- /dev/null +++ b/src/include/access/xlog_fn.h @@ -0,0 +1,35 @@ +/* + * xlog_fn.h + * + * PostgreSQL transaction log SQL-callable function declarations + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/xlog_fn.h + */ +#ifndef XLOG_FN_H +#define XLOG_FN_H + +#include "fmgr.h" + +extern Datum pg_start_backup(PG_FUNCTION_ARGS); +extern Datum pg_stop_backup(PG_FUNCTION_ARGS); +extern Datum pg_switch_xlog(PG_FUNCTION_ARGS); +extern Datum pg_create_restore_point(PG_FUNCTION_ARGS); +extern Datum pg_current_xlog_location(PG_FUNCTION_ARGS); +extern Datum pg_current_xlog_insert_location(PG_FUNCTION_ARGS); +extern Datum pg_last_xlog_receive_location(PG_FUNCTION_ARGS); +extern Datum pg_last_xlog_replay_location(PG_FUNCTION_ARGS); +extern Datum pg_last_xact_replay_timestamp(PG_FUNCTION_ARGS); +extern Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS); +extern Datum pg_xlogfile_name(PG_FUNCTION_ARGS); +extern Datum pg_is_in_recovery(PG_FUNCTION_ARGS); +extern Datum pg_xlog_replay_pause(PG_FUNCTION_ARGS); +extern Datum pg_xlog_replay_resume(PG_FUNCTION_ARGS); +extern Datum pg_is_xlog_replay_paused(PG_FUNCTION_ARGS); +extern Datum pg_xlog_location_diff(PG_FUNCTION_ARGS); +extern Datum pg_is_in_backup(PG_FUNCTION_ARGS); +extern Datum pg_backup_start_time(PG_FUNCTION_ARGS); + +#endif /* XLOG_FN_H */ diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 3328a50fab..3a692cdf0c 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -8,7 +8,10 @@ * needed by rmgr routines (redo support for individual record types). * So the XLogRecord typedef and associated stuff appear in xlog.h. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Note: This file must be includable in both frontend and backend contexts, + * to allow stand-alone tools like pg_receivexlog to deal with WAL files. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlog_internal.h @@ -16,8 +19,9 @@ #ifndef XLOG_INTERNAL_H #define XLOG_INTERNAL_H -#include "access/xlog.h" -#include "fmgr.h" +#include "access/xlogdefs.h" +#include "datatype/timestamp.h" +#include "lib/stringinfo.h" #include "pgtime.h" #include "storage/block.h" #include "storage/relfilenode.h" @@ -49,29 +53,9 @@ typedef struct BkpBlock } BkpBlock; /* - * When there is not enough space on current page for whole record, we - * continue on the next page with continuation record. (However, the - * XLogRecord header will never be split across pages; if there's less than - * SizeOfXLogRecord space left at the end of a page, we just waste it.) - * - * Note that xl_rem_len includes backup-block data; that is, it tracks - * xl_tot_len not xl_len in the initial header. Also note that the - * continuation data isn't necessarily aligned. - */ -typedef struct XLogContRecord -{ - uint32 xl_rem_len; /* total len of remaining data for record */ - - /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ - -} XLogContRecord; - -#define SizeOfXLogContRecord sizeof(XLogContRecord) - -/* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD071 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD07E /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { @@ -79,6 +63,17 @@ typedef struct XLogPageHeaderData uint16 xlp_info; /* flag bits, see below */ TimeLineID xlp_tli; /* TimeLineID of first record on page */ XLogRecPtr xlp_pageaddr; /* XLOG address of this page */ + + /* + * When there is not enough space on current page for whole record, we + * continue on the next page. xlp_rem_len is the number of bytes + * remaining from a previous page. + * + * Note that xl_rem_len includes backup-block data; that is, it tracks + * xl_tot_len not xl_len in the initial header. Also note that the + * continuation data isn't necessarily aligned. + */ + uint32 xlp_rem_len; /* total len of remaining data for record */ } XLogPageHeaderData; #define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) @@ -115,74 +110,28 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) /* - * We break each logical log file (xlogid value) into segment files of the - * size indicated by XLOG_SEG_SIZE. One possible segment at the end of each - * log file is wasted, to ensure that we don't have problems representing - * last-byte-position-plus-1. + * The XLOG is split into WAL segments (physical files) of the size indicated + * by XLOG_SEG_SIZE. */ #define XLogSegSize ((uint32) XLOG_SEG_SIZE) -#define XLogSegsPerFile (((uint32) 0xffffffff) / XLogSegSize) -#define XLogFileSize (XLogSegsPerFile * XLogSegSize) - - -/* - * Macros for manipulating XLOG pointers - */ - -/* Increment an xlogid/segment pair */ -#define NextLogSeg(logId, logSeg) \ - do { \ - if ((logSeg) >= XLogSegsPerFile-1) \ - { \ - (logId)++; \ - (logSeg) = 0; \ - } \ - else \ - (logSeg)++; \ - } while (0) - -/* Decrement an xlogid/segment pair (assume it's not 0,0) */ -#define PrevLogSeg(logId, logSeg) \ - do { \ - if (logSeg) \ - (logSeg)--; \ - else \ - { \ - (logId)--; \ - (logSeg) = XLogSegsPerFile-1; \ - } \ - } while (0) +#define XLogSegmentsPerXLogId (UINT64CONST(0x100000000) / XLOG_SEG_SIZE) -/* Align a record pointer to next page */ -#define NextLogPage(recptr) \ - do { \ - if ((recptr).xrecoff % XLOG_BLCKSZ != 0) \ - (recptr).xrecoff += \ - (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ); \ - if ((recptr).xrecoff >= XLogFileSize) \ - { \ - ((recptr).xlogid)++; \ - (recptr).xrecoff = 0; \ - } \ - } while (0) +#define XLogSegNoOffsetToRecPtr(segno, offset, dest) \ + (dest) = (segno) * XLOG_SEG_SIZE + (offset) /* * Compute ID and segment from an XLogRecPtr. * * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, - * a boundary byte is taken to be in the previous segment. This is suitable + * a boundary byte is taken to be in the previous segment. This is suitable * for deciding which segment to write given a pointer to a record end, - * for example. (We can assume xrecoff is not zero, since no valid recptr - * can have that.) + * for example. */ -#define XLByteToSeg(xlrp, logId, logSeg) \ - ( logId = (xlrp).xlogid, \ - logSeg = (xlrp).xrecoff / XLogSegSize \ - ) -#define XLByteToPrevSeg(xlrp, logId, logSeg) \ - ( logId = (xlrp).xlogid, \ - logSeg = ((xlrp).xrecoff - 1) / XLogSegSize \ - ) +#define XLByteToSeg(xlrp, logSegNo) \ + logSegNo = (xlrp) / XLogSegSize + +#define XLByteToPrevSeg(xlrp, logSegNo) \ + logSegNo = ((xlrp) - 1) / XLogSegSize /* * Is an XLogRecPtr within a particular XLOG segment? @@ -190,18 +139,15 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; * For XLByteInSeg, do the computation at face value. For XLByteInPrevSeg, * a boundary byte is taken to be in the previous segment. */ -#define XLByteInSeg(xlrp, logId, logSeg) \ - ((xlrp).xlogid == (logId) && \ - (xlrp).xrecoff / XLogSegSize == (logSeg)) +#define XLByteInSeg(xlrp, logSegNo) \ + (((xlrp) / XLogSegSize) == (logSegNo)) -#define XLByteInPrevSeg(xlrp, logId, logSeg) \ - ((xlrp).xlogid == (logId) && \ - ((xlrp).xrecoff - 1) / XLogSegSize == (logSeg)) +#define XLByteInPrevSeg(xlrp, logSegNo) \ + ((((xlrp) - 1) / XLogSegSize) == (logSegNo)) -/* Check if an xrecoff value is in a plausible range */ -#define XRecOffIsValid(xrecoff) \ - ((xrecoff) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \ - (XLOG_BLCKSZ - (xrecoff) % XLOG_BLCKSZ) >= SizeOfXLogRecord) +/* Check if an XLogRecPtr value is in a plausible range */ +#define XRecOffIsValid(xlrp) \ + ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) /* * The XLog directory and control file (relative to $PGDATA) @@ -215,14 +161,23 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; */ #define MAXFNAMELEN 64 -#define XLogFileName(fname, tli, log, seg) \ - snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg) - -#define XLogFromFileName(fname, tli, log, seg) \ - sscanf(fname, "%08X%08X%08X", tli, log, seg) +#define XLogFileName(fname, tli, logSegNo) \ + snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, \ + (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ + (uint32) ((logSegNo) % XLogSegmentsPerXLogId)) + +#define XLogFromFileName(fname, tli, logSegNo) \ + do { \ + uint32 log; \ + uint32 seg; \ + sscanf(fname, "%08X%08X%08X", tli, &log, &seg); \ + *logSegNo = (uint64) log * XLogSegmentsPerXLogId + seg; \ + } while (0) -#define XLogFilePath(path, tli, log, seg) \ - snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, log, seg) +#define XLogFilePath(path, tli, logSegNo) \ + snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, \ + (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ + (uint32) ((logSegNo) % XLogSegmentsPerXLogId)) #define TLHistoryFileName(fname, tli) \ snprintf(fname, MAXFNAMELEN, "%08X.history", tli) @@ -233,26 +188,66 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define StatusFilePath(path, xlog, suffix) \ snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) -#define BackupHistoryFileName(fname, tli, log, seg, offset) \ - snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, log, seg, offset) +#define BackupHistoryFileName(fname, tli, logSegNo, offset) \ + snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \ + (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ + (uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset) + +#define BackupHistoryFilePath(path, tli, logSegNo, offset) \ + snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, \ + (uint32) ((logSegNo) / XLogSegmentsPerXLogId), \ + (uint32) ((logSegNo) % XLogSegmentsPerXLogId), offset) + +/* + * Information logged when we detect a change in one of the parameters + * important for Hot Standby. + */ +typedef struct xl_parameter_change +{ + int MaxConnections; + int max_worker_processes; + int max_prepared_xacts; + int max_locks_per_xact; + int wal_level; + bool wal_log_hints; +} xl_parameter_change; + +/* logs restore point */ +typedef struct xl_restore_point +{ + TimestampTz rp_time; + char rp_name[MAXFNAMELEN]; +} xl_restore_point; -#define BackupHistoryFilePath(path, tli, log, seg, offset) \ - snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, log, seg, offset) +/* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ +typedef struct xl_end_of_recovery +{ + TimestampTz end_time; + TimeLineID ThisTimeLineID; /* new TLI */ + TimeLineID PrevTimeLineID; /* previous TLI we forked off from */ +} xl_end_of_recovery; +/* + * XLogRecord is defined in xlog.h, but we avoid #including that to keep + * this file includable in stand-alone programs. + */ +struct XLogRecord; /* * Method table for resource managers. * - * RmgrTable[] is indexed by RmgrId values (see rmgr.h). + * This struct must be kept in sync with the PG_RMGR definition in + * rmgr.c. + * + * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). */ typedef struct RmgrData { const char *rm_name; - void (*rm_redo) (XLogRecPtr lsn, XLogRecord *rptr); + void (*rm_redo) (XLogRecPtr lsn, struct XLogRecord *rptr); void (*rm_desc) (StringInfo buf, uint8 xl_info, char *rec); void (*rm_startup) (void); void (*rm_cleanup) (void); - bool (*rm_safe_restartpoint) (void); } RmgrData; extern const RmgrData RmgrTable[]; @@ -263,24 +258,31 @@ extern const RmgrData RmgrTable[]; extern pg_time_t GetLastSegSwitchTime(void); extern XLogRecPtr RequestXLogSwitch(void); +extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli); + +/* + * Exported for the functions in timeline.c and xlogarchive.c. Only valid + * in the startup process. + */ +extern bool ArchiveRecoveryRequested; +extern bool InArchiveRecovery; +extern bool StandbyMode; +extern char *recoveryRestoreCommand; + /* - * These aren't in xlog.h because I'd rather not include fmgr.h there. + * Prototypes for functions in xlogarchive.c */ -extern Datum pg_start_backup(PG_FUNCTION_ARGS); -extern Datum pg_stop_backup(PG_FUNCTION_ARGS); -extern Datum pg_switch_xlog(PG_FUNCTION_ARGS); -extern Datum pg_create_restore_point(PG_FUNCTION_ARGS); -extern Datum pg_current_xlog_location(PG_FUNCTION_ARGS); -extern Datum pg_current_xlog_insert_location(PG_FUNCTION_ARGS); -extern Datum pg_last_xlog_receive_location(PG_FUNCTION_ARGS); -extern Datum pg_last_xlog_replay_location(PG_FUNCTION_ARGS); -extern Datum pg_last_xact_replay_timestamp(PG_FUNCTION_ARGS); -extern Datum pg_xlogfile_name_offset(PG_FUNCTION_ARGS); -extern Datum pg_xlogfile_name(PG_FUNCTION_ARGS); -extern Datum pg_is_in_recovery(PG_FUNCTION_ARGS); -extern Datum pg_xlog_replay_pause(PG_FUNCTION_ARGS); -extern Datum pg_xlog_replay_resume(PG_FUNCTION_ARGS); -extern Datum pg_is_xlog_replay_paused(PG_FUNCTION_ARGS); -extern Datum pg_xlog_location_diff(PG_FUNCTION_ARGS); +extern bool RestoreArchivedFile(char *path, const char *xlogfname, + const char *recovername, off_t expectedSize, + bool cleanupEnabled); +extern void ExecuteRecoveryCommand(char *command, char *commandName, + bool failOnerror); +extern void KeepFileRestoredFromArchive(char *path, char *xlogfname); +extern void XLogArchiveNotify(const char *xlog); +extern void XLogArchiveNotifySeg(XLogSegNo segno); +extern void XLogArchiveForceDone(const char *xlog); +extern bool XLogArchiveCheckDone(const char *xlog); +extern bool XLogArchiveIsBusy(const char *xlog); +extern void XLogArchiveCleanup(const char *xlog); #endif /* XLOG_INTERNAL_H */ diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h index 5e6d7e600b..3b8e738eac 100644 --- a/src/include/access/xlogdefs.h +++ b/src/include/access/xlogdefs.h @@ -4,7 +4,7 @@ * Postgres transaction log manager record pointer and * timeline number definitions * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlogdefs.h @@ -17,60 +17,21 @@ /* * Pointer to a location in the XLOG. These pointers are 64 bits wide, * because we don't want them ever to overflow. - * - * NOTE: xrecoff == 0 is used to indicate an invalid pointer. This is OK - * because we use page headers in the XLOG, so no XLOG record can start - * right at the beginning of a file. - * - * NOTE: the "log file number" is somewhat misnamed, since the actual files - * making up the XLOG are much smaller than 4Gb. Each actual file is an - * XLogSegSize-byte "segment" of a logical log file having the indicated - * xlogid. The log file number and segment number together identify a - * physical XLOG file. Segment number and offset within the physical file - * are computed from xrecoff div and mod XLogSegSize. */ -typedef struct XLogRecPtr -{ - uint32 xlogid; /* log file #, 0 based */ - uint32 xrecoff; /* byte offset of location in log file */ -} XLogRecPtr; - -#define XLogRecPtrIsInvalid(r) ((r).xrecoff == 0) - +typedef uint64 XLogRecPtr; /* - * Macros for comparing XLogRecPtrs - * - * Beware of passing expressions with side-effects to these macros, - * since the arguments may be evaluated multiple times. + * Zero is used indicate an invalid pointer. Bootstrap skips the first possible + * WAL segment, initializing the first WAL page at XLOG_SEG_SIZE, so no XLOG + * record can begin at zero. */ -#define XLByteLT(a, b) \ - ((a).xlogid < (b).xlogid || \ - ((a).xlogid == (b).xlogid && (a).xrecoff < (b).xrecoff)) - -#define XLByteLE(a, b) \ - ((a).xlogid < (b).xlogid || \ - ((a).xlogid == (b).xlogid && (a).xrecoff <= (b).xrecoff)) - -#define XLByteEQ(a, b) \ - ((a).xlogid == (b).xlogid && (a).xrecoff == (b).xrecoff) - +#define InvalidXLogRecPtr 0 +#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr) /* - * Macro for advancing a record pointer by the specified number of bytes. + * XLogSegNo - physical log file sequence number. */ -#define XLByteAdvance(recptr, nbytes) \ - do { \ - if (recptr.xrecoff + nbytes >= XLogFileSize) \ - { \ - recptr.xlogid += 1; \ - recptr.xrecoff \ - = recptr.xrecoff + nbytes - XLogFileSize; \ - } \ - else \ - recptr.xrecoff += nbytes; \ - } while (0) - +typedef uint64 XLogSegNo; /* * TimeLineID (TLI) - identifies different database histories to prevent @@ -88,7 +49,7 @@ typedef uint32 TimeLineID; * read those buffers except during crash recovery or if wal_level != minimal, * it is a win to use it in all cases where we sync on each write(). We could * allow O_DIRECT with fsync(), but it is unclear if fsync() could process - * writes not buffered in the kernel. Also, O_DIRECT is never enough to force + * writes not buffered in the kernel. Also, O_DIRECT is never enough to force * data to the drives, it merely tries to bypass the kernel cache, so we still * need O_SYNC/O_DSYNC. */ @@ -101,7 +62,7 @@ typedef uint32 TimeLineID; /* * This chunk of hackery attempts to determine which file sync methods * are available on the current platform, and to choose an appropriate - * default method. We assume that fsync() is always available, and that + * default method. We assume that fsync() is always available, and that * configure determined whether fdatasync() is. */ #if defined(O_SYNC) @@ -132,14 +93,4 @@ typedef uint32 TimeLineID; #define DEFAULT_SYNC_METHOD SYNC_METHOD_FSYNC #endif -/* - * Limitation of buffer-alignment for direct IO depends on OS and filesystem, - * but XLOG_BLCKSZ is assumed to be enough for it. - */ -#ifdef O_DIRECT -#define ALIGNOF_XLOG_BUFFER XLOG_BLCKSZ -#else -#define ALIGNOF_XLOG_BUFFER ALIGNOF_BUFFER -#endif - #endif /* XLOG_DEFS_H */ diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h new file mode 100644 index 0000000000..ea873a2d9c --- /dev/null +++ b/src/include/access/xlogreader.h @@ -0,0 +1,126 @@ +/*------------------------------------------------------------------------- + * + * xlogreader.h + * Definitions for the generic XLog reading facility + * + * Portions Copyright (c) 2013-2014, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/access/xlogreader.h + * + * NOTES + * See the definition of the XLogReaderState struct for instructions on + * how to use the XLogReader infrastructure. + * + * The basic idea is to allocate an XLogReaderState via + * XLogReaderAllocate(), and call XLogReadRecord() until it returns NULL. + *------------------------------------------------------------------------- + */ +#ifndef XLOGREADER_H +#define XLOGREADER_H + +#include "access/xlog_internal.h" + +typedef struct XLogReaderState XLogReaderState; + +/* Function type definition for the read_page callback */ +typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader, + XLogRecPtr targetPagePtr, + int reqLen, + XLogRecPtr targetRecPtr, + char *readBuf, + TimeLineID *pageTLI); + +struct XLogReaderState +{ + /* ---------------------------------------- + * Public parameters + * ---------------------------------------- + */ + + /* + * Data input callback (mandatory). + * + * This callback shall read at least reqLen valid bytes of the xlog page + * starting at targetPagePtr, and store them in readBuf. The callback + * shall return the number of bytes read (never more than XLOG_BLCKSZ), or + * -1 on failure. The callback shall sleep, if necessary, to wait for the + * requested bytes to become available. The callback will not be invoked + * again for the same page unless more than the returned number of bytes + * are needed. + * + * targetRecPtr is the position of the WAL record we're reading. Usually + * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs + * to read and verify the page or segment header, before it reads the + * actual WAL record it's interested in. In that case, targetRecPtr can + * be used to determine which timeline to read the page from. + * + * The callback shall set *pageTLI to the TLI of the file the page was + * read from. It is currently used only for error reporting purposes, to + * reconstruct the name of the WAL file where an error occurred. + */ + XLogPageReadCB read_page; + + /* + * System identifier of the xlog files we're about to read. Set to zero + * (the default value) if unknown or unimportant. + */ + uint64 system_identifier; + + /* + * Opaque data for callbacks to use. Not used by XLogReader. + */ + void *private_data; + + /* + * Start and end point of last record read. EndRecPtr is also used as the + * position to read next, if XLogReadRecord receives an invalid recptr. + */ + XLogRecPtr ReadRecPtr; /* start of last record read */ + XLogRecPtr EndRecPtr; /* end+1 of last record read */ + + /* ---------------------------------------- + * private/internal state + * ---------------------------------------- + */ + + /* Buffer for currently read page (XLOG_BLCKSZ bytes) */ + char *readBuf; + + /* last read segment, segment offset, read length, TLI */ + XLogSegNo readSegNo; + uint32 readOff; + uint32 readLen; + TimeLineID readPageTLI; + + /* beginning of last page read, and its TLI */ + XLogRecPtr latestPagePtr; + TimeLineID latestPageTLI; + + /* beginning of the WAL record being read. */ + XLogRecPtr currRecPtr; + + /* Buffer for current ReadRecord result (expandable) */ + char *readRecordBuf; + uint32 readRecordBufSize; + + /* Buffer to hold error message */ + char *errormsg_buf; +}; + +/* Get a new XLogReader */ +extern XLogReaderState *XLogReaderAllocate(XLogPageReadCB pagereadfunc, + void *private_data); + +/* Free an XLogReader */ +extern void XLogReaderFree(XLogReaderState *state); + +/* Read the next XLog record. Returns NULL on end-of-WAL or failure */ +extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, + XLogRecPtr recptr, char **errormsg); + +#ifdef FRONTEND +extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); +#endif /* FRONTEND */ + +#endif /* XLOGREADER_H */ diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h index 6ade4769ca..58f11d919b 100644 --- a/src/include/access/xlogutils.h +++ b/src/include/access/xlogutils.h @@ -3,7 +3,7 @@ * * PostgreSQL transaction log manager utility routines * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlogutils.h diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index 7f0ed6db2b..aebabec453 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -4,7 +4,7 @@ * include file for the bootstrapping code * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -17,20 +17,6 @@ #include "nodes/execnodes.h" -typedef enum -{ - CheckerProcess, - BootstrapProcess, - StartupProcess, - BgWriterProcess, - CheckpointerProcess, - WalWriterProcess, - WalReceiverProcess, -#ifdef PGXC - PoolerProcess, -#endif - NUM_AUXPROCTYPES /* Must be last! */ -} AuxProcType; /* * MAXATTR is the maximum number of attributes in a relation supported @@ -43,7 +29,7 @@ extern Form_pg_attribute attrtypes[MAXATTR]; extern int numattr; -extern void AuxiliaryProcessMain(int argc, char *argv[]); +extern void AuxiliaryProcessMain(int argc, char *argv[]) __attribute__((noreturn)); extern void err_out(void); diff --git a/src/include/c.h b/src/include/c.h index 8b3c5e5996..df22d50d4e 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -9,7 +9,7 @@ * polluting the namespace with lots of stuff... * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/c.h @@ -31,12 +31,13 @@ * 3) standard system types * 4) IsValid macros for system types * 5) offsetof, lengthof, endof, alignment - * 6) widely useful macros - * 7) random stuff - * 8) system-specific hacks + * 6) assertions + * 7) widely useful macros + * 8) random stuff + * 9) system-specific hacks * * NOTE: since this file is included by both frontend and backend modules, it's - * almost certainly wrong to put an "extern" declaration here. typedefs and + * almost certainly wrong to put an "extern" declaration here. typedefs and * macros are the kind of thing that might go here. * *---------------------------------------------------------------- @@ -44,19 +45,26 @@ #ifndef C_H #define C_H -/* - * We have to include stdlib.h here because it defines many of these macros - * on some platforms, and we only want our definitions used if stdlib.h doesn't - * have its own. The same goes for stddef and stdarg if present. - */ +#include "postgres_ext.h" + +/* Must undef pg_config_ext.h symbols before including pg_config.h */ +#undef PG_INT64_TYPE #include "pg_config.h" #include "pg_config_manual.h" /* must be after pg_config.h */ -#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 will include further - * down */ + +/* + * We always rely on the WIN32 macro being set by our build system, + * but _WIN32 is the compiler pre-defined macro. So make sure we define + * WIN32 whenever _WIN32 is set, to facilitate standalone building. + */ +#if defined(_WIN32) && !defined(WIN32) +#define WIN32 +#endif + +#if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */ #include "pg_config_os.h" /* must be before any system header files */ #endif -#include "postgres_ext.h" #if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H) #define errcode __msvc_errcode @@ -64,6 +72,12 @@ #undef errcode #endif +/* + * We have to include stdlib.h here because it defines many of these macros + * on some platforms, and we only want our definitions used if stdlib.h doesn't + * have its own. The same goes for stddef and stdarg if present. + */ + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -103,7 +117,7 @@ /* * Use this to mark string constants as needing translation at some later - * time, rather than immediately. This is useful for cases where you need + * time, rather than immediately. This is useful for cases where you need * access to the original string and translated string, and for cases where * immediate translation is not possible, like when initializing global * variables. @@ -125,28 +139,12 @@ * CppConcat * Concatenate two arguments together, using the C preprocessor. * - * Note: the standard Autoconf macro AC_C_STRINGIZE actually only checks - * whether #identifier works, but if we have that we likely have ## too. + * Note: There used to be support here for pre-ANSI C compilers that didn't + * support # and ##. Nowadays, these macros are just for clarity and/or + * backward compatibility with existing PostgreSQL code. */ -#if defined(HAVE_STRINGIZE) - #define CppAsString(identifier) #identifier #define CppConcat(x, y) x##y -#else /* !HAVE_STRINGIZE */ - -#define CppAsString(identifier) "identifier" - -/* - * CppIdentity -- On Reiser based cpp's this is used to concatenate - * two tokens. That is - * CppIdentity(A)B ==> AB - * We renamed it to _private_CppIdentity because it should not - * be referenced outside this file. On other cpp's it - * produces A B. - */ -#define _priv_CppIdentity(x)x -#define CppConcat(x, y) _priv_CppIdentity(x)y -#endif /* !HAVE_STRINGIZE */ /* * dummyret is used to set return values in macros that use ?: to make @@ -329,8 +327,6 @@ typedef signed int Offset; /* * Common Postgres datatype names (as used in the catalogs) */ -typedef int16 int2; -typedef int32 int4; typedef float float4; typedef double float8; @@ -365,6 +361,7 @@ typedef uint32 MultiXactOffset; typedef uint32 CommandId; #define FirstCommandId ((CommandId) 0) +#define InvalidCommandId (~(CommandId)0) /* * Array indexing support @@ -379,7 +376,7 @@ typedef struct * Variable-length datatypes all share the 'struct varlena' header. * * NOTE: for TOASTable types, this is an oversimplification, since the value - * may be compressed or moved out-of-line. However datatype-specific routines + * may be compressed or moved out-of-line. However datatype-specific routines * are mostly content to deal with de-TOASTed values only, and of course * client-side routines should never see a TOASTed value. But even in a * de-TOASTed value, beware of touching vl_len_ directly, as its representation @@ -409,7 +406,7 @@ typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ /* * Specialized array types. These are physically laid out just the same * as regular arrays (so that the regular array subscripting code works - * with them). They exist as distinct types mostly for historical reasons: + * with them). They exist as distinct types mostly for historical reasons: * they have nonstandard I/O behavior which we don't want to change for fear * of breaking applications that look at the system catalogs. There is also * an implementation issue for oidvector: it's part of the primary key for @@ -424,7 +421,7 @@ typedef struct Oid elemtype; int dim1; int lbound1; - int2 values[1]; /* VARIABLE LENGTH ARRAY */ + int16 values[1]; /* VARIABLE LENGTH ARRAY */ } int2vector; /* VARIABLE LENGTH STRUCT */ typedef struct @@ -452,7 +449,7 @@ typedef NameData *Name; /* * Support macros for escaping strings. escape_backslash should be TRUE - * if generating a non-standard-conforming string. Prefixing a string + * if generating a non-standard-conforming string. Prefixing a string * with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming. * Beware of multiple evaluation of the "ch" argument! */ @@ -482,7 +479,7 @@ typedef NameData *Name; * True iff pointer is properly aligned to point to the given type. */ #define PointerIsAligned(pointer, type) \ - (((intptr_t)(pointer) % (sizeof (type))) == 0) + (((uintptr_t)(pointer) % (sizeof (type))) == 0) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) @@ -528,7 +525,7 @@ typedef NameData *Name; */ #define TYPEALIGN(ALIGNVAL,LEN) \ - (((intptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((intptr_t) ((ALIGNVAL) - 1))) + (((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) #define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) @@ -539,7 +536,7 @@ typedef NameData *Name; #define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) #define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ - (((intptr_t) (LEN)) & ~((intptr_t) ((ALIGNVAL) - 1))) + (((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1))) #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) @@ -547,8 +544,147 @@ typedef NameData *Name; #define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) #define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) +/* + * The above macros will not work with types wider than uintptr_t, like with + * uint64 on 32-bit platforms. That's not problem for the usual use where a + * pointer or a length is aligned, but for the odd case that you need to + * align something (potentially) wider, use TYPEALIGN64. + */ +#define TYPEALIGN64(ALIGNVAL,LEN) \ + (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1))) + +/* we don't currently need wider versions of the other ALIGN macros */ +#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN)) + /* ---------------------------------------------------------------- - * Section 6: widely useful macros + * Section 6: assertions + * ---------------------------------------------------------------- + */ + +/* + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. + * - plai 9/5/90 + * + * It should _NOT_ be defined in releases or in benchmark copies + */ + +/* + * Assert() can be used in both frontend and backend code. In frontend code it + * just calls the standard assert, if it's available. If use of assertions is + * not configured, it does nothing. + */ +#ifndef USE_ASSERT_CHECKING + +#define Assert(condition) +#define AssertMacro(condition) ((void)true) +#define AssertArg(condition) +#define AssertState(condition) +#define Trap(condition, errorType) +#define TrapMacro(condition, errorType) (true) + +#elif defined(FRONTEND) + +#include <assert.h> +#define Assert(p) assert(p) +#define AssertMacro(p) ((void) assert(p)) +#define AssertArg(condition) assert(condition) +#define AssertState(condition) assert(condition) +#else /* USE_ASSERT_CHECKING && !FRONTEND */ + +/* + * Trap + * Generates an exception if the given condition is true. + */ +#define Trap(condition, errorType) \ + do { \ + if ((assert_enabled) && (condition)) \ + ExceptionalCondition(CppAsString(condition), (errorType), \ + __FILE__, __LINE__); \ + } while (0) + +/* + * TrapMacro is the same as Trap but it's intended for use in macros: + * + * #define foo(x) (AssertMacro(x != 0), bar(x)) + * + * Isn't CPP fun? + */ +#define TrapMacro(condition, errorType) \ + ((bool) ((! assert_enabled) || ! (condition) || \ + (ExceptionalCondition(CppAsString(condition), (errorType), \ + __FILE__, __LINE__), 0))) + +#define Assert(condition) \ + Trap(!(condition), "FailedAssertion") + +#define AssertMacro(condition) \ + ((void) TrapMacro(!(condition), "FailedAssertion")) + +#define AssertArg(condition) \ + Trap(!(condition), "BadArgument") + +#define AssertState(condition) \ + Trap(!(condition), "BadState") +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ + + +/* + * Macros to support compile-time assertion checks. + * + * If the "condition" (a compile-time-constant expression) evaluates to false, + * throw a compile error using the "errmessage" (a string literal). + * + * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic + * placement restrictions. These macros make it safe to use as a statement + * or in an expression, respectively. + * + * Otherwise we fall back on a kluge that assumes the compiler will complain + * about a negative width for a struct bit-field. This will not include a + * helpful error message, but it beats not getting an error at all. + */ +#ifdef HAVE__STATIC_ASSERT +#define StaticAssertStmt(condition, errmessage) \ + do { _Static_assert(condition, errmessage); } while(0) +#define StaticAssertExpr(condition, errmessage) \ + ({ StaticAssertStmt(condition, errmessage); true; }) +#else /* !HAVE__STATIC_ASSERT */ +#define StaticAssertStmt(condition, errmessage) \ + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) +#define StaticAssertExpr(condition, errmessage) \ + StaticAssertStmt(condition, errmessage) +#endif /* HAVE__STATIC_ASSERT */ + + +/* + * Compile-time checks that a variable (or expression) has the specified type. + * + * AssertVariableIsOfType() can be used as a statement. + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) + * + * If we don't have __builtin_types_compatible_p, we can still assert that + * the types have the same size. This is far from ideal (especially on 32-bit + * platforms) but it provides at least some coverage. + */ +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + ((void) StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#define AssertVariableIsOfType(varname, typename) \ + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename)) +#define AssertVariableIsOfTypeMacro(varname, typename) \ + ((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \ + CppAsString(varname) " does not have type " CppAsString(typename))) +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + + +/* ---------------------------------------------------------------- + * Section 7: widely useful macros * ---------------------------------------------------------------- */ /* @@ -581,7 +717,7 @@ typedef NameData *Name; * datum) and add a null, do not do it with StrNCpy(..., len+1). That * might seem to work, but it fetches one byte more than there is in the * text object. One fine day you'll have a SIGSEGV because there isn't - * another byte before the end of memory. Don't laugh, we've had real + * another byte before the end of memory. Don't laugh, we've had real * live bug reports from real live users over exactly this mistake. * Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead. */ @@ -607,7 +743,7 @@ typedef NameData *Name; * Exactly the same as standard library function memset(), but considerably * faster for zeroing small word-aligned structures (such as parsetree nodes). * This has to be a macro because the main point is to avoid function-call - * overhead. However, we have also found that the loop is faster than + * overhead. However, we have also found that the loop is faster than * native libc memset() on some platforms, even those with assembler * memset() functions. More research needs to be done, perhaps with * MEMSET_LOOP_LIMIT tests in configure. @@ -620,7 +756,7 @@ typedef NameData *Name; int _val = (val); \ Size _len = (len); \ \ - if ((((intptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ + if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ (_len & LONG_ALIGN_MASK) == 0 && \ _val == 0 && \ _len <= MEMSET_LOOP_LIMIT && \ @@ -691,8 +827,40 @@ typedef NameData *Name; } while (0) +/* + * Mark a point as unreachable in a portable fashion. This should preferably + * be something that the compiler understands, to aid code generation. + * In assert-enabled builds, we prefer abort() for debugging reasons. + */ +#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __builtin_unreachable() +#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) +#define pg_unreachable() __assume(0) +#else +#define pg_unreachable() abort() +#endif + + +/* + * Function inlining support -- Allow modules to define functions that may be + * inlined, if the compiler supports it. + * + * The function bodies must be defined in the module header prefixed by + * STATIC_IF_INLINE, protected by a cpp symbol that the module's .c file must + * define. If the compiler doesn't support inline functions, the function + * definitions are pulled in by the .c file as regular (not inline) symbols. + * + * The header must also declare the functions' prototypes, protected by + * !PG_USE_INLINE. + */ +#ifdef PG_USE_INLINE +#define STATIC_IF_INLINE static inline +#else +#define STATIC_IF_INLINE +#endif /* PG_USE_INLINE */ + /* ---------------------------------------------------------------- - * Section 7: random stuff + * Section 8: random stuff * ---------------------------------------------------------------- */ @@ -746,10 +914,10 @@ typedef NameData *Name; /* ---------------------------------------------------------------- - * Section 8: system-specific hacks + * Section 9: system-specific hacks * * This should be limited to things that absolutely have to be - * included in every source file. The port-specific header file + * included in every source file. The port-specific header file * is usually a better place for this sort of thing. * ---------------------------------------------------------------- */ @@ -758,7 +926,7 @@ typedef NameData *Name; * NOTE: this is also used for opening text files. * WIN32 treats Control-Z as EOF in files opened in text mode. * Therefore, we open files in binary mode on Win32 so we can read - * literal control-Z. The other affect is that we see CRLF, but + * literal control-Z. The other affect is that we see CRLF, but * that is OK because we can already handle those cleanly. */ #if defined(WIN32) || defined(__CYGWIN__) diff --git a/src/include/catalog/binary_upgrade.h b/src/include/catalog/binary_upgrade.h new file mode 100644 index 0000000000..f39017cfdf --- /dev/null +++ b/src/include/catalog/binary_upgrade.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * binary_upgrade.h + * variables used for binary upgrades + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/binary_upgrade.h + * + *------------------------------------------------------------------------- + */ +#ifndef BINARY_UPGRADE_H +#define BINARY_UPGRADE_H + +extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_array_pg_type_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_type_oid; + +extern PGDLLIMPORT Oid binary_upgrade_next_heap_pg_class_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_index_pg_class_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_toast_pg_class_oid; + +extern PGDLLIMPORT Oid binary_upgrade_next_pg_enum_oid; +extern PGDLLIMPORT Oid binary_upgrade_next_pg_authid_oid; + +#endif /* BINARY_UPGRADE_H */ diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 5a1861da6e..56009efebf 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/catalog.h @@ -25,39 +25,20 @@ */ #include "catalog/catversion.h" /* pgrminclude ignore */ #include "catalog/pg_class.h" -#include "storage/relfilenode.h" #include "utils/relcache.h" #define OIDCHARS 10 /* max chars printed by %u */ #define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \ CppAsString2(CATALOG_VERSION_NO) -extern const char *forkNames[]; -extern ForkNumber forkname_to_number(char *forkName); -extern int forkname_chars(const char *str, ForkNumber *); - -extern char *relpathbackend(RelFileNode rnode, BackendId backend, - ForkNumber forknum); -extern char *GetDatabasePath(Oid dbNode, Oid spcNode); - -/* First argument is a RelFileNodeBackend */ -#ifdef XCP -#define relpath(rnode, forknum) \ - relpathbackend((rnode).node, InvalidBackendId, (forknum)) -#else -#define relpath(rnode, forknum) \ - relpathbackend((rnode).node, (rnode).backend, (forknum)) -#endif - -/* First argument is a RelFileNode */ -#define relpathperm(rnode, forknum) \ - relpathbackend((rnode), InvalidBackendId, (forknum)) extern bool IsSystemRelation(Relation relation); extern bool IsToastRelation(Relation relation); +extern bool IsCatalogRelation(Relation relation); -extern bool IsSystemClass(Form_pg_class reltuple); +extern bool IsSystemClass(Oid relid, Form_pg_class reltuple); extern bool IsToastClass(Form_pg_class reltuple); +extern bool IsCatalogClass(Oid relid, Form_pg_class reltuple); extern bool IsSystemNamespace(Oid namespaceId); extern bool IsToastNamespace(Oid namespaceId); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index fe020a692c..93afbbe033 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -4,7 +4,7 @@ * "Catalog version number" for PostgreSQL. * * The catalog version number is used to flag incompatible changes in - * the PostgreSQL system catalogs. Whenever anyone changes the format of + * the PostgreSQL system catalogs. Whenever anyone changes the format of * a system catalog relation, or adds, deletes, or modifies standard * catalog entries in such a way that an updated backend wouldn't work * with an old database (or vice versa), the catalog version number @@ -34,7 +34,7 @@ * database contents or layout, such as altering tuple headers. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/catversion.h @@ -53,10 +53,6 @@ */ /* yyyymmddN */ -#ifdef PGXC -#define CATALOG_VERSION_NO 201204301 -#else -#define CATALOG_VERSION_NO 201204301 -#endif +#define CATALOG_VERSION_NO 201406051 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 79afd25651..54e9d25309 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -4,7 +4,7 @@ * Routines to support inter-object dependencies. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -59,7 +59,7 @@ * DEPENDENCY_PIN ('p'): there is no dependent object; this type of entry * is a signal that the system itself depends on the referenced object, * and so that object must never be deleted. Entries of this type are - * created only during initdb. The fields for the dependent object + * created only during initdb. The fields for the dependent object * contain zeroes. * * Other dependency flavors may be needed in future. @@ -152,7 +152,8 @@ typedef enum ObjectClass #endif OCLASS_DEFACL, /* pg_default_acl */ OCLASS_EXTENSION, /* pg_extension */ - MAX_OCLASS /* MUST BE LAST */ + OCLASS_EVENT_TRIGGER, /* pg_event_trigger */ + MAX_OCLASS /* MUST BE LAST */ } ObjectClass; @@ -187,9 +188,6 @@ extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, extern ObjectClass getObjectClass(const ObjectAddress *object); -extern char *getObjectDescription(const ObjectAddress *object); -extern char *getObjectDescriptionOids(Oid classid, Oid objid); - extern ObjectAddresses *new_object_addresses(void); extern void add_exact_object_address(const ObjectAddress *object, diff --git a/src/include/catalog/duplicate_oids b/src/include/catalog/duplicate_oids index be65f4329d..b5bd5db04d 100755 --- a/src/include/catalog/duplicate_oids +++ b/src/include/catalog/duplicate_oids @@ -1,30 +1,36 @@ -#!/bin/sh -# -# duplicate_oids -# -# src/include/catalog/duplicate_oids -# -# finds manually-assigned oids that are duplicated in the system tables. -# -# run this script in src/include/catalog. -# +#!/usr/bin/perl -# note: we exclude BKI_BOOTSTRAP relations since they are expected to have -# matching DATA lines in pg_class.h and pg_type.h +use strict; +use warnings; -cat pgxc_*.h pg_*.h toasting.h indexing.h | \ -egrep -v -e '^CATALOG\(.*BKI_BOOTSTRAP' | \ -sed -n -e 's/^DATA(insert *OID *= *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^CATALOG([^,]*, *\([0-9][0-9]*\).*BKI_ROWTYPE_OID(\([0-9][0-9]*\)).*$/\1,\2/p' \ - -e 's/^CATALOG([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_INDEX([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_UNIQUE_INDEX([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_TOAST([^,]*, *\([0-9][0-9]*\), *\([0-9][0-9]*\).*$/\1,\2/p' | \ -tr ',' '\n' | \ -sort -n | \ -uniq -d | \ -grep '.' +BEGIN +{ + @ARGV = (glob("pg_*.h"), glob("pgxc_*.h"), qw(indexing.h toasting.h)); +} -# nonzero exit code if lines were produced -[ $? -eq 1 ] -exit +my %oidcounts; + +while (<>) +{ + next if /^CATALOG\(.*BKI_BOOTSTRAP/; + next + unless /^DATA\(insert *OID *= *(\d+)/ + || /^CATALOG\([^,]*, *(\d+).*BKI_ROWTYPE_OID\((\d+)\)/ + || /^CATALOG\([^,]*, *(\d+)/ + || /^DECLARE_INDEX\([^,]*, *(\d+)/ + || /^DECLARE_UNIQUE_INDEX\([^,]*, *(\d+)/ + || /^DECLARE_TOAST\([^,]*, *(\d+), *(\d+)/; + $oidcounts{$1}++; + $oidcounts{$2}++ if $2; +} + +my $found = 0; + +foreach my $oid (sort { $a <=> $b } keys %oidcounts) +{ + next unless $oidcounts{$oid} > 1; + $found = 1; + print "$oid\n"; +} + +exit $found; diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h index f973580e5f..cb40c07063 100644 --- a/src/include/catalog/genbki.h +++ b/src/include/catalog/genbki.h @@ -9,7 +9,7 @@ * bootstrap file from these header files.) * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/genbki.h @@ -27,7 +27,7 @@ * * Variable-length catalog fields (except possibly the first not nullable one) * should not be visible in C structures, so they are made invisible by #ifdefs - * of an undefined symbol. See also MARKNOTNULL in bootstrap.c for how this is + * of an undefined symbol. See also MARKNOTNULL in bootstrap.c for how this is * handled. */ #undef CATALOG_VARLEN diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 88a61ce3d5..2a452ba65d 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -4,7 +4,7 @@ * prototypes for functions in backend/catalog/heap.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -68,7 +68,8 @@ extern Oid heap_create_with_catalog(const char *relname, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, - bool allow_system_table_mods); + bool allow_system_table_mods, + bool is_internal); extern void heap_create_init_fork(Relation rel); @@ -96,9 +97,11 @@ extern List *AddRelationNewConstraints(Relation rel, List *newColDefaults, List *newConstraints, bool allow_merge, - bool is_local); + bool is_local, + bool is_internal); -extern void StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr); +extern void StoreAttrDefault(Relation rel, AttrNumber attnum, + Node *expr, bool is_internal); extern Node *cookDefault(ParseState *pstate, Node *raw_default, @@ -108,6 +111,7 @@ extern Node *cookDefault(ParseState *pstate, extern void DeleteRelationTuple(Oid relid); extern void DeleteAttributeTuples(Oid relid); +extern void DeleteSystemAttributeTuples(Oid relid); extern void RemoveAttributeById(Oid relid, AttrNumber attnum); extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, DropBehavior behavior, bool complain, bool internal); diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 7c8198f31e..006b1801a3 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -4,7 +4,7 @@ * prototypes for catalog/index.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/index.h @@ -27,6 +27,15 @@ typedef void (*IndexBuildCallback) (Relation index, bool tupleIsAlive, void *state); +/* Action code for index_set_state_flags */ +typedef enum +{ + INDEX_CREATE_SET_READY, + INDEX_CREATE_SET_VALID, + INDEX_DROP_CLEAR_VALID, + INDEX_DROP_SET_DEAD +} IndexStateFlagsAction; + extern void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, @@ -50,7 +59,8 @@ extern Oid index_create(Relation heapRelation, bool initdeferred, bool allow_system_table_mods, bool skip_build, - bool concurrent); + bool concurrent, + bool is_internal); extern void index_constraint_create(Relation heapRelation, Oid indexRelationId, @@ -61,7 +71,9 @@ extern void index_constraint_create(Relation heapRelation, bool initdeferred, bool mark_as_primary, bool update_pgindex, - bool allow_system_table_mods); + bool remove_old_dependencies, + bool allow_system_table_mods, + bool is_internal); extern void index_drop(Oid indexId, bool concurrent); @@ -88,6 +100,8 @@ extern double IndexBuildHeapScan(Relation heapRelation, extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot); +extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action); + extern void reindex_index(Oid indexId, bool skip_constraint_checks); /* Flag bits for reindex_relation(): */ diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 69bdd8443a..d013fce83b 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -5,7 +5,7 @@ * on system catalogs * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -107,6 +107,8 @@ DECLARE_UNIQUE_INDEX(pg_class_oid_index, 2662, on pg_class using btree(oid oid_o #define ClassOidIndexId 2662 DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index, 2663, on pg_class using btree(relname name_ops, relnamespace oid_ops)); #define ClassNameNspIndexId 2663 +DECLARE_INDEX(pg_class_tblspc_relfilenode_index, 3455, on pg_class using btree(reltablespace oid_ops, relfilenode oid_ops)); +#define ClassTblspcRelfilenodeIndexId 3455 DECLARE_UNIQUE_INDEX(pg_collation_name_enc_nsp_index, 3164, on pg_collation using btree(collname name_ops, collencoding int4_ops, collnamespace oid_ops)); #define CollationNameEncNspIndexId 3164 @@ -235,6 +237,11 @@ DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, on pg_trigger using DECLARE_UNIQUE_INDEX(pg_trigger_oid_index, 2702, on pg_trigger using btree(oid oid_ops)); #define TriggerOidIndexId 2702 +DECLARE_UNIQUE_INDEX(pg_event_trigger_evtname_index, 3467, on pg_event_trigger using btree(evtname name_ops)); +#define EventTriggerNameIndexId 3467 +DECLARE_UNIQUE_INDEX(pg_event_trigger_oid_index, 3468, on pg_event_trigger using btree(oid oid_ops)); +#define EventTriggerOidIndexId 3468 + DECLARE_UNIQUE_INDEX(pg_ts_config_cfgname_index, 3608, on pg_ts_config using btree(cfgname name_ops, cfgnamespace oid_ops)); #define TSConfigNameNspIndexId 3608 DECLARE_UNIQUE_INDEX(pg_ts_config_oid_index, 3712, on pg_ts_config using btree(oid oid_ops)); diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 0c2d245e90..e45815b1d9 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/namespace.h @@ -25,7 +25,7 @@ /* * This structure holds a list of possible functions or operators - * found by namespace lookup. Each function/operator is identified + * found by namespace lookup. Each function/operator is identified * by OID and by argument types; the list must be pruned by type * resolution rules that are embodied in the parser, not here. * See FuncnameGetCandidates's comments for more info. @@ -76,11 +76,13 @@ extern bool TypeIsVisible(Oid typid); extern FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, - bool expand_defaults); + bool expand_defaults, + bool missing_ok); extern bool FunctionIsVisible(Oid funcid); extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright); -extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind); +extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind, + bool missing_schema_ok); extern bool OperatorIsVisible(Oid oprid); extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); @@ -111,7 +113,7 @@ extern void DeconstructQualifiedName(List *names, char **nspname_p, char **objname_p); extern Oid LookupNamespaceNoError(const char *nspname); -extern Oid LookupExplicitNamespace(const char *nspname); +extern Oid LookupExplicitNamespace(const char *nspname, bool missing_ok); extern Oid get_namespace_oid(const char *nspname, bool missing_ok); extern Oid LookupCreationNamespace(const char *nspname); @@ -136,12 +138,13 @@ extern void ForgetTempTableNamespace(void); extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context); extern OverrideSearchPath *CopyOverrideSearchPath(OverrideSearchPath *path); +extern bool OverrideSearchPathMatchesCurrent(OverrideSearchPath *path); extern void PushOverrideSearchPath(OverrideSearchPath *newpath); extern void PopOverrideSearchPath(void); extern Oid get_collation_oid(List *collname, bool missing_ok); extern Oid get_conversion_oid(List *conname, bool missing_ok); -extern Oid FindDefaultConversionProc(int4 for_encoding, int4 to_encoding); +extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding); /* initialization & transaction cleanup code */ extern void InitializeSearchPath(void); diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h index 3b40dbc492..4fdd0567ca 100644 --- a/src/include/catalog/objectaccess.h +++ b/src/include/catalog/objectaccess.h @@ -3,7 +3,7 @@ * * Object access hooks. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ @@ -12,7 +12,7 @@ /* * Object access hooks are intended to be called just before or just after - * performing certain actions on a SQL object. This is intended as + * performing certain actions on a SQL object. This is intended as * infrastructure for security or logging pluggins. * * OAT_POST_CREATE should be invoked just after the object is created. @@ -22,15 +22,46 @@ * OAT_DROP should be invoked just before deletion of objects; typically * deleteOneObject(). Its arguments are packed within ObjectAccessDrop. * + * OAT_POST_ALTER should be invoked just after the object is altered, + * but before the command counter is incremented. An extension using the + * hook can use a current MVCC snapshot to get the old version of the tuple, + * and can use SnapshotSelf to get the new version of the tuple. + * + * OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under + * a particular namespace. This event is equivalent to usage permission + * on a schema under the default access control mechanism. + * + * OAT_FUNCTION_EXECUTE should be invoked prior to function execution. + * This event is almost equivalent to execute permission on functions, + * except for the case when execute permission is checked during object + * creation or altering, because OAT_POST_CREATE or OAT_POST_ALTER are + * sufficient for extensions to track these kind of checks. + * * Other types may be added in the future. */ typedef enum ObjectAccessType { OAT_POST_CREATE, OAT_DROP, + OAT_POST_ALTER, + OAT_NAMESPACE_SEARCH, + OAT_FUNCTION_EXECUTE } ObjectAccessType; /* + * Arguments of OAT_POST_CREATE event + */ +typedef struct +{ + /* + * This flag informs extensions whether the context of this creation is + * invoked by user's operations, or not. E.g, it shall be dealt as + * internal stuff on toast tables or indexes due to type changes. + */ + bool is_internal; +} ObjectAccessPostCreate; + +/* * Arguments of OAT_DROP event */ typedef struct @@ -43,21 +74,112 @@ typedef struct } ObjectAccessDrop; /* - * Hook, and a macro to invoke it. + * Arguments of OAT_POST_ALTER event + */ +typedef struct +{ + /* + * This identifier is used when system catalog takes two IDs to identify a + * particular tuple of the catalog. It is only used when the caller want + * to identify an entry of pg_inherits, pg_db_role_setting or + * pg_user_mapping. Elsewhere, InvalidOid should be set. + */ + Oid auxiliary_id; + + /* + * If this flag is set, the user hasn't requested that the object be + * altered, but we're doing it anyway for some internal reason. + * Permissions-checking hooks may want to skip checks if, say, we're alter + * the constraints of a temporary heap during CLUSTER. + */ + bool is_internal; +} ObjectAccessPostAlter; + +/* + * Arguments of OAT_NAMESPACE_SEARCH */ +typedef struct +{ + /* + * If true, hook should report an error when permission to search this + * schema is denied. + */ + bool ereport_on_violation; + + /* + * This is, in essence, an out parameter. Core code should initialize + * this to true, and any extension that wants to deny access should reset + * it to false. But an extension should be careful never to store a true + * value here, so that in case there are multiple extensions access is + * only allowed if all extensions agree. + */ + bool result; +} ObjectAccessNamespaceSearch; + +/* Plugin provides a hook function matching this signature. */ typedef void (*object_access_hook_type) (ObjectAccessType access, Oid classId, Oid objectId, int subId, void *arg); +/* Plugin sets this variable to a suitable hook function. */ extern PGDLLIMPORT object_access_hook_type object_access_hook; -#define InvokeObjectAccessHook(access,classId,objectId,subId,arg) \ +/* Core code uses these functions to call the hook (see macros below). */ +extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, + bool is_internal); +extern void RunObjectDropHook(Oid classId, Oid objectId, int subId, + int dropflags); +extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, + Oid auxiliaryId, bool is_internal); +extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation); +extern void RunFunctionExecuteHook(Oid objectId); + +/* + * The following macros are wrappers around the functions above; these should + * normally be used to invoke the hook in lieu of calling the above functions + * directly. + */ + +#define InvokeObjectPostCreateHook(classId,objectId,subId) \ + InvokeObjectPostCreateHookArg((classId),(objectId),(subId),false) +#define InvokeObjectPostCreateHookArg(classId,objectId,subId,is_internal) \ do { \ if (object_access_hook) \ - (*object_access_hook)((access),(classId), \ - (objectId),(subId),(arg)); \ + RunObjectPostCreateHook((classId),(objectId),(subId), \ + (is_internal)); \ + } while(0) + +#define InvokeObjectDropHook(classId,objectId,subId) \ + InvokeObjectDropHookArg((classId),(objectId),(subId),0) +#define InvokeObjectDropHookArg(classId,objectId,subId,dropflags) \ + do { \ + if (object_access_hook) \ + RunObjectDropHook((classId),(objectId),(subId), \ + (dropflags)); \ + } while(0) + +#define InvokeObjectPostAlterHook(classId,objectId,subId) \ + InvokeObjectPostAlterHookArg((classId),(objectId),(subId), \ + InvalidOid,false) +#define InvokeObjectPostAlterHookArg(classId,objectId,subId, \ + auxiliaryId,is_internal) \ + do { \ + if (object_access_hook) \ + RunObjectPostAlterHook((classId),(objectId),(subId), \ + (auxiliaryId),(is_internal)); \ + } while(0) + +#define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \ + (!object_access_hook \ + ? true \ + : RunNamespaceSearchHook((objectId), (ereport_on_violation))) + +#define InvokeFunctionExecuteHook(objectId) \ + do { \ + if (object_access_hook) \ + RunFunctionExecuteHook(objectId); \ } while(0) #endif /* OBJECTACCESS_H */ diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h index 0af09c616d..2a9431d0d3 100644 --- a/src/include/catalog/objectaddress.h +++ b/src/include/catalog/objectaddress.h @@ -3,7 +3,7 @@ * objectaddress.h * functions for working with object addresses * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/objectaddress.h @@ -13,8 +13,9 @@ #ifndef OBJECTADDRESS_H #define OBJECTADDRESS_H -#include "nodes/parsenodes.h" +#include "nodes/pg_list.h" #include "storage/lock.h" +#include "utils/acl.h" #include "utils/relcache.h" /* @@ -37,4 +38,24 @@ extern void check_object_ownership(Oid roleid, extern Oid get_object_namespace(const ObjectAddress *address); -#endif /* PARSE_OBJECT_H */ +extern bool is_objectclass_supported(Oid class_id); +extern Oid get_object_oid_index(Oid class_id); +extern int get_object_catcache_oid(Oid class_id); +extern int get_object_catcache_name(Oid class_id); +extern AttrNumber get_object_attnum_name(Oid class_id); +extern AttrNumber get_object_attnum_namespace(Oid class_id); +extern AttrNumber get_object_attnum_owner(Oid class_id); +extern AttrNumber get_object_attnum_acl(Oid class_id); +extern AclObjectKind get_object_aclkind(Oid class_id); +extern bool get_object_namensp_unique(Oid class_id); + +extern HeapTuple get_catalog_object_by_oid(Relation catalog, + Oid objectId); + +extern char *getObjectDescription(const ObjectAddress *object); +extern char *getObjectDescriptionOids(Oid classid, Oid objid); + +extern char *getObjectTypeDescription(const ObjectAddress *object); +extern char *getObjectIdentity(const ObjectAddress *address); + +#endif /* OBJECTADDRESS_H */ diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 7bf70e4ff8..a960bd9b29 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -10,7 +10,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_aggregate.h @@ -38,20 +38,31 @@ #endif * * aggfnoid pg_proc OID of the aggregate itself + * aggkind aggregate kind, see AGGKIND_ categories below + * aggnumdirectargs number of arguments that are "direct" arguments * aggtransfn transition function #ifdef PGXC * aggcollectfn collectition function #endif * aggfinalfn final function (0 if none) + * aggmtransfn forward function for moving-aggregate mode (0 if none) + * aggminvtransfn inverse function for moving-aggregate mode (0 if none) + * aggmfinalfn final function for moving-aggregate mode (0 if none) + * aggfinalextra true to pass extra dummy arguments to aggfinalfn + * aggmfinalextra true to pass extra dummy arguments to aggmfinalfn * aggsortop associated sort operator (0 if none) * aggtranstype type of aggregate's transition (state) data #ifdef PGXC * aggcollecttype type of aggregate's collection (state) data #endif + * aggtransspace estimated size of state data (0 for default estimate) + * aggmtranstype type of moving-aggregate state data (0 if none) + * aggmtransspace estimated size of moving-agg state (0 for default est) * agginitval initial value for transition state (can be NULL) #ifdef PGXC * agginitcollect initial value for collection state (can be NULL) #endif + * aggminitval initial value for moving-agg state (can be NULL) * ---------------------------------------------------------------- */ #define AggregateRelationId 2600 @@ -59,16 +70,27 @@ CATALOG(pg_aggregate,2600) BKI_WITHOUT_OIDS { regproc aggfnoid; + char aggkind; + int16 aggnumdirectargs; regproc aggtransfn; regproc aggcollectfn; /* PGXC */ regproc aggfinalfn; + regproc aggmtransfn; + regproc aggminvtransfn; + regproc aggmfinalfn; + bool aggfinalextra; + bool aggmfinalextra; Oid aggsortop; Oid aggtranstype; Oid aggcollecttype; /* PGXC */ + int32 aggtransspace; + Oid aggmtranstype; + int32 aggmtransspace; #ifdef CATALOG_VARLEN /* variable-length fields start here */ text agginitval; text agginitcollect; /* PGXC, VARIABLE LENGTH FIELD */ + text aggminitval; #endif } FormData_pg_aggregate; @@ -84,27 +106,42 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; * ---------------- */ -#ifdef PGXC -#define Natts_pg_aggregate 9 +#define Natts_pg_aggregate 20 #define Anum_pg_aggregate_aggfnoid 1 -#define Anum_pg_aggregate_aggtransfn 2 -#define Anum_pg_aggregate_aggcollectfn 3 -#define Anum_pg_aggregate_aggfinalfn 4 -#define Anum_pg_aggregate_aggsortop 5 -#define Anum_pg_aggregate_aggtranstype 6 -#define Anum_pg_aggregate_aggcollecttype 7 -#define Anum_pg_aggregate_agginitval 8 -#define Anum_pg_aggregate_agginitcollect 9 -#endif -#ifdef PGXC -//#define Natts_pg_aggregate 6 -//#define Anum_pg_aggregate_aggfnoid 1 -//#define Anum_pg_aggregate_aggtransfn 2 -//#define Anum_pg_aggregate_aggfinalfn 3 -//#define Anum_pg_aggregate_aggsortop 4 -//#define Anum_pg_aggregate_aggtranstype 5 -//#define Anum_pg_aggregate_agginitval 6 -#endif +#define Anum_pg_aggregate_aggkind 2 +#define Anum_pg_aggregate_aggnumdirectargs 3 +#define Anum_pg_aggregate_aggtransfn 4 +#define Anum_pg_aggregate_aggcollectfn 5 +#define Anum_pg_aggregate_aggfinalfn 6 +#define Anum_pg_aggregate_aggmtransfn 7 +#define Anum_pg_aggregate_aggminvtransfn 8 +#define Anum_pg_aggregate_aggmfinalfn 9 +#define Anum_pg_aggregate_aggfinalextra 10 +#define Anum_pg_aggregate_aggmfinalextra 11 +#define Anum_pg_aggregate_aggsortop 12 +#define Anum_pg_aggregate_aggtranstype 13 +#define Anum_pg_aggregate_aggcollecttype 14 +#define Anum_pg_aggregate_aggtransspace 15 +#define Anum_pg_aggregate_aggmtranstype 16 +#define Anum_pg_aggregate_aggmtransspace 17 +#define Anum_pg_aggregate_agginitval 18 +#define Anum_pg_aggregate_agginitcollect 19 +#define Anum_pg_aggregate_aggminitval 20 + +/* + * Symbolic values for aggkind column. We distinguish normal aggregates + * from ordered-set aggregates (which have two sets of arguments, namely + * direct and aggregated arguments) and from hypothetical-set aggregates + * (which are a subclass of ordered-set aggregates in which the last + * direct arguments have to match up in number and datatypes with the + * aggregated arguments). + */ +#define AGGKIND_NORMAL 'n' +#define AGGKIND_ORDERED_SET 'o' +#define AGGKIND_HYPOTHETICAL 'h' + +/* Use this macro to test for "ordered-set agg including hypothetical case" */ +#define AGGKIND_IS_ORDERED_SET(kind) ((kind) != AGGKIND_NORMAL) /* ---------------- @@ -113,379 +150,215 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; */ /* avg */ -#ifdef PGXC -DATA(insert ( 2100 int8_avg_accum numeric_avg_collect numeric_avg 0 1231 1231 "{0,0}" "{0,0}" )); -DATA(insert ( 2101 int4_avg_accum int8_avg_collect int8_avg 0 1016 1016 "{0,0}" "{0,0}" )); -DATA(insert ( 2102 int2_avg_accum int8_avg_collect int8_avg 0 1016 1016 "{0,0}" "{0,0}" )); -DATA(insert ( 2103 numeric_avg_accum numeric_avg_collect numeric_avg 0 1231 1231 "{0,0}" "{0,0}" )); -DATA(insert ( 2104 float4_accum float8_collect float8_avg 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2105 float8_accum float8_collect float8_avg 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2106 interval_accum interval_collect interval_avg 0 1187 1187 "{0 second,0 second}" "{0 second,0 second}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2100 int8_avg_accum numeric_avg 0 1231 "{0,0}" )); -//DATA(insert ( 2101 int4_avg_accum int8_avg 0 1016 "{0,0}" )); -//DATA(insert ( 2102 int2_avg_accum int8_avg 0 1016 "{0,0}" )); -//DATA(insert ( 2103 numeric_avg_accum numeric_avg 0 1231 "{0,0}" )); -//DATA(insert ( 2104 float4_accum float8_avg 0 1022 "{0,0,0}" )); -//DATA(insert ( 2105 float8_accum float8_avg 0 1022 "{0,0,0}" )); -//DATA(insert ( 2106 interval_accum interval_avg 0 1187 "{0 second,0 second}" )); -#endif +DATA(insert ( 2100 n 0 int8_avg_accum numeric_avg_collect numeric_avg int8_avg_accum int8_accum_inv numeric_avg f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2101 n 0 int4_avg_accum int8_avg_collect int8_avg int4_avg_accum int4_avg_accum_inv int8_avg f f 0 1016 1016 0 1016 0 "{0,0}" "{0,0}" "{0,0}" )); +DATA(insert ( 2102 n 0 int2_avg_accum int8_avg_collect int8_avg int2_avg_accum int2_avg_accum_inv int8_avg f f 0 1016 1016 0 1016 0 "{0,0}" "{0,0}" "{0,0}" )); +DATA(insert ( 2103 n 0 numeric_avg_accum numeric_avg_collect numeric_avg numeric_avg_accum numeric_accum_inv numeric_avg f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2104 n 0 float4_accum float8_collect float8_avg - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2105 n 0 float8_accum float8_collect float8_avg - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2106 n 0 interval_accum interval_collect interval_avg interval_accum interval_accum_inv interval_avg f f 0 1187 1187 0 1187 0 "{0 second,0 second}" "{0 second,0 second}" "{0 second,0 second}" )); /* sum */ -#ifdef PGXC -DATA(insert ( 2107 int8_sum numeric_add - 0 1700 1700 _null_ _null_ )); -DATA(insert ( 2108 int4_sum int8_sum_to_int8 - 0 20 20 _null_ _null_ )); -DATA(insert ( 2109 int2_sum int8_sum_to_int8 - 0 20 20 _null_ _null_ )); -DATA(insert ( 2110 float4pl float4pl - 0 700 700 _null_ _null_ )); -DATA(insert ( 2111 float8pl float8pl - 0 701 701 _null_ _null_ )); -DATA(insert ( 2112 cash_pl cash_pl - 0 790 790 _null_ _null_ )); -DATA(insert ( 2113 interval_pl interval_pl - 0 1186 1186 _null_ _null_ )); -DATA(insert ( 2114 numeric_add numeric_add - 0 1700 1700 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2107 int8_sum - 0 1700 _null_ )); -//DATA(insert ( 2108 int4_sum - 0 20 _null_ )); -//DATA(insert ( 2109 int2_sum - 0 20 _null_ )); -//DATA(insert ( 2110 float4pl - 0 700 _null_ )); -//DATA(insert ( 2111 float8pl - 0 701 _null_ )); -//DATA(insert ( 2112 cash_pl - 0 790 _null_ )); -//DATA(insert ( 2113 interval_pl - 0 1186 _null_ )); -//DATA(insert ( 2114 numeric_add - 0 1700 _null_ )); -#endif +DATA(insert ( 2107 n 0 int8_avg_accum numeric_add numeric_sum int8_avg_accum int8_accum_inv numeric_sum f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2108 n 0 int4_sum int8_sum_to_int8 - int4_avg_accum int4_avg_accum_inv int2int4_sum f f 0 20 20 0 1016 0 _null_ _null_ "{0,0}" )); +DATA(insert ( 2109 n 0 int2_sum int8_sum_to_int8 - int2_avg_accum int2_avg_accum_inv int2int4_sum f f 0 20 20 0 1016 0 _null_ _null_ "{0,0}" )); +DATA(insert ( 2110 n 0 float4pl float4pl - - - - f f 0 700 700 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2111 n 0 float8pl float8pl - - - - f f 0 701 701 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2112 n 0 cash_pl cash_pl - cash_pl cash_mi - f f 0 790 0 790 790 0 _null_ _null_ _null_ )); +DATA(insert ( 2113 n 0 interval_pl interval_pl - interval_pl interval_mi - f f 0 1186 1186 0 1186 0 _null_ _null_ _null_ )); +DATA(insert ( 2114 n 0 numeric_avg_accum numeric_add numeric_sum numeric_avg_accum numeric_accum_inv numeric_sum f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* max */ -#ifdef PGXC -DATA(insert ( 2115 int8larger int8larger - 413 20 20 _null_ _null_ )); -DATA(insert ( 2116 int4larger int4larger - 521 23 23 _null_ _null_ )); -DATA(insert ( 2117 int2larger int2larger - 520 21 21 _null_ _null_ )); -DATA(insert ( 2118 oidlarger oidlarger - 610 26 26 _null_ _null_ )); -DATA(insert ( 2119 float4larger float4larger - 623 700 700 _null_ _null_ )); -DATA(insert ( 2120 float8larger float8larger - 674 701 701 _null_ _null_ )); -DATA(insert ( 2121 int4larger int4larger - 563 702 702 _null_ _null_ )); -DATA(insert ( 2122 date_larger date_larger - 1097 1082 1082 _null_ _null_ )); -DATA(insert ( 2123 time_larger time_larger - 1112 1083 1083 _null_ _null_ )); -DATA(insert ( 2124 timetz_larger timetz_larger - 1554 1266 1266 _null_ _null_ )); -DATA(insert ( 2125 cashlarger cashlarger - 903 790 790 _null_ _null_ )); -DATA(insert ( 2126 timestamp_larger timestamp_larger - 2064 1114 1114 _null_ _null_ )); -DATA(insert ( 2127 timestamptz_larger timestamptz_larger - 1324 1184 1184 _null_ _null_ )); -DATA(insert ( 2128 interval_larger interval_larger - 1334 1186 1186 _null_ _null_ )); -DATA(insert ( 2129 text_larger text_larger - 666 25 25 _null_ _null_ )); -DATA(insert ( 2130 numeric_larger numeric_larger - 1756 1700 1700 _null_ _null_ )); -DATA(insert ( 2050 array_larger array_larger - 1073 2277 2277 _null_ _null_ )); -DATA(insert ( 2244 bpchar_larger bpchar_larger - 1060 1042 1042 _null_ _null_ )); -DATA(insert ( 2797 tidlarger tidlarger - 2800 27 27 _null_ _null_ )); -DATA(insert ( 3526 enum_larger enum_larger - 3519 3500 3500 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2115 int8larger - 413 20 _null_ )); -//DATA(insert ( 2116 int4larger - 521 23 _null_ )); -//DATA(insert ( 2117 int2larger - 520 21 _null_ )); -//DATA(insert ( 2118 oidlarger - 610 26 _null_ )); -//DATA(insert ( 2119 float4larger - 623 700 _null_ )); -//DATA(insert ( 2120 float8larger - 674 701 _null_ )); -//DATA(insert ( 2121 int4larger - 563 702 _null_ )); -//DATA(insert ( 2122 date_larger - 1097 1082 _null_ )); -//DATA(insert ( 2123 time_larger - 1112 1083 _null_ )); -//DATA(insert ( 2124 timetz_larger - 1554 1266 _null_ )); -//DATA(insert ( 2125 cashlarger - 903 790 _null_ )); -//DATA(insert ( 2126 timestamp_larger - 2064 1114 _null_ )); -//DATA(insert ( 2127 timestamptz_larger - 1324 1184 _null_ )); -//DATA(insert ( 2128 interval_larger - 1334 1186 _null_ )); -//DATA(insert ( 2129 text_larger - 666 25 _null_ )); -//DATA(insert ( 2130 numeric_larger - 1756 1700 _null_ )); -//DATA(insert ( 2050 array_larger - 1073 2277 _null_ )); -//DATA(insert ( 2244 bpchar_larger - 1060 1042 _null_ )); -//DATA(insert ( 2797 tidlarger - 2800 27 _null_ )); -//DATA(insert ( 3526 enum_larger - 3519 3500 _null_ )); -#endif +DATA(insert ( 2115 n 0 int8larger int8larger - - - - f f 413 20 20 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2116 n 0 int4larger int4larger - - - - f f 521 23 23 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2117 n 0 int2larger int2larger - - - - f f 520 21 21 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2118 n 0 oidlarger oidlarger - - - - f f 610 26 26 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2119 n 0 float4larger float4larger - - - - f f 623 700 700 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2120 n 0 float8larger float8larger - - - - f f 674 701 701 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2121 n 0 int4larger int4larger - - - - f f 563 702 702 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2122 n 0 date_larger date_larger - - - - f f 1097 1082 1082 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2123 n 0 time_larger time_larger - - - - f f 1112 1083 1083 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2124 n 0 timetz_larger timetz_larger - - - - f f 1554 1266 1266 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2125 n 0 cashlarger cashlarger - - - - f f 903 790 790 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2126 n 0 timestamp_larger timestamp_larger - - - - f f 2064 1114 1114 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2127 n 0 timestamptz_larger timestamptz_larger - - - - f f 1324 1184 1184 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2128 n 0 interval_larger interval_larger - - - - f f 1334 1186 1186 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2129 n 0 text_larger text_larger - - - - f f 666 25 25 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2130 n 0 numeric_larger numeric_larger - - - - f f 1756 1700 1700 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2050 n 0 array_larger array_larger - - - - f f 1073 2277 2277 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2244 n 0 bpchar_larger bpchar_larger - - - - f f 1060 1042 1042 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2797 n 0 tidlarger tidlarger - - - - f f 2800 27 27 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3526 n 0 enum_larger enum_larger - - - - f f 3519 3500 3500 0 0 0 _null_ _null_ _null_ )); /* min */ -#ifdef PGXC -DATA(insert ( 2131 int8smaller int8smaller - 412 20 20 _null_ _null_ )); -DATA(insert ( 2132 int4smaller int4smaller - 97 23 23 _null_ _null_ )); -DATA(insert ( 2133 int2smaller int2smaller - 95 21 21 _null_ _null_ )); -DATA(insert ( 2134 oidsmaller oidsmaller - 609 26 26 _null_ _null_ )); -DATA(insert ( 2135 float4smaller float4smaller - 622 700 700 _null_ _null_ )); -DATA(insert ( 2136 float8smaller float8smaller - 672 701 701 _null_ _null_ )); -DATA(insert ( 2137 int4smaller int4smaller - 562 702 702 _null_ _null_ )); -DATA(insert ( 2138 date_smaller date_smaller - 1095 1082 1082 _null_ _null_ )); -DATA(insert ( 2139 time_smaller time_smaller - 1110 1083 1083 _null_ _null_ )); -DATA(insert ( 2140 timetz_smaller timetz_smaller - 1552 1266 1266 _null_ _null_ )); -DATA(insert ( 2141 cashsmaller cashsmaller - 902 790 790 _null_ _null_ )); -DATA(insert ( 2142 timestamp_smaller timestamp_smaller - 2062 1114 1114 _null_ _null_ )); -DATA(insert ( 2143 timestamptz_smaller timestamptz_smaller - 1322 1184 1184 _null_ _null_ )); -DATA(insert ( 2144 interval_smaller interval_smaller - 1332 1186 1186 _null_ _null_ )); -DATA(insert ( 2145 text_smaller text_smaller - 664 25 25 _null_ _null_ )); -DATA(insert ( 2146 numeric_smaller numeric_smaller - 1754 1700 1700 _null_ _null_ )); -DATA(insert ( 2051 array_smaller array_smaller - 1072 2277 2277 _null_ _null_ )); -DATA(insert ( 2245 bpchar_smaller bpchar_smaller - 1058 1042 1042 _null_ _null_ )); -DATA(insert ( 2798 tidsmaller tidsmaller - 2799 27 27 _null_ _null_ )); -DATA(insert ( 3527 enum_smaller enum_smaller - 3518 3500 3500 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2131 int8smaller - 412 20 _null_ )); -//DATA(insert ( 2132 int4smaller - 97 23 _null_ )); -//DATA(insert ( 2133 int2smaller - 95 21 _null_ )); -//DATA(insert ( 2134 oidsmaller - 609 26 _null_ )); -//DATA(insert ( 2135 float4smaller - 622 700 _null_ )); -//DATA(insert ( 2136 float8smaller - 672 701 _null_ )); -//DATA(insert ( 2137 int4smaller - 562 702 _null_ )); -//DATA(insert ( 2138 date_smaller - 1095 1082 _null_ )); -//DATA(insert ( 2139 time_smaller - 1110 1083 _null_ )); -//DATA(insert ( 2140 timetz_smaller - 1552 1266 _null_ )); -//DATA(insert ( 2141 cashsmaller - 902 790 _null_ )); -//DATA(insert ( 2142 timestamp_smaller - 2062 1114 _null_ )); -//DATA(insert ( 2143 timestamptz_smaller - 1322 1184 _null_ )); -//DATA(insert ( 2144 interval_smaller - 1332 1186 _null_ )); -//DATA(insert ( 2145 text_smaller - 664 25 _null_ )); -//DATA(insert ( 2146 numeric_smaller - 1754 1700 _null_ )); -//DATA(insert ( 2051 array_smaller - 1072 2277 _null_ )); -//DATA(insert ( 2245 bpchar_smaller - 1058 1042 _null_ )); -//DATA(insert ( 2798 tidsmaller - 2799 27 _null_ )); -//DATA(insert ( 3527 enum_smaller - 3518 3500 _null_ )); -#endif +DATA(insert ( 2131 n 0 int8smaller int8smaller - - - - f f 412 20 20 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2132 n 0 int4smaller int4smaller - - - - f f 97 23 23 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2133 n 0 int2smaller int2smaller - - - - f f 95 21 21 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2134 n 0 oidsmaller oidsmaller - - - - f f 609 26 26 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2135 n 0 float4smaller float4smaller - - - - f f 622 700 700 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2136 n 0 float8smaller float8smaller - - - - f f 672 701 701 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2137 n 0 int4smaller int4smaller - - - - f f 562 702 702 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2138 n 0 date_smaller date_smaller - - - - f f 1095 1082 1082 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2139 n 0 time_smaller time_smaller - - - - f f 1110 1083 1083 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2140 n 0 timetz_smaller timetz_smaller - - - - f f 1552 1266 1266 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2141 n 0 cashsmaller cashsmaller - - - - f f 902 790 790 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2142 n 0 timestamp_smaller timestamp_smaller - - - - f f 2062 1114 1114 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2143 n 0 timestamptz_smaller timestamptz_smaller - - - - f f 1322 1184 1184 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2144 n 0 interval_smaller interval_smaller - - - - f f 1332 1186 1186 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2145 n 0 text_smaller text_smaller - - - - f f 664 25 25 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2146 n 0 numeric_smaller numeric_smaller - - - - f f 1754 1700 1700 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2051 n 0 array_smaller array_smaller - - - - f f 1072 2277 2277 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2245 n 0 bpchar_smaller bpchar_smaller - - - - f f 1058 1042 1042 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2798 n 0 tidsmaller tidsmaller - - - - f f 2799 27 27 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3527 n 0 enum_smaller enum_smaller - - - - f f 3518 3500 3500 0 0 0 _null_ _null_ _null_ )); /* count */ -/* Final function is data type conversion function numeric_int8 is referenced by OID because of ambiguous definition in pg_proc */ -#ifdef PGXC -DATA(insert ( 2147 int8inc_any int8_sum_to_int8 - 0 20 20 "0" _null_ )); -DATA(insert ( 2803 int8inc int8_sum_to_int8 - 0 20 20 "0" _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2147 int8inc_any - 0 20 "0" )); -//DATA(insert ( 2803 int8inc - 0 20 "0" )); -#endif +DATA(insert ( 2147 n 0 int8inc_any int8_sum_to_int8 - int8inc_any int8dec_any - f f 0 20 20 0 20 0 "0" _null_ "0" )); +DATA(insert ( 2803 n 0 int8inc int8_sum_to_int8 - int8inc int8dec - f f 0 20 20 0 20 0 "0" _null_ "0" )); /* var_pop */ -#ifdef PGXC -DATA(insert ( 2718 int8_accum numeric_collect numeric_var_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2719 int4_accum numeric_collect numeric_var_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2720 int2_accum numeric_collect numeric_var_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2721 float4_accum float8_collect float8_var_pop 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2722 float8_accum float8_collect float8_var_pop 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2723 numeric_accum numeric_collect numeric_var_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2718 int8_accum numeric_var_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2719 int4_accum numeric_var_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2720 int2_accum numeric_var_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2721 float4_accum float8_var_pop 0 1022 "{0,0,0}" )); -//DATA(insert ( 2722 float8_accum float8_var_pop 0 1022 "{0,0,0}" )); -//DATA(insert ( 2723 numeric_accum numeric_var_pop 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2718 n 0 int8_accum numeric_collect numeric_var_pop int8_accum int8_accum_inv numeric_var_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2719 n 0 int4_accum numeric_collect numeric_var_pop int4_accum int4_accum_inv numeric_var_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2720 n 0 int2_accum numeric_collect numeric_var_pop int2_accum int2_accum_inv numeric_var_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2721 n 0 float4_accum float8_collect float8_var_pop - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2722 n 0 float8_accum float8_collect float8_var_pop - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2723 n 0 numeric_accum numeric_collect numeric_var_pop numeric_accum numeric_accum_inv numeric_var_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* var_samp */ -#ifdef PGXC -DATA(insert ( 2641 int8_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2642 int4_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2643 int2_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2644 float4_accum float8_collect float8_var_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2645 float8_accum float8_collect float8_var_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2646 numeric_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2641 int8_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2642 int4_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2643 int2_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2644 float4_accum float8_var_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2645 float8_accum float8_var_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2646 numeric_accum numeric_var_samp 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2641 n 0 int8_accum numeric_collect numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2642 n 0 int4_accum numeric_collect numeric_var_samp int4_accum int4_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2643 n 0 int2_accum numeric_collect numeric_var_samp int2_accum int2_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2644 n 0 float4_accum float8_collect float8_var_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2645 n 0 float8_accum float8_collect float8_var_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2646 n 0 numeric_accum numeric_collect numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* variance: historical Postgres syntax for var_samp */ -#ifdef PGXC -DATA(insert ( 2148 int8_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2149 int4_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2150 int2_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2151 float4_accum float8_collect float8_var_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2152 float8_accum float8_collect float8_var_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2153 numeric_accum numeric_collect numeric_var_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2148 int8_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2149 int4_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2150 int2_accum numeric_var_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2151 float4_accum float8_var_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2152 float8_accum float8_var_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2153 numeric_accum numeric_var_samp 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2148 n 0 int8_accum numeric_collect numeric_var_samp int8_accum int8_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2149 n 0 int4_accum numeric_collect numeric_var_samp int4_accum int4_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2150 n 0 int2_accum numeric_collect numeric_var_samp int2_accum int2_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2151 n 0 float4_accum float8_collect float8_var_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2152 n 0 float8_accum float8_collect float8_var_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2153 n 0 numeric_accum numeric_collect numeric_var_samp numeric_accum numeric_accum_inv numeric_var_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* stddev_pop */ -#ifdef PGXC -DATA(insert ( 2724 int8_accum numeric_collect numeric_stddev_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2725 int4_accum numeric_collect numeric_stddev_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2726 int2_accum numeric_collect numeric_stddev_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2727 float4_accum float8_collect float8_stddev_pop 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2728 float8_accum float8_collect float8_stddev_pop 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2729 numeric_accum numeric_collect numeric_stddev_pop 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2724 int8_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2725 int4_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2726 int2_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); -//DATA(insert ( 2727 float4_accum float8_stddev_pop 0 1022 "{0,0,0}" )); -//DATA(insert ( 2728 float8_accum float8_stddev_pop 0 1022 "{0,0,0}" )); -//DATA(insert ( 2729 numeric_accum numeric_stddev_pop 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2724 n 0 int8_accum numeric_collect numeric_stddev_pop int8_accum int8_accum_inv numeric_stddev_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2725 n 0 int4_accum numeric_collect numeric_stddev_pop int4_accum int4_accum_inv numeric_stddev_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2726 n 0 int2_accum numeric_collect numeric_stddev_pop int2_accum int2_accum_inv numeric_stddev_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2727 n 0 float4_accum float8_collect float8_stddev_pop - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2728 n 0 float8_accum float8_collect float8_stddev_pop - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2729 n 0 numeric_accum numeric_collect numeric_stddev_pop numeric_accum numeric_accum_inv numeric_stddev_pop f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* stddev_samp */ -#ifdef PGXC -DATA(insert ( 2712 int8_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2713 int4_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2714 int2_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2715 float4_accum float8_collect float8_stddev_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2716 float8_accum float8_collect float8_stddev_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2717 numeric_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2712 int8_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2713 int4_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2714 int2_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2715 float4_accum float8_stddev_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2716 float8_accum float8_stddev_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2717 numeric_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2712 n 0 int8_accum numeric_collect numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2713 n 0 int4_accum numeric_collect numeric_stddev_samp int4_accum int4_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2714 n 0 int2_accum numeric_collect numeric_stddev_samp int2_accum int2_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2715 n 0 float4_accum float8_collect float8_stddev_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2716 n 0 float8_accum float8_collect float8_stddev_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2717 n 0 numeric_accum numeric_collect numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* stddev: historical Postgres syntax for stddev_samp */ -#ifdef PGXC -DATA(insert ( 2154 int8_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2155 int4_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2156 int2_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2157 float4_accum float8_collect float8_stddev_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2158 float8_accum float8_collect float8_stddev_samp 0 1022 1022 "{0,0,0}" "{0,0,0}" )); -DATA(insert ( 2159 numeric_accum numeric_collect numeric_stddev_samp 0 1231 1231 "{0,0,0}" "{0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2154 int8_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2155 int4_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2156 int2_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -//DATA(insert ( 2157 float4_accum float8_stddev_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2158 float8_accum float8_stddev_samp 0 1022 "{0,0,0}" )); -//DATA(insert ( 2159 numeric_accum numeric_stddev_samp 0 1231 "{0,0,0}" )); -#endif +DATA(insert ( 2154 n 0 int8_accum numeric_collect numeric_stddev_samp int8_accum int8_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2155 n 0 int4_accum numeric_collect numeric_stddev_samp int4_accum int4_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2156 n 0 int2_accum numeric_collect numeric_stddev_samp int2_accum int2_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); +DATA(insert ( 2157 n 0 float4_accum float8_collect float8_stddev_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2158 n 0 float8_accum float8_collect float8_stddev_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0}" "{0,0,0}" _null_ )); +DATA(insert ( 2159 n 0 numeric_accum numeric_collect numeric_stddev_samp numeric_accum numeric_accum_inv numeric_stddev_samp f f 0 2281 2281 128 2281 128 _null_ _null_ _null_ )); /* SQL2003 binary regression aggregates */ -#ifdef PGXC -DATA(insert ( 2818 int8inc_float8_float8 int8_sum_to_int8 - 0 20 20 "0" _null_ )); -DATA(insert ( 2819 float8_regr_accum float8_regr_collect float8_regr_sxx 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2820 float8_regr_accum float8_regr_collect float8_regr_syy 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2821 float8_regr_accum float8_regr_collect float8_regr_sxy 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2822 float8_regr_accum float8_regr_collect float8_regr_avgx 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2823 float8_regr_accum float8_regr_collect float8_regr_avgy 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2824 float8_regr_accum float8_regr_collect float8_regr_r2 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2825 float8_regr_accum float8_regr_collect float8_regr_slope 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2826 float8_regr_accum float8_regr_collect float8_regr_intercept 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2827 float8_regr_accum float8_regr_collect float8_covar_pop 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2828 float8_regr_accum float8_regr_collect float8_covar_samp 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -DATA(insert ( 2829 float8_regr_accum float8_regr_collect float8_corr 0 1022 1022 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" )); -#endif -#ifdef PGXC -//DATA(insert ( 2818 int8inc_float8_float8 - 0 20 "0" )); -//DATA(insert ( 2819 float8_regr_accum float8_regr_sxx 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2820 float8_regr_accum float8_regr_syy 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2821 float8_regr_accum float8_regr_sxy 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2822 float8_regr_accum float8_regr_avgx 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2823 float8_regr_accum float8_regr_avgy 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2824 float8_regr_accum float8_regr_r2 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2825 float8_regr_accum float8_regr_slope 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2826 float8_regr_accum float8_regr_intercept 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2827 float8_regr_accum float8_covar_pop 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2828 float8_regr_accum float8_covar_samp 0 1022 "{0,0,0,0,0,0}" )); -//DATA(insert ( 2829 float8_regr_accum float8_corr 0 1022 "{0,0,0,0,0,0}" )); -#endif +DATA(insert ( 2818 n 0 int8inc_float8_float8 int8_sum_to_int8 - - - - f f 0 20 20 0 0 0 "0" _null_ _null_ )); +DATA(insert ( 2819 n 0 float8_regr_accum float8_regr_collect float8_regr_sxx - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2820 n 0 float8_regr_accum float8_regr_collect float8_regr_syy - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2821 n 0 float8_regr_accum float8_regr_collect float8_regr_sxy - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2822 n 0 float8_regr_accum float8_regr_collect float8_regr_avgx - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2823 n 0 float8_regr_accum float8_regr_collect float8_regr_avgy - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2824 n 0 float8_regr_accum float8_regr_collect float8_regr_r2 - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2825 n 0 float8_regr_accum float8_regr_collect float8_regr_slope - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2826 n 0 float8_regr_accum float8_regr_collect float8_regr_intercept - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2827 n 0 float8_regr_accum float8_regr_collect float8_covar_pop - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2828 n 0 float8_regr_accum float8_regr_collect float8_covar_samp - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); +DATA(insert ( 2829 n 0 float8_regr_accum float8_regr_collect float8_corr - - - f f 0 1022 1022 0 0 0 "{0,0,0,0,0,0}" "{0,0,0,0,0,0}" _null_ )); /* boolean-and and boolean-or */ -#ifdef PGXC -DATA(insert ( 2517 booland_statefunc booland_statefunc - 58 16 16 _null_ _null_ )); -DATA(insert ( 2518 boolor_statefunc boolor_statefunc - 59 16 16 _null_ _null_ )); -DATA(insert ( 2519 booland_statefunc booland_statefunc - 58 16 16 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2517 booland_statefunc - 58 16 _null_ )); -//DATA(insert ( 2518 boolor_statefunc - 59 16 _null_ )); -//DATA(insert ( 2519 booland_statefunc - 58 16 _null_ )); -#endif +DATA(insert ( 2517 n 0 booland_statefunc booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 16 0 2281 16 _null_ __null_ null_ )); +DATA(insert ( 2518 n 0 boolor_statefunc boolor_statefunc - bool_accum bool_accum_inv bool_anytrue f f 59 16 16 0 2281 16 _null_ __null_ null_ )); +DATA(insert ( 2519 n 0 booland_statefunc booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 16 0 2281 16 _null_ __null_ null_ )); /* bitwise integer */ -#ifdef PGXC -DATA(insert ( 2236 int2and int2and - 0 21 21 _null_ _null_ )); -DATA(insert ( 2237 int2or int2or - 0 21 21 _null_ _null_ )); -DATA(insert ( 2238 int4and int4and - 0 23 23 _null_ _null_ )); -DATA(insert ( 2239 int4or int4or - 0 23 23 _null_ _null_ )); -DATA(insert ( 2240 int8and int8and - 0 20 20 _null_ _null_ )); -DATA(insert ( 2241 int8or int8or - 0 20 20 _null_ _null_ )); -DATA(insert ( 2242 bitand bitand - 0 1560 1560 _null_ _null_ )); -DATA(insert ( 2243 bitor bitor - 0 1560 1560 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2236 int2and - 0 21 _null_ )); -//DATA(insert ( 2237 int2or - 0 21 _null_ )); -//DATA(insert ( 2238 int4and - 0 23 _null_ )); -//DATA(insert ( 2239 int4or - 0 23 _null_ )); -//DATA(insert ( 2240 int8and - 0 20 _null_ )); -//DATA(insert ( 2241 int8or - 0 20 _null_ )); -//DATA(insert ( 2242 bitand - 0 1560 _null_ )); -//DATA(insert ( 2243 bitor - 0 1560 _null_ )); -#endif +DATA(insert ( 2236 n 0 int2and int2and - - - - f f 0 21 21 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2237 n 0 int2or int2or - - - - f f 0 21 21 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2238 n 0 int4and int4and - - - - f f 0 23 23 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2239 n 0 int4or int4or - - - - f f 0 23 23 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2240 n 0 int8and int8and - - - - f f 0 20 20 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2241 n 0 int8or int8or - - - - f f 0 20 20 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2242 n 0 bitand bitand - - - - f f 0 1560 1560 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 2243 n 0 bitor bitor - - - - f f 0 1560 1560 0 0 0 _null_ _null_ _null_ )); /* xml */ -#ifdef PGXC -DATA(insert ( 2901 xmlconcat2 - - 0 142 0 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2901 xmlconcat2 - 0 142 _null_ )); -#endif +DATA(insert ( 2901 n 0 xmlconcat2 - - - - - f f 0 142 0 0 0 0 _null_ _null_ _null_ )); /* array */ -#ifdef PGXC -DATA(insert ( 2335 array_agg_transfn - array_agg_finalfn 0 2281 0 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 2335 array_agg_transfn array_agg_finalfn 0 2281 _null_ )); -#endif +DATA(insert ( 2335 n 0 array_agg_transfn - array_agg_finalfn - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); /* text */ -#ifdef PGXC -DATA(insert (3538 string_agg_transfn - string_agg_finalfn 0 2281 0 _null_ _null_ )); -// XXX function string_agg_delim_transfn is not defined? -//DATA(insert (3538 string_agg_delim_transfn - string_agg_finalfn 0 2281 0 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert (3535 string_agg_transfn string_agg_finalfn 0 2281 _null_ )); -//DATA(insert (3538 string_agg_delim_transfn string_agg_finalfn 0 2281 _null_ )); -#endif +DATA(insert ( 3538 n 0 string_agg_transfn - string_agg_finalfn - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); /* bytea */ -#ifdef PGXC -DATA(insert ( 3545 bytea_string_agg_transfn - bytea_string_agg_finalfn 0 2281 0 _null_ _null_ )); -#endif -#ifdef PGXC -//DATA(insert ( 3545 bytea_string_agg_transfn bytea_string_agg_finalfn 0 2281 _null_ )); -#endif +DATA(insert ( 3545 n 0 bytea_string_agg_transfn - bytea_string_agg_finalfn - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); + +/* json */ +DATA(insert ( 3175 n 0 json_agg_transfn - json_agg_finalfn - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3197 n 0 json_object_agg_transfn - json_object_agg_finalfn - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); + +/* ordered-set and hypothetical-set aggregates */ +DATA(insert ( 3972 o 1 ordered_set_transition - percentile_disc_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3974 o 1 ordered_set_transition - percentile_cont_float8_final - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3976 o 1 ordered_set_transition - percentile_cont_interval_final - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3978 o 1 ordered_set_transition - percentile_disc_multi_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3980 o 1 ordered_set_transition - percentile_cont_float8_multi_final - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3982 o 1 ordered_set_transition - percentile_cont_interval_multi_final - - - f f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3984 o 0 ordered_set_transition - mode_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3986 h 1 ordered_set_transition_multi - rank_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3988 h 1 ordered_set_transition_multi - percent_rank_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3990 h 1 ordered_set_transition_multi - cume_dist_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); +DATA(insert ( 3992 h 1 ordered_set_transition_multi - dense_rank_final - - - t f 0 2281 0 0 0 0 _null_ _null_ _null_ )); + /* * prototypes for functions in pg_aggregate.c */ -extern void AggregateCreate(const char *aggName, +extern Oid AggregateCreate(const char *aggName, Oid aggNamespace, - Oid *aggArgTypes, + char aggKind, int numArgs, + int numDirectArgs, + oidvector *parameterTypes, + Datum allParameterTypes, + Datum parameterModes, + Datum parameterNames, + List *parameterDefaults, + Oid variadicArgType, List *aggtransfnName, #ifdef PGXC List *aggcollectfnName, #endif List *aggfinalfnName, + List *aggmtransfnName, + List *aggminvtransfnName, + List *aggmfinalfnName, + bool finalfnExtraArgs, + bool mfinalfnExtraArgs, List *aggsortopName, Oid aggTransType, #ifdef XCP Oid aggCollectType, #endif -#ifdef PGXC + int32 aggTransSpace, + Oid aggmTransType, + int32 aggmTransSpace, const char *agginitval, - const char *agginitcollect); -#else - const char *agginitval); +#ifdef XCP + const char *agginitcollect, #endif + const char *aggminitval); #endif /* PG_AGGREGATE_H */ diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 0d7ed6857e..759ea70570 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_am.h @@ -34,11 +34,11 @@ CATALOG(pg_am,2601) { NameData amname; /* access method name */ - int2 amstrategies; /* total number of strategies (operators) by + int16 amstrategies; /* total number of strategies (operators) by * which we can traverse/search this AM. Zero * if AM does not have a fixed set of strategy * assignments. */ - int2 amsupport; /* total number of support functions that this + int16 amsupport; /* total number of support functions that this * AM uses */ bool amcanorder; /* does AM support order by column value? */ bool amcanorderbyop; /* does AM support order by operator result? */ @@ -126,7 +126,7 @@ DESCR("hash index access method"); DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions )); DESCR("GiST index access method"); #define GIST_AM_OID 783 -DATA(insert OID = 2742 ( gin 0 5 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions )); +DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions )); DESCR("GIN index access method"); #define GIN_AM_OID 2742 DATA(insert OID = 4000 ( spgist 0 5 f f f f f t f t f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcanreturn spgcostestimate spgoptions )); diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index 82391b09d8..3ef5a49cc9 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -30,7 +30,7 @@ * intentional denormalization of the catalogs to buy lookup speed. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_amop.h @@ -58,7 +58,7 @@ CATALOG(pg_amop,2602) Oid amopfamily; /* the index opfamily this entry is for */ Oid amoplefttype; /* operator's left input data type */ Oid amoprighttype; /* operator's right input data type */ - int2 amopstrategy; /* operator strategy number */ + int16 amopstrategy; /* operator strategy number */ char amoppurpose; /* is operator for 's'earch or 'o'rdering? */ Oid amopopr; /* the operator's pg_operator OID */ Oid amopmethod; /* the index access method this entry is for */ @@ -493,6 +493,16 @@ DATA(insert ( 2994 2249 2249 4 s 2993 403 0 )); DATA(insert ( 2994 2249 2249 5 s 2991 403 0 )); /* + * btree record_image_ops + */ + +DATA(insert ( 3194 2249 2249 1 s 3190 403 0 )); +DATA(insert ( 3194 2249 2249 2 s 3192 403 0 )); +DATA(insert ( 3194 2249 2249 3 s 3188 403 0 )); +DATA(insert ( 3194 2249 2249 4 s 3193 403 0 )); +DATA(insert ( 3194 2249 2249 5 s 3191 403 0 )); + +/* * btree uuid_ops */ @@ -503,6 +513,16 @@ DATA(insert ( 2968 2950 2950 4 s 2977 403 0 )); DATA(insert ( 2968 2950 2950 5 s 2975 403 0 )); /* + * btree pg_lsn_ops + */ + +DATA(insert ( 3253 3220 3220 1 s 3224 403 0 )); +DATA(insert ( 3253 3220 3220 2 s 3226 403 0 )); +DATA(insert ( 3253 3220 3220 3 s 3222 403 0 )); +DATA(insert ( 3253 3220 3220 4 s 3227 403 0 )); +DATA(insert ( 3253 3220 3220 5 s 3225 403 0 )); + +/* * hash index _ops */ @@ -571,6 +591,8 @@ DATA(insert ( 2231 1042 1042 1 s 1054 405 0 )); DATA(insert ( 2235 1033 1033 1 s 974 405 0 )); /* uuid_ops */ DATA(insert ( 2969 2950 2950 1 s 2972 405 0 )); +/* pg_lsn_ops */ +DATA(insert ( 3254 3220 3220 1 s 3222 405 0 )); /* numeric_ops */ DATA(insert ( 1998 1700 1700 1 s 1752 405 0 )); /* array_ops */ @@ -767,4 +789,60 @@ DATA(insert ( 4017 25 25 12 s 665 4000 0 )); DATA(insert ( 4017 25 25 14 s 667 4000 0 )); DATA(insert ( 4017 25 25 15 s 666 4000 0 )); +/* + * btree jsonb_ops + */ +DATA(insert ( 4033 3802 3802 1 s 3242 403 0 )); +DATA(insert ( 4033 3802 3802 2 s 3244 403 0 )); +DATA(insert ( 4033 3802 3802 3 s 3240 403 0 )); +DATA(insert ( 4033 3802 3802 4 s 3245 403 0 )); +DATA(insert ( 4033 3802 3802 5 s 3243 403 0 )); + +/* + * hash jsonb_ops + */ +DATA(insert ( 4034 3802 3802 1 s 3240 405 0 )); + +/* + * GIN jsonb_ops + */ +DATA(insert ( 4036 3802 3802 7 s 3246 2742 0 )); +DATA(insert ( 4036 3802 25 9 s 3247 2742 0 )); +DATA(insert ( 4036 3802 1009 10 s 3248 2742 0 )); +DATA(insert ( 4036 3802 1009 11 s 3249 2742 0 )); + +/* + * GIN jsonb_path_ops + */ +DATA(insert ( 4037 3802 3802 7 s 3246 2742 0 )); + +/* + * SP-GiST range_ops + */ +DATA(insert ( 3474 3831 3831 1 s 3893 4000 0 )); +DATA(insert ( 3474 3831 3831 2 s 3895 4000 0 )); +DATA(insert ( 3474 3831 3831 3 s 3888 4000 0 )); +DATA(insert ( 3474 3831 3831 4 s 3896 4000 0 )); +DATA(insert ( 3474 3831 3831 5 s 3894 4000 0 )); +DATA(insert ( 3474 3831 3831 6 s 3897 4000 0 )); +DATA(insert ( 3474 3831 3831 7 s 3890 4000 0 )); +DATA(insert ( 3474 3831 3831 8 s 3892 4000 0 )); +DATA(insert ( 3474 3831 2283 16 s 3889 4000 0 )); +DATA(insert ( 3474 3831 3831 18 s 3882 4000 0 )); + +/* + * GiST inet_ops + */ +DATA(insert ( 3550 869 869 3 s 3552 783 0 )); +DATA(insert ( 3550 869 869 18 s 1201 783 0 )); +DATA(insert ( 3550 869 869 19 s 1202 783 0 )); +DATA(insert ( 3550 869 869 20 s 1203 783 0 )); +DATA(insert ( 3550 869 869 21 s 1204 783 0 )); +DATA(insert ( 3550 869 869 22 s 1205 783 0 )); +DATA(insert ( 3550 869 869 23 s 1206 783 0 )); +DATA(insert ( 3550 869 869 24 s 931 783 0 )); +DATA(insert ( 3550 869 869 25 s 932 783 0 )); +DATA(insert ( 3550 869 869 26 s 933 783 0 )); +DATA(insert ( 3550 869 869 27 s 934 783 0 )); + #endif /* PG_AMOP_H */ diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 72307dec22..10a47df6be 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -19,7 +19,7 @@ * some don't pay attention to non-default functions at all. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_amproc.h @@ -47,7 +47,7 @@ CATALOG(pg_amproc,2603) Oid amprocfamily; /* the index opfamily this entry is for */ Oid amproclefttype; /* procedure's left input data type */ Oid amprocrighttype; /* procedure's right input data type */ - int2 amprocnum; /* support procedure index */ + int16 amprocnum; /* support procedure index */ regproc amproc; /* OID of the proc */ } FormData_pg_amproc; @@ -121,7 +121,6 @@ DATA(insert ( 1988 1700 1700 1 1769 )); DATA(insert ( 1989 26 26 1 356 )); DATA(insert ( 1989 26 26 2 3134 )); DATA(insert ( 1991 30 30 1 404 )); -DATA(insert ( 2994 2249 2249 1 2987 )); DATA(insert ( 1994 25 25 1 360 )); DATA(insert ( 1996 1083 1083 1 1107 )); DATA(insert ( 2000 1266 1266 1 1358 )); @@ -133,7 +132,14 @@ DATA(insert ( 2233 703 703 1 380 )); DATA(insert ( 2234 704 704 1 381 )); DATA(insert ( 2789 27 27 1 2794 )); DATA(insert ( 2968 2950 2950 1 2960 )); +DATA(insert ( 2994 2249 2249 1 2987 )); +DATA(insert ( 3194 2249 2249 1 3187 )); +DATA(insert ( 3253 3220 3220 1 3251 )); DATA(insert ( 3522 3500 3500 1 3514 )); +DATA(insert ( 3626 3614 3614 1 3622 )); +DATA(insert ( 3683 3615 3615 1 3668 )); +DATA(insert ( 3901 3831 3831 1 3870 )); +DATA(insert ( 4033 3802 3802 1 4044 )); /* hash */ @@ -169,10 +175,21 @@ DATA(insert ( 2229 25 25 1 400 )); DATA(insert ( 2231 1042 1042 1 1080 )); DATA(insert ( 2235 1033 1033 1 329 )); DATA(insert ( 2969 2950 2950 1 2963 )); +DATA(insert ( 3254 3220 3220 1 3252 )); DATA(insert ( 3523 3500 3500 1 3515 )); +DATA(insert ( 3903 3831 3831 1 3902 )); +DATA(insert ( 4034 3802 3802 1 4045 )); /* gist */ +DATA(insert ( 1029 600 600 1 2179 )); +DATA(insert ( 1029 600 600 2 2583 )); +DATA(insert ( 1029 600 600 3 1030 )); +DATA(insert ( 1029 600 600 4 2580 )); +DATA(insert ( 1029 600 600 5 2581 )); +DATA(insert ( 1029 600 600 6 2582 )); +DATA(insert ( 1029 600 600 7 2584 )); +DATA(insert ( 1029 600 600 8 3064 )); DATA(insert ( 2593 603 603 1 2578 )); DATA(insert ( 2593 603 603 2 2583 )); DATA(insert ( 2593 603 603 3 2579 )); @@ -208,14 +225,13 @@ DATA(insert ( 3702 3615 3615 4 3696 )); DATA(insert ( 3702 3615 3615 5 3700 )); DATA(insert ( 3702 3615 3615 6 3697 )); DATA(insert ( 3702 3615 3615 7 3699 )); -DATA(insert ( 1029 600 600 1 2179 )); -DATA(insert ( 1029 600 600 2 2583 )); -DATA(insert ( 1029 600 600 3 1030 )); -DATA(insert ( 1029 600 600 4 2580 )); -DATA(insert ( 1029 600 600 5 2581 )); -DATA(insert ( 1029 600 600 6 2582 )); -DATA(insert ( 1029 600 600 7 2584 )); -DATA(insert ( 1029 600 600 8 3064 )); +DATA(insert ( 3919 3831 3831 1 3875 )); +DATA(insert ( 3919 3831 3831 2 3876 )); +DATA(insert ( 3919 3831 3831 3 3877 )); +DATA(insert ( 3919 3831 3831 4 3878 )); +DATA(insert ( 3919 3831 3831 5 3879 )); +DATA(insert ( 3919 3831 3831 6 3880 )); +DATA(insert ( 3919 3831 3831 7 3881 )); /* gin */ @@ -223,141 +239,182 @@ DATA(insert ( 2745 1007 1007 1 351 )); DATA(insert ( 2745 1007 1007 2 2743 )); DATA(insert ( 2745 1007 1007 3 2774 )); DATA(insert ( 2745 1007 1007 4 2744 )); +DATA(insert ( 2745 1007 1007 6 3920 )); DATA(insert ( 2745 1009 1009 1 360 )); DATA(insert ( 2745 1009 1009 2 2743 )); DATA(insert ( 2745 1009 1009 3 2774 )); DATA(insert ( 2745 1009 1009 4 2744 )); +DATA(insert ( 2745 1009 1009 6 3920 )); DATA(insert ( 2745 1015 1015 1 360 )); DATA(insert ( 2745 1015 1015 2 2743 )); DATA(insert ( 2745 1015 1015 3 2774 )); DATA(insert ( 2745 1015 1015 4 2744 )); +DATA(insert ( 2745 1015 1015 6 3920 )); DATA(insert ( 2745 1023 1023 1 357 )); DATA(insert ( 2745 1023 1023 2 2743 )); DATA(insert ( 2745 1023 1023 3 2774 )); DATA(insert ( 2745 1023 1023 4 2744 )); +DATA(insert ( 2745 1023 1023 6 3920 )); DATA(insert ( 2745 1561 1561 1 1596 )); DATA(insert ( 2745 1561 1561 2 2743 )); DATA(insert ( 2745 1561 1561 3 2774 )); DATA(insert ( 2745 1561 1561 4 2744 )); +DATA(insert ( 2745 1561 1561 6 3920 )); DATA(insert ( 2745 1000 1000 1 1693 )); DATA(insert ( 2745 1000 1000 2 2743 )); DATA(insert ( 2745 1000 1000 3 2774 )); DATA(insert ( 2745 1000 1000 4 2744 )); +DATA(insert ( 2745 1000 1000 6 3920 )); DATA(insert ( 2745 1014 1014 1 1078 )); DATA(insert ( 2745 1014 1014 2 2743 )); DATA(insert ( 2745 1014 1014 3 2774 )); DATA(insert ( 2745 1014 1014 4 2744 )); +DATA(insert ( 2745 1014 1014 6 3920 )); DATA(insert ( 2745 1001 1001 1 1954 )); DATA(insert ( 2745 1001 1001 2 2743 )); DATA(insert ( 2745 1001 1001 3 2774 )); DATA(insert ( 2745 1001 1001 4 2744 )); +DATA(insert ( 2745 1001 1001 6 3920 )); DATA(insert ( 2745 1002 1002 1 358 )); DATA(insert ( 2745 1002 1002 2 2743 )); DATA(insert ( 2745 1002 1002 3 2774 )); DATA(insert ( 2745 1002 1002 4 2744 )); +DATA(insert ( 2745 1002 1002 6 3920 )); DATA(insert ( 2745 1182 1182 1 1092 )); DATA(insert ( 2745 1182 1182 2 2743 )); DATA(insert ( 2745 1182 1182 3 2774 )); DATA(insert ( 2745 1182 1182 4 2744 )); +DATA(insert ( 2745 1182 1182 6 3920 )); DATA(insert ( 2745 1021 1021 1 354 )); DATA(insert ( 2745 1021 1021 2 2743 )); DATA(insert ( 2745 1021 1021 3 2774 )); DATA(insert ( 2745 1021 1021 4 2744 )); +DATA(insert ( 2745 1021 1021 6 3920 )); DATA(insert ( 2745 1022 1022 1 355 )); DATA(insert ( 2745 1022 1022 2 2743 )); DATA(insert ( 2745 1022 1022 3 2774 )); DATA(insert ( 2745 1022 1022 4 2744 )); +DATA(insert ( 2745 1022 1022 6 3920 )); DATA(insert ( 2745 1041 1041 1 926 )); DATA(insert ( 2745 1041 1041 2 2743 )); DATA(insert ( 2745 1041 1041 3 2774 )); DATA(insert ( 2745 1041 1041 4 2744 )); +DATA(insert ( 2745 1041 1041 6 3920 )); DATA(insert ( 2745 651 651 1 926 )); DATA(insert ( 2745 651 651 2 2743 )); DATA(insert ( 2745 651 651 3 2774 )); DATA(insert ( 2745 651 651 4 2744 )); +DATA(insert ( 2745 651 651 6 3920 )); DATA(insert ( 2745 1005 1005 1 350 )); DATA(insert ( 2745 1005 1005 2 2743 )); DATA(insert ( 2745 1005 1005 3 2774 )); DATA(insert ( 2745 1005 1005 4 2744 )); +DATA(insert ( 2745 1005 1005 6 3920 )); DATA(insert ( 2745 1016 1016 1 842 )); DATA(insert ( 2745 1016 1016 2 2743 )); DATA(insert ( 2745 1016 1016 3 2774 )); DATA(insert ( 2745 1016 1016 4 2744 )); +DATA(insert ( 2745 1016 1016 6 3920 )); DATA(insert ( 2745 1187 1187 1 1315 )); DATA(insert ( 2745 1187 1187 2 2743 )); DATA(insert ( 2745 1187 1187 3 2774 )); DATA(insert ( 2745 1187 1187 4 2744 )); +DATA(insert ( 2745 1187 1187 6 3920 )); DATA(insert ( 2745 1040 1040 1 836 )); DATA(insert ( 2745 1040 1040 2 2743 )); DATA(insert ( 2745 1040 1040 3 2774 )); DATA(insert ( 2745 1040 1040 4 2744 )); +DATA(insert ( 2745 1040 1040 6 3920 )); DATA(insert ( 2745 1003 1003 1 359 )); DATA(insert ( 2745 1003 1003 2 2743 )); DATA(insert ( 2745 1003 1003 3 2774 )); DATA(insert ( 2745 1003 1003 4 2744 )); +DATA(insert ( 2745 1003 1003 6 3920 )); DATA(insert ( 2745 1231 1231 1 1769 )); DATA(insert ( 2745 1231 1231 2 2743 )); DATA(insert ( 2745 1231 1231 3 2774 )); DATA(insert ( 2745 1231 1231 4 2744 )); +DATA(insert ( 2745 1231 1231 6 3920 )); DATA(insert ( 2745 1028 1028 1 356 )); DATA(insert ( 2745 1028 1028 2 2743 )); DATA(insert ( 2745 1028 1028 3 2774 )); DATA(insert ( 2745 1028 1028 4 2744 )); +DATA(insert ( 2745 1028 1028 6 3920 )); DATA(insert ( 2745 1013 1013 1 404 )); DATA(insert ( 2745 1013 1013 2 2743 )); DATA(insert ( 2745 1013 1013 3 2774 )); DATA(insert ( 2745 1013 1013 4 2744 )); +DATA(insert ( 2745 1013 1013 6 3920 )); DATA(insert ( 2745 1183 1183 1 1107 )); DATA(insert ( 2745 1183 1183 2 2743 )); DATA(insert ( 2745 1183 1183 3 2774 )); DATA(insert ( 2745 1183 1183 4 2744 )); +DATA(insert ( 2745 1183 1183 6 3920 )); DATA(insert ( 2745 1185 1185 1 1314 )); DATA(insert ( 2745 1185 1185 2 2743 )); DATA(insert ( 2745 1185 1185 3 2774 )); DATA(insert ( 2745 1185 1185 4 2744 )); +DATA(insert ( 2745 1185 1185 6 3920 )); DATA(insert ( 2745 1270 1270 1 1358 )); DATA(insert ( 2745 1270 1270 2 2743 )); DATA(insert ( 2745 1270 1270 3 2774 )); DATA(insert ( 2745 1270 1270 4 2744 )); +DATA(insert ( 2745 1270 1270 6 3920 )); DATA(insert ( 2745 1563 1563 1 1672 )); DATA(insert ( 2745 1563 1563 2 2743 )); DATA(insert ( 2745 1563 1563 3 2774 )); DATA(insert ( 2745 1563 1563 4 2744 )); +DATA(insert ( 2745 1563 1563 6 3920 )); DATA(insert ( 2745 1115 1115 1 2045 )); DATA(insert ( 2745 1115 1115 2 2743 )); DATA(insert ( 2745 1115 1115 3 2774 )); DATA(insert ( 2745 1115 1115 4 2744 )); +DATA(insert ( 2745 1115 1115 6 3920 )); DATA(insert ( 2745 791 791 1 377 )); DATA(insert ( 2745 791 791 2 2743 )); DATA(insert ( 2745 791 791 3 2774 )); DATA(insert ( 2745 791 791 4 2744 )); +DATA(insert ( 2745 791 791 6 3920 )); DATA(insert ( 2745 1024 1024 1 380 )); DATA(insert ( 2745 1024 1024 2 2743 )); DATA(insert ( 2745 1024 1024 3 2774 )); DATA(insert ( 2745 1024 1024 4 2744 )); +DATA(insert ( 2745 1024 1024 6 3920 )); DATA(insert ( 2745 1025 1025 1 381 )); DATA(insert ( 2745 1025 1025 2 2743 )); DATA(insert ( 2745 1025 1025 3 2774 )); DATA(insert ( 2745 1025 1025 4 2744 )); +DATA(insert ( 2745 1025 1025 6 3920 )); DATA(insert ( 3659 3614 3614 1 3724 )); DATA(insert ( 3659 3614 3614 2 3656 )); DATA(insert ( 3659 3614 3614 3 3657 )); DATA(insert ( 3659 3614 3614 4 3658 )); DATA(insert ( 3659 3614 3614 5 2700 )); -DATA(insert ( 3626 3614 3614 1 3622 )); -DATA(insert ( 3683 3615 3615 1 3668 )); -DATA(insert ( 3901 3831 3831 1 3870 )); -DATA(insert ( 3903 3831 3831 1 3902 )); -DATA(insert ( 3919 3831 3831 1 3875 )); -DATA(insert ( 3919 3831 3831 2 3876 )); -DATA(insert ( 3919 3831 3831 3 3877 )); -DATA(insert ( 3919 3831 3831 4 3878 )); -DATA(insert ( 3919 3831 3831 5 3879 )); -DATA(insert ( 3919 3831 3831 6 3880 )); -DATA(insert ( 3919 3831 3831 7 3881 )); - +DATA(insert ( 3659 3614 3614 6 3921 )); +DATA(insert ( 4036 3802 3802 1 3480 )); +DATA(insert ( 4036 3802 3802 2 3482 )); +DATA(insert ( 4036 3802 3802 3 3483 )); +DATA(insert ( 4036 3802 3802 4 3484 )); +DATA(insert ( 4036 3802 3802 6 3488 )); +DATA(insert ( 4037 3802 3802 1 351 )); +DATA(insert ( 4037 3802 3802 2 3485 )); +DATA(insert ( 4037 3802 3802 3 3486 )); +DATA(insert ( 4037 3802 3802 4 3487 )); +DATA(insert ( 4037 3802 3802 6 3489 )); +DATA(insert ( 3550 869 869 1 3553 )); +DATA(insert ( 3550 869 869 2 3554 )); +DATA(insert ( 3550 869 869 3 3555 )); +DATA(insert ( 3550 869 869 4 3556 )); +DATA(insert ( 3550 869 869 5 3557 )); +DATA(insert ( 3550 869 869 6 3558 )); +DATA(insert ( 3550 869 869 7 3559 )); /* sp-gist */ +DATA(insert ( 3474 3831 3831 1 3469 )); +DATA(insert ( 3474 3831 3831 2 3470 )); +DATA(insert ( 3474 3831 3831 3 3471 )); +DATA(insert ( 3474 3831 3831 4 3472 )); +DATA(insert ( 3474 3831 3831 5 3473 )); DATA(insert ( 4015 600 600 1 4018 )); DATA(insert ( 4015 600 600 2 4019 )); DATA(insert ( 4015 600 600 3 4020 )); diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h index b92fd1593f..b8ceefd7cd 100644 --- a/src/include/catalog/pg_attrdef.h +++ b/src/include/catalog/pg_attrdef.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_attrdef.h @@ -22,7 +22,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_attrdef definition. cpp turns this into + * pg_attrdef definition. cpp turns this into * typedef struct FormData_pg_attrdef * ---------------- */ @@ -31,7 +31,7 @@ CATALOG(pg_attrdef,2604) { Oid adrelid; /* OID of table containing attribute */ - int2 adnum; /* attnum of attribute */ + int16 adnum; /* attnum of attribute */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ pg_node_tree adbin; /* nodeToString representation of default */ diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 4ee1d90ce3..cdde814307 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_attribute.h @@ -54,13 +54,13 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK * that no value has been explicitly set for this column, so ANALYZE * should use the default setting. */ - int4 attstattarget; + int32 attstattarget; /* * attlen is a copy of the typlen field from pg_type for this attribute. * See atttypid comments above. */ - int2 attlen; + int16 attlen; /* * attnum is the "attribute number" for the attribute: A value that @@ -75,13 +75,13 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK * * Note that (attnum - 1) is often used as the index to an array. */ - int2 attnum; + int16 attnum; /* * attndims is the declared number of dimensions, if an array type, * otherwise zero. */ - int4 attndims; + int32 attndims; /* * fastgetattr() uses attcacheoff to cache byte offsets of attributes in @@ -90,7 +90,7 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK * descriptor, we may then update attcacheoff in the copies. This speeds * up the attribute walking process. */ - int4 attcacheoff; + int32 attcacheoff; /* * atttypmod records type-specific data supplied at table creation time @@ -98,7 +98,7 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK * type-specific input and output functions as the third argument. The * value will generally be -1 for types that do not need typmod. */ - int4 atttypmod; + int32 atttypmod; /* * attbyval is a copy of the typbyval field from pg_type for this @@ -140,7 +140,7 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK bool attislocal; /* Number of times inherited from direct parent relation(s) */ - int4 attinhcount; + int32 attinhcount; /* attribute's collation */ Oid attcollation; @@ -161,7 +161,7 @@ CATALOG(pg_attribute,1249) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75) BK /* * ATTRIBUTE_FIXED_PART_SIZE is the size of the fixed-layout, - * guaranteed-not-null part of a pg_attribute row. This is in fact as much + * guaranteed-not-null part of a pg_attribute row. This is in fact as much * of the row as gets copied into tuple descriptors, so don't expect you * can access fields beyond attcollation except in a real tuple! */ diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h index ea2deb7c91..ac14457c44 100644 --- a/src/include/catalog/pg_auth_members.h +++ b/src/include/catalog/pg_auth_members.h @@ -5,7 +5,7 @@ * (pg_auth_members) along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_auth_members.h diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index e96c875f58..e7c32c9fa6 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -7,7 +7,7 @@ * pg_shadow and pg_group are now publicly accessible views on pg_authid. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_authid.h @@ -26,7 +26,7 @@ /* * The CATALOG definition has to refer to the type of rolvaliduntil as * "timestamptz" (lower case) so that bootstrap mode recognizes it. But - * the C header files define this type as TimestampTz. Since the field is + * the C header files define this type as TimestampTz. Since the field is * potentially-null and therefore can't be accessed directly from C code, * there is no particular need for the C struct definition to show the * field type as TimestampTz --- instead we just make it int. @@ -52,7 +52,7 @@ CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MAC bool rolcatupdate; /* allowed to alter catalogs manually? */ bool rolcanlogin; /* allowed to log in as session user? */ bool rolreplication; /* role used for streaming replication */ - int4 rolconnlimit; /* max connections allowed (-1=no limit) */ + int32 rolconnlimit; /* max connections allowed (-1=no limit) */ /* remaining fields may be null; use heap_getattr to read them! */ text rolpassword; /* password, if any */ diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index ac2b2968eb..e037957472 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -8,7 +8,7 @@ * but also length coercion functions. * * - * Copyright (c) 2002-2012, PostgreSQL Global Development Group + * Copyright (c) 2002-2014, PostgreSQL Global Development Group * * src/include/catalog/pg_cast.h * @@ -359,4 +359,8 @@ DATA(insert ( 1560 1560 1685 i f )); DATA(insert ( 1562 1562 1687 i f )); DATA(insert ( 1700 1700 1703 i f )); +/* json to/from jsonb */ +DATA(insert ( 114 3802 0 e i )); +DATA(insert ( 3802 114 0 e i )); + #endif /* PG_CAST_H */ diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index 1567206a7e..f2fb317e5f 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_class.h @@ -43,30 +43,33 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO /* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */ Oid reltablespace; /* identifier of table space for relation */ - int4 relpages; /* # of blocks (not always up-to-date) */ + int32 relpages; /* # of blocks (not always up-to-date) */ float4 reltuples; /* # of tuples (not always up-to-date) */ - int4 relallvisible; /* # of all-visible blocks (not always + int32 relallvisible; /* # of all-visible blocks (not always * up-to-date) */ Oid reltoastrelid; /* OID of toast table; 0 if none */ - Oid reltoastidxid; /* if toast table, OID of chunk_id index */ bool relhasindex; /* T if has (or has had) any indexes */ bool relisshared; /* T if shared across databases */ char relpersistence; /* see RELPERSISTENCE_xxx constants below */ char relkind; /* see RELKIND_xxx constants below */ - int2 relnatts; /* number of user attributes */ + int16 relnatts; /* number of user attributes */ /* * Class pg_attribute must contain exactly "relnatts" user attributes * (with attnums ranging from 1 to relnatts) for this class. It may also * contain entries with negative attnums for system attributes. */ - int2 relchecks; /* # of CHECK constraints for class */ + int16 relchecks; /* # of CHECK constraints for class */ bool relhasoids; /* T if we generate OIDs for rows of rel */ bool relhaspkey; /* has (or has had) PRIMARY KEY index */ bool relhasrules; /* has (or has had) any rules */ bool relhastriggers; /* has (or has had) any TRIGGERs */ bool relhassubclass; /* has (or has had) derived classes */ + bool relispopulated; /* matview currently holds query results */ + char relreplident; /* see REPLICA_IDENTITY_xxx constants */ TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */ + TransactionId relminmxid; /* all multixacts in this rel are >= this. + * this is really a MultiXactId */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ @@ -77,7 +80,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO /* Size of fixed part of pg_class tuples, not counting var-length fields */ #define CLASS_TUPLE_SIZE \ - (offsetof(FormData_pg_class,relfrozenxid) + sizeof(TransactionId)) + (offsetof(FormData_pg_class,relminmxid) + sizeof(TransactionId)) /* ---------------- * Form_pg_class corresponds to a pointer to a tuple with @@ -91,7 +94,7 @@ typedef FormData_pg_class *Form_pg_class; * ---------------- */ -#define Natts_pg_class 27 +#define Natts_pg_class 29 #define Anum_pg_class_relname 1 #define Anum_pg_class_relnamespace 2 #define Anum_pg_class_reltype 3 @@ -104,21 +107,23 @@ typedef FormData_pg_class *Form_pg_class; #define Anum_pg_class_reltuples 10 #define Anum_pg_class_relallvisible 11 #define Anum_pg_class_reltoastrelid 12 -#define Anum_pg_class_reltoastidxid 13 -#define Anum_pg_class_relhasindex 14 -#define Anum_pg_class_relisshared 15 -#define Anum_pg_class_relpersistence 16 -#define Anum_pg_class_relkind 17 -#define Anum_pg_class_relnatts 18 -#define Anum_pg_class_relchecks 19 -#define Anum_pg_class_relhasoids 20 -#define Anum_pg_class_relhaspkey 21 -#define Anum_pg_class_relhasrules 22 -#define Anum_pg_class_relhastriggers 23 -#define Anum_pg_class_relhassubclass 24 -#define Anum_pg_class_relfrozenxid 25 -#define Anum_pg_class_relacl 26 -#define Anum_pg_class_reloptions 27 +#define Anum_pg_class_relhasindex 13 +#define Anum_pg_class_relisshared 14 +#define Anum_pg_class_relpersistence 15 +#define Anum_pg_class_relkind 16 +#define Anum_pg_class_relnatts 17 +#define Anum_pg_class_relchecks 18 +#define Anum_pg_class_relhasoids 19 +#define Anum_pg_class_relhaspkey 20 +#define Anum_pg_class_relhasrules 21 +#define Anum_pg_class_relhastriggers 22 +#define Anum_pg_class_relhassubclass 23 +#define Anum_pg_class_relispopulated 24 +#define Anum_pg_class_relreplident 25 +#define Anum_pg_class_relfrozenxid 26 +#define Anum_pg_class_relminmxid 27 +#define Anum_pg_class_relacl 28 +#define Anum_pg_class_reloptions 29 /* ---------------- * initial contents of pg_class @@ -129,14 +134,17 @@ typedef FormData_pg_class *Form_pg_class; * ---------------- */ -/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 0 f f p r 30 0 t f f f f 3 _null_ _null_ )); +/* + * Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId; + * similarly, "1" in relminmxid stands for FirstMultiXactId + */ +DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 0 f f p r 21 0 f f f f f 3 _null_ _null_ )); +DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 21 0 f f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 0 f f p r 27 0 t f f f f 3 _null_ _null_ )); +DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 0 f f p r 27 0 t f f f f 3 _null_ _null_ )); +DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 29 0 t f f f f t n 3 1 _null_ _null_ )); DESCR(""); @@ -147,10 +155,22 @@ DESCR(""); #define RELKIND_VIEW 'v' /* view */ #define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ -#define RELKIND_UNCATALOGED 'u' /* not yet cataloged */ +#define RELKIND_MATVIEW 'm' /* materialized view */ #define RELPERSISTENCE_PERMANENT 'p' /* regular table */ #define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ #define RELPERSISTENCE_TEMP 't' /* temporary table */ +/* default selection for replica identity (primary key or nothing) */ +#define REPLICA_IDENTITY_DEFAULT 'd' +/* no replica identity is logged for this relation */ +#define REPLICA_IDENTITY_NOTHING 'n' +/* all columns are loged as replica identity */ +#define REPLICA_IDENTITY_FULL 'f' +/* + * an explicitly chosen candidate key's columns are used as identity; + * will still be set if the index has been dropped, in that case it + * has the same meaning as 'd' + */ +#define REPLICA_IDENTITY_INDEX 'i' #endif /* PG_CLASS_H */ diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h index 8a1917e4f2..6d0b68012c 100644 --- a/src/include/catalog/pg_collation.h +++ b/src/include/catalog/pg_collation.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -34,7 +34,7 @@ CATALOG(pg_collation,3456) NameData collname; /* collation name */ Oid collnamespace; /* OID of namespace containing collation */ Oid collowner; /* owner of collation */ - int4 collencoding; /* encoding for this collation; -1 = "all" */ + int32 collencoding; /* encoding for this collation; -1 = "all" */ NameData collcollate; /* LC_COLLATE setting */ NameData collctype; /* LC_CTYPE setting */ } FormData_pg_collation; diff --git a/src/include/catalog/pg_collation_fn.h b/src/include/catalog/pg_collation_fn.h index 62f158256d..62841155ad 100644 --- a/src/include/catalog/pg_collation_fn.h +++ b/src/include/catalog/pg_collation_fn.h @@ -4,7 +4,7 @@ * prototypes for functions in catalog/pg_collation.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_collation_fn.h diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index b9e4bf41f9..014b85bd20 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_constraint.h @@ -20,6 +20,7 @@ #define PG_CONSTRAINT_H #include "catalog/genbki.h" +#include "catalog/dependency.h" #include "nodes/pg_list.h" /* ---------------- @@ -37,7 +38,7 @@ CATALOG(pg_constraint,2606) * relations. This is partly for backwards compatibility with past * Postgres practice, and partly because we don't want to have to obtain a * global lock to generate a globally unique name for a nameless - * constraint. We associate a namespace with constraint names only for + * constraint. We associate a namespace with constraint names only for * SQL-spec compatibility. */ NameData conname; /* name of this constraint */ @@ -56,7 +57,7 @@ CATALOG(pg_constraint,2606) /* * contypid links to the pg_type row for a domain if this is a domain - * constraint. Otherwise it's 0. + * constraint. Otherwise it's 0. * * For SQL-style global ASSERTIONs, both conrelid and contypid would be * zero. This is not presently supported, however. @@ -75,7 +76,7 @@ CATALOG(pg_constraint,2606) /* * These fields, plus confkey, are only meaningful for a foreign-key - * constraint. Otherwise confrelid is 0 and the char fields are spaces. + * constraint. Otherwise confrelid is 0 and the char fields are spaces. */ Oid confrelid; /* relation referenced by foreign key */ char confupdtype; /* foreign key's ON UPDATE action */ @@ -86,7 +87,7 @@ CATALOG(pg_constraint,2606) bool conislocal; /* Number of times inherited from direct parent relation(s) */ - int4 coninhcount; + int32 coninhcount; /* Has a local definition and cannot be inherited */ bool connoinherit; @@ -97,12 +98,12 @@ CATALOG(pg_constraint,2606) * Columns of conrelid that the constraint applies to, if known (this is * NULL for trigger constraints) */ - int2 conkey[1]; + int16 conkey[1]; /* * If a foreign key, the referenced columns of confrelid */ - int2 confkey[1]; + int16 confkey[1]; /* * If a foreign key, the OIDs of the PK = FK equality operators for each @@ -231,7 +232,8 @@ extern Oid CreateConstraintEntry(const char *constraintName, const char *conSrc, bool conIsLocal, int conInhCount, - bool conIsOnly); + bool conNoInherit, + bool is_internal); extern void RemoveConstraintById(Oid conId); extern void RenameConstraintById(Oid conId, const char *newname); @@ -244,7 +246,8 @@ extern char *ChooseConstraintName(const char *name1, const char *name2, List *others); extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, - Oid newNspId, bool isType); + Oid newNspId, bool isType, ObjectAddresses *objsMoved); +extern void get_constraint_relation_oids(Oid constraint_oid, Oid *conrelid, Oid *confrelid); extern Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok); extern Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 5cff39608b..ba79d253ae 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -5,7 +5,7 @@ * However, we define it here so that the format is documented. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_control.h @@ -21,7 +21,7 @@ /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 922 +#define PG_CONTROL_VERSION 942 /* * Body of CheckPoint XLOG records. This is declared here because we keep @@ -33,6 +33,8 @@ typedef struct CheckPoint XLogRecPtr redo; /* next RecPtr available when we began to * create CheckPoint (i.e. REDO start point) */ TimeLineID ThisTimeLineID; /* current TLI */ + TimeLineID PrevTimeLineID; /* previous TLI, if this record begins a new + * timeline (equals ThisTimeLineID otherwise) */ bool fullPageWrites; /* current full_page_writes */ uint32 nextXidEpoch; /* higher-order bits of nextXid */ TransactionId nextXid; /* next free XID */ @@ -41,6 +43,8 @@ typedef struct CheckPoint MultiXactOffset nextMultiOffset; /* next free MultiXact offset */ TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ Oid oldestXidDB; /* database with minimum datfrozenxid */ + MultiXactId oldestMulti; /* cluster-wide minimum datminmxid */ + Oid oldestMultiDB; /* database with minimum datminmxid */ pg_time_t time; /* time stamp of checkpoint */ /* @@ -61,7 +65,9 @@ typedef struct CheckPoint #define XLOG_BACKUP_END 0x50 #define XLOG_PARAMETER_CHANGE 0x60 #define XLOG_RESTORE_POINT 0x70 -#define XLOG_FPW_CHANGE 0x80 +#define XLOG_FPW_CHANGE 0x80 +#define XLOG_END_OF_RECOVERY 0x90 +#define XLOG_FPI 0xA0 /* @@ -96,9 +102,9 @@ typedef struct ControlFileData uint64 system_identifier; /* - * Version identifier information. Keep these fields at the same offset, + * Version identifier information. Keep these fields at the same offset, * especially pg_control_version; they won't be real useful if they move - * around. (For historical reasons they must be 8 bytes into the file + * around. (For historical reasons they must be 8 bytes into the file * rather than immediately at the front.) * * pg_control_version identifies the format of pg_control itself. @@ -121,6 +127,8 @@ typedef struct ControlFileData CheckPoint checkPointCopy; /* copy of last check point record */ + XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */ + /* * These two values determine the minimum point we must recover up to * before starting up: @@ -153,6 +161,7 @@ typedef struct ControlFileData * pg_start_backup() call, not accompanied by pg_stop_backup(). */ XLogRecPtr minRecoveryPoint; + TimeLineID minRecoveryPointTLI; XLogRecPtr backupStartPoint; XLogRecPtr backupEndPoint; bool backupEndRequired; @@ -162,7 +171,9 @@ typedef struct ControlFileData * or hot standby. */ int wal_level; + bool wal_log_hints; int MaxConnections; + int max_worker_processes; int max_prepared_xacts; int max_locks_per_xact; @@ -196,6 +207,7 @@ typedef struct ControlFileData uint32 indexMaxKeys; /* max number of columns in an index */ uint32 toast_max_chunk_size; /* chunk size in TOAST tables */ + uint32 loblksize; /* chunk size in pg_largeobject */ /* flag indicating internal format of timestamp, interval, time */ bool enableIntTimes; /* int64 storage enabled? */ @@ -204,6 +216,9 @@ typedef struct ControlFileData bool float4ByVal; /* float4 pass-by-value? */ bool float8ByVal; /* float8, int8, etc pass-by-value? */ + /* Are data pages protected by checksums? Zero if no checksum version */ + uint32 data_checksum_version; + /* CRC of all above ... MUST BE LAST! */ pg_crc32 crc; } ControlFileData; diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h index 04fe3e8706..db5e28be17 100644 --- a/src/include/catalog/pg_conversion.h +++ b/src/include/catalog/pg_conversion.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_conversion.h @@ -42,8 +42,8 @@ CATALOG(pg_conversion,2607) NameData conname; Oid connamespace; Oid conowner; - int4 conforencoding; - int4 contoencoding; + int32 conforencoding; + int32 contoencoding; regproc conproc; bool condefault; } FormData_pg_conversion; diff --git a/src/include/catalog/pg_conversion_fn.h b/src/include/catalog/pg_conversion_fn.h index f860522278..d49d2f910b 100644 --- a/src/include/catalog/pg_conversion_fn.h +++ b/src/include/catalog/pg_conversion_fn.h @@ -4,7 +4,7 @@ * prototypes for functions in catalog/pg_conversion.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_conversion_fn.h diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index af803bba89..4e8db873e7 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_database.h @@ -33,14 +33,15 @@ CATALOG(pg_database,1262) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248) BKI_SCHEMA_M { NameData datname; /* database name */ Oid datdba; /* owner of database */ - int4 encoding; /* character encoding */ + int32 encoding; /* character encoding */ NameData datcollate; /* LC_COLLATE setting */ NameData datctype; /* LC_CTYPE setting */ bool datistemplate; /* allowed as CREATE DATABASE template? */ bool datallowconn; /* new connections allowed? */ - int4 datconnlimit; /* max connections allowed (-1=no limit) */ + int32 datconnlimit; /* max connections allowed (-1=no limit) */ Oid datlastsysoid; /* highest OID to consider a system OID */ TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */ + TransactionId datminmxid; /* all multixacts in the DB are >= this */ Oid dattablespace; /* default table space for this DB */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ @@ -59,7 +60,7 @@ typedef FormData_pg_database *Form_pg_database; * compiler constants for pg_database * ---------------- */ -#define Natts_pg_database 12 +#define Natts_pg_database 13 #define Anum_pg_database_datname 1 #define Anum_pg_database_datdba 2 #define Anum_pg_database_encoding 3 @@ -70,10 +71,11 @@ typedef FormData_pg_database *Form_pg_database; #define Anum_pg_database_datconnlimit 8 #define Anum_pg_database_datlastsysoid 9 #define Anum_pg_database_datfrozenxid 10 -#define Anum_pg_database_dattablespace 11 -#define Anum_pg_database_datacl 12 +#define Anum_pg_database_datminmxid 11 +#define Anum_pg_database_dattablespace 12 +#define Anum_pg_database_datacl 13 -DATA(insert OID = 1 ( template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_)); +DATA(insert OID = 1 ( template1 PGUID ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1 1663 _null_)); SHDESCR("default template for new databases"); #define TemplateDbOid 1 diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h index c6a69c5a6d..054e87a0dd 100644 --- a/src/include/catalog/pg_db_role_setting.h +++ b/src/include/catalog/pg_db_role_setting.h @@ -4,7 +4,7 @@ * definition of configuration settings * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_db_role_setting.h @@ -23,9 +23,10 @@ #include "utils/guc.h" #include "utils/relcache.h" +#include "utils/snapshot.h" /* ---------------- - * pg_db_role_setting definition. cpp turns this into + * pg_db_role_setting definition. cpp turns this into * typedef struct FormData_pg_db_role_setting * ---------------- */ @@ -62,7 +63,7 @@ typedef FormData_pg_db_role_setting *Form_pg_db_role_setting; */ extern void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt); extern void DropSetting(Oid databaseid, Oid roleid); -extern void ApplySetting(Oid databaseid, Oid roleid, Relation relsetting, - GucSource source); +extern void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, + Relation relsetting, GucSource source); #endif /* PG_DB_ROLE_SETTING_H */ diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h index d7421007af..749e2e431d 100644 --- a/src/include/catalog/pg_default_acl.h +++ b/src/include/catalog/pg_default_acl.h @@ -4,7 +4,7 @@ * definition of default ACLs for new objects. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_default_acl.h @@ -21,7 +21,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_default_acl definition. cpp turns this into + * pg_default_acl definition. cpp turns this into * typedef struct FormData_pg_default_acl * ---------------- */ @@ -63,7 +63,7 @@ typedef FormData_pg_default_acl *Form_pg_default_acl; /* * Types of objects for which the user is allowed to specify default - * permissions through pg_default_acl. These codes are used in the + * permissions through pg_default_acl. These codes are used in the * defaclobjtype column. */ #define DEFACLOBJ_RELATION 'r' /* table, view */ diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h index e56dd1ad3d..207694211b 100644 --- a/src/include/catalog/pg_depend.h +++ b/src/include/catalog/pg_depend.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_depend.h @@ -37,14 +37,14 @@ CATALOG(pg_depend,2608) BKI_WITHOUT_OIDS */ Oid classid; /* OID of table containing object */ Oid objid; /* OID of object itself */ - int4 objsubid; /* column number, or 0 if not used */ + int32 objsubid; /* column number, or 0 if not used */ /* * Identification of the independent (referenced) object. */ Oid refclassid; /* OID of table containing object */ Oid refobjid; /* OID of object itself */ - int4 refobjsubid; /* column number, or 0 if not used */ + int32 refobjsubid; /* column number, or 0 if not used */ /* * Precise semantics of the relationship are specified by the deptype diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h index a454194893..b5f23b808f 100644 --- a/src/include/catalog/pg_description.h +++ b/src/include/catalog/pg_description.h @@ -6,12 +6,12 @@ * NOTE: an object is identified by the OID of the row that primarily * defines the object, plus the OID of the table that that row appears in. * For example, a function is identified by the OID of its pg_proc row - * plus the pg_class OID of table pg_proc. This allows unique identification + * plus the pg_class OID of table pg_proc. This allows unique identification * of objects without assuming that OIDs are unique across tables. * * Since attributes don't have OIDs of their own, we identify an attribute * comment by the objoid+classoid of its parent table, plus an "objsubid" - * giving the attribute column number. "objsubid" must be zero in a comment + * giving the attribute column number. "objsubid" must be zero in a comment * for a table itself, so that it is distinct from any column comment. * Currently, objsubid is unused and zero for all other kinds of objects, * but perhaps it might be useful someday to associate comments with @@ -19,7 +19,7 @@ * for example). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_description.h @@ -39,7 +39,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_description definition. cpp turns this into + * pg_description definition. cpp turns this into * typedef struct FormData_pg_description * ---------------- */ @@ -49,7 +49,7 @@ CATALOG(pg_description,2609) BKI_WITHOUT_OIDS { Oid objoid; /* OID of object itself */ Oid classoid; /* OID of table containing object */ - int4 objsubid; /* column number, or 0 if not used */ + int32 objsubid; /* column number, or 0 if not used */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ text description; /* description of object */ diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h index 91c1ab1de7..b50addb76d 100644 --- a/src/include/catalog/pg_enum.h +++ b/src/include/catalog/pg_enum.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Copyright (c) 2006-2012, PostgreSQL Global Development Group + * Copyright (c) 2006-2014, PostgreSQL Global Development Group * * src/include/catalog/pg_enum.h * @@ -65,6 +65,7 @@ typedef FormData_pg_enum *Form_pg_enum; extern void EnumValuesCreate(Oid enumTypeOid, List *vals); extern void EnumValuesDelete(Oid enumTypeOid); extern void AddEnumLabel(Oid enumTypeOid, const char *newVal, - const char *neighbor, bool newValIsAfter); + const char *neighbor, bool newValIsAfter, + bool skipIfExists); #endif /* PG_ENUM_H */ diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h new file mode 100644 index 0000000000..1284b88cec --- /dev/null +++ b/src/include/catalog/pg_event_trigger.h @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * pg_event_trigger.h + * definition of the system "event trigger" relation (pg_event_trigger) + * along with the relation's initial contents. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_event_trigger.h + * + * NOTES + * the genbki.pl script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_EVENT_TRIGGER_H +#define PG_EVENT_TRIGGER_H + +#include "catalog/genbki.h" + +/* ---------------- + * pg_event_trigger definition. cpp turns this into + * typedef struct FormData_pg_event_trigger + * ---------------- + */ +#define EventTriggerRelationId 3466 + +CATALOG(pg_event_trigger,3466) +{ + NameData evtname; /* trigger's name */ + NameData evtevent; /* trigger's event */ + Oid evtowner; /* trigger's owner */ + Oid evtfoid; /* OID of function to be called */ + char evtenabled; /* trigger's firing configuration WRT + * session_replication_role */ + +#ifdef CATALOG_VARLEN + text evttags[1]; /* command TAGs this event trigger targets */ +#endif +} FormData_pg_event_trigger; + +/* ---------------- + * Form_pg_event_trigger corresponds to a pointer to a tuple with + * the format of pg_event_trigger relation. + * ---------------- + */ +typedef FormData_pg_event_trigger *Form_pg_event_trigger; + +/* ---------------- + * compiler constants for pg_event_trigger + * ---------------- + */ +#define Natts_pg_event_trigger 6 +#define Anum_pg_event_trigger_evtname 1 +#define Anum_pg_event_trigger_evtevent 2 +#define Anum_pg_event_trigger_evtowner 3 +#define Anum_pg_event_trigger_evtfoid 4 +#define Anum_pg_event_trigger_evtenabled 5 +#define Anum_pg_event_trigger_evttags 6 + +#endif /* PG_EVENT_TRIGGER_H */ diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h index 4807c6a733..15b24eb8db 100644 --- a/src/include/catalog/pg_extension.h +++ b/src/include/catalog/pg_extension.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_extension.h diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h index 18c538f49c..9ad25d8061 100644 --- a/src/include/catalog/pg_foreign_data_wrapper.h +++ b/src/include/catalog/pg_foreign_data_wrapper.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_data_wrapper.h diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h index 38830af29e..d57e672661 100644 --- a/src/include/catalog/pg_foreign_server.h +++ b/src/include/catalog/pg_foreign_server.h @@ -3,7 +3,7 @@ * pg_foreign_server.h * definition of the system "foreign server" relation (pg_foreign_server) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_server.h diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h index 186c49d425..50b17a1146 100644 --- a/src/include/catalog/pg_foreign_table.h +++ b/src/include/catalog/pg_foreign_table.h @@ -3,7 +3,7 @@ * pg_foreign_table.h * definition of the system "foreign table" relation (pg_foreign_table) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_table.h diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h index 9a86121cf9..8b8be3bfbf 100644 --- a/src/include/catalog/pg_index.h +++ b/src/include/catalog/pg_index.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_index.h @@ -32,7 +32,7 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO { Oid indexrelid; /* OID of the index */ Oid indrelid; /* OID of the relation it indexes */ - int2 indnatts; /* number of columns in index */ + int16 indnatts; /* number of columns in index */ bool indisunique; /* is this a unique index? */ bool indisprimary; /* is this index for primary key? */ bool indisexclusion; /* is this index for exclusion constraint? */ @@ -41,6 +41,8 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO bool indisvalid; /* is this index valid for use by queries? */ bool indcheckxmin; /* must we wait for xmin to be old? */ bool indisready; /* is this index ready for inserts? */ + bool indislive; /* is this index alive at all? */ + bool indisreplident; /* is this index the identity for replication? */ /* variable-length fields start here, but we allow direct access to indkey */ int2vector indkey; /* column numbers of indexed cols, or 0 */ @@ -68,7 +70,7 @@ typedef FormData_pg_index *Form_pg_index; * compiler constants for pg_index * ---------------- */ -#define Natts_pg_index 17 +#define Natts_pg_index 19 #define Anum_pg_index_indexrelid 1 #define Anum_pg_index_indrelid 2 #define Anum_pg_index_indnatts 3 @@ -80,12 +82,14 @@ typedef FormData_pg_index *Form_pg_index; #define Anum_pg_index_indisvalid 9 #define Anum_pg_index_indcheckxmin 10 #define Anum_pg_index_indisready 11 -#define Anum_pg_index_indkey 12 -#define Anum_pg_index_indcollation 13 -#define Anum_pg_index_indclass 14 -#define Anum_pg_index_indoption 15 -#define Anum_pg_index_indexprs 16 -#define Anum_pg_index_indpred 17 +#define Anum_pg_index_indislive 12 +#define Anum_pg_index_indisreplident 13 +#define Anum_pg_index_indkey 14 +#define Anum_pg_index_indcollation 15 +#define Anum_pg_index_indclass 16 +#define Anum_pg_index_indoption 17 +#define Anum_pg_index_indexprs 18 +#define Anum_pg_index_indpred 19 /* * Index AMs that support ordered scans must support these two indoption @@ -95,4 +99,13 @@ typedef FormData_pg_index *Form_pg_index; #define INDOPTION_DESC 0x0001 /* values are in reverse order */ #define INDOPTION_NULLS_FIRST 0x0002 /* NULLs are first instead of last */ +/* + * Use of these macros is recommended over direct examination of the state + * flag columns where possible; this allows source code compatibility with + * the hacky representation used in 9.2. + */ +#define IndexIsValid(indexForm) ((indexForm)->indisvalid) +#define IndexIsReady(indexForm) ((indexForm)->indisready) +#define IndexIsLive(indexForm) ((indexForm)->indislive) + #endif /* PG_INDEX_H */ diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h index 18552bde7e..cda48f2519 100644 --- a/src/include/catalog/pg_inherits.h +++ b/src/include/catalog/pg_inherits.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_inherits.h @@ -32,7 +32,7 @@ CATALOG(pg_inherits,2611) BKI_WITHOUT_OIDS { Oid inhrelid; Oid inhparent; - int4 inhseqno; + int32 inhseqno; } FormData_pg_inherits; /* ---------------- diff --git a/src/include/catalog/pg_inherits_fn.h b/src/include/catalog/pg_inherits_fn.h index 9484b41dec..757d8499e1 100644 --- a/src/include/catalog/pg_inherits_fn.h +++ b/src/include/catalog/pg_inherits_fn.h @@ -4,7 +4,7 @@ * prototypes for functions in catalog/pg_inherits.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_inherits_fn.h diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h index 79cfa09d02..4032fe080e 100644 --- a/src/include/catalog/pg_language.h +++ b/src/include/catalog/pg_language.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_language.h diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h index d442ec4e4a..b341f92eb7 100644 --- a/src/include/catalog/pg_largeobject.h +++ b/src/include/catalog/pg_largeobject.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_largeobject.h @@ -22,7 +22,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_largeobject definition. cpp turns this into + * pg_largeobject definition. cpp turns this into * typedef struct FormData_pg_largeobject * ---------------- */ @@ -31,7 +31,7 @@ CATALOG(pg_largeobject,2613) BKI_WITHOUT_OIDS { Oid loid; /* Identifier of large object */ - int4 pageno; /* Page number (starting from 0) */ + int32 pageno; /* Page number (starting from 0) */ /* data has variable length, but we allow direct access; see inv_api.c */ bytea data; /* Data for page (may be zero-length) */ @@ -55,7 +55,6 @@ typedef FormData_pg_largeobject *Form_pg_largeobject; extern Oid LargeObjectCreate(Oid loid); extern void LargeObjectDrop(Oid loid); -extern void LargeObjectAlterOwner(Oid loid, Oid newOwnerId); extern bool LargeObjectExists(Oid loid); #endif /* PG_LARGEOBJECT_H */ diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h index 768497eb52..9f4f63267c 100644 --- a/src/include/catalog/pg_largeobject_metadata.h +++ b/src/include/catalog/pg_largeobject_metadata.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_largeobject_metadata.h diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index 2e63e8dd6b..e58ef3aa21 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -10,7 +10,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_namespace.h diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 638f8088c7..dc523416c9 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -17,15 +17,15 @@ * don't support partial indexes on system catalogs.) * * Normally opckeytype = InvalidOid (zero), indicating that the data stored - * in the index is the same as the data in the indexed column. If opckeytype + * in the index is the same as the data in the indexed column. If opckeytype * is nonzero then it indicates that a conversion step is needed to produce * the stored index data, which will be of type opckeytype (which might be - * the same or different from the input datatype). Performing such a + * the same or different from the input datatype). Performing such a * conversion is the responsibility of the index access method --- not all * AMs support this. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_opclass.h @@ -42,7 +42,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_opclass definition. cpp turns this into + * pg_opclass definition. cpp turns this into * typedef struct FormData_pg_opclass * ---------------- */ @@ -112,6 +112,7 @@ DATA(insert OID = 3123 ( 403 float8_ops PGNSP PGUID 1970 701 t 0 )); DATA(insert ( 405 float8_ops PGNSP PGUID 1971 701 t 0 )); DATA(insert ( 403 inet_ops PGNSP PGUID 1974 869 t 0 )); DATA(insert ( 405 inet_ops PGNSP PGUID 1975 869 t 0 )); +DATA(insert ( 783 inet_ops PGNSP PGUID 3550 869 f 0 )); DATA(insert OID = 1979 ( 403 int2_ops PGNSP PGUID 1976 21 t 0 )); #define INT2_BTREE_OPS_OID 1979 DATA(insert ( 405 int2_ops PGNSP PGUID 1977 21 t 0 )); @@ -143,6 +144,7 @@ DATA(insert ( 405 oid_ops PGNSP PGUID 1990 26 t 0 )); DATA(insert ( 403 oidvector_ops PGNSP PGUID 1991 30 t 0 )); DATA(insert ( 405 oidvector_ops PGNSP PGUID 1992 30 t 0 )); DATA(insert ( 403 record_ops PGNSP PGUID 2994 2249 t 0 )); +DATA(insert ( 403 record_image_ops PGNSP PGUID 3194 2249 f 0 )); DATA(insert OID = 3126 ( 403 text_ops PGNSP PGUID 1994 25 t 0 )); #define TEXT_BTREE_OPS_OID 3126 DATA(insert ( 405 text_ops PGNSP PGUID 1995 25 t 0 )); @@ -213,6 +215,8 @@ DATA(insert ( 2742 _reltime_ops PGNSP PGUID 2745 1024 t 703 )); DATA(insert ( 2742 _tinterval_ops PGNSP PGUID 2745 1025 t 704 )); DATA(insert ( 403 uuid_ops PGNSP PGUID 2968 2950 t 0 )); DATA(insert ( 405 uuid_ops PGNSP PGUID 2969 2950 t 0 )); +DATA(insert ( 403 pg_lsn_ops PGNSP PGUID 3253 3220 t 0 )); +DATA(insert ( 405 pg_lsn_ops PGNSP PGUID 3254 3220 t 0 )); DATA(insert ( 403 enum_ops PGNSP PGUID 3522 3500 t 0 )); DATA(insert ( 405 enum_ops PGNSP PGUID 3523 3500 t 0 )); DATA(insert ( 403 tsvector_ops PGNSP PGUID 3626 3614 t 0 )); @@ -223,8 +227,13 @@ DATA(insert ( 783 tsquery_ops PGNSP PGUID 3702 3615 t 20 )); DATA(insert ( 403 range_ops PGNSP PGUID 3901 3831 t 0 )); DATA(insert ( 405 range_ops PGNSP PGUID 3903 3831 t 0 )); DATA(insert ( 783 range_ops PGNSP PGUID 3919 3831 t 0 )); +DATA(insert ( 4000 range_ops PGNSP PGUID 3474 3831 t 0 )); DATA(insert ( 4000 quad_point_ops PGNSP PGUID 4015 600 t 0 )); DATA(insert ( 4000 kd_point_ops PGNSP PGUID 4016 600 f 0 )); DATA(insert ( 4000 text_ops PGNSP PGUID 4017 25 t 0 )); +DATA(insert ( 403 jsonb_ops PGNSP PGUID 4033 3802 t 0 )); +DATA(insert ( 405 jsonb_ops PGNSP PGUID 4034 3802 t 0 )); +DATA(insert ( 2742 jsonb_ops PGNSP PGUID 4036 3802 t 25 )); +DATA(insert ( 2742 jsonb_path_ops PGNSP PGUID 4037 3802 f 23 )); #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 94702541f5..87ee4eb852 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_operator.h @@ -128,8 +128,10 @@ DATA(insert OID = 95 ( "<" PGNSP PGUID b f f 21 21 16 520 524 int2lt scalar DESCR("less than"); DATA(insert OID = 96 ( "=" PGNSP PGUID b t t 23 23 16 96 518 int4eq eqsel eqjoinsel )); DESCR("equal"); +#define Int4EqualOperator 96 DATA(insert OID = 97 ( "<" PGNSP PGUID b f f 23 23 16 521 525 int4lt scalarltsel scalarltjoinsel )); DESCR("less than"); +#define Int4LessOperator 97 DATA(insert OID = 98 ( "=" PGNSP PGUID b t t 25 25 16 98 531 texteq eqsel eqjoinsel )); DESCR("equal"); #define TextEqualOperator 98 @@ -175,6 +177,7 @@ DATA(insert OID = 411 ( "<>" PGNSP PGUID b f f 20 20 16 411 410 int8ne neqsel DESCR("not equal"); DATA(insert OID = 412 ( "<" PGNSP PGUID b f f 20 20 16 413 415 int8lt scalarltsel scalarltjoinsel )); DESCR("less than"); +#define Int8LessOperator 412 DATA(insert OID = 413 ( ">" PGNSP PGUID b f f 20 20 16 412 414 int8gt scalargtsel scalargtjoinsel )); DESCR("greater than"); DATA(insert OID = 414 ( "<=" PGNSP PGUID b f f 20 20 16 415 413 int8le scalarltsel scalarltjoinsel )); @@ -527,6 +530,7 @@ DATA(insert OID = 671 ( "<>" PGNSP PGUID b f f 701 701 16 671 670 float8ne DESCR("not equal"); DATA(insert OID = 672 ( "<" PGNSP PGUID b f f 701 701 16 674 675 float8lt scalarltsel scalarltjoinsel )); DESCR("less than"); +#define Float8LessOperator 672 DATA(insert OID = 673 ( "<=" PGNSP PGUID b f f 701 701 16 675 674 float8le scalarltsel scalarltjoinsel )); DESCR("less than or equal"); DATA(insert OID = 674 ( ">" PGNSP PGUID b f f 701 701 16 672 673 float8gt scalargtsel scalargtjoinsel )); @@ -1136,18 +1140,20 @@ DATA(insert OID = 1205 ( ">" PGNSP PGUID b f f 869 869 16 1203 1204 network DESCR("greater than"); DATA(insert OID = 1206 ( ">=" PGNSP PGUID b f f 869 869 16 1204 1203 network_ge scalargtsel scalargtjoinsel )); DESCR("greater than or equal"); -DATA(insert OID = 931 ( "<<" PGNSP PGUID b f f 869 869 16 933 0 network_sub - - )); +DATA(insert OID = 931 ( "<<" PGNSP PGUID b f f 869 869 16 933 0 network_sub networksel networkjoinsel )); DESCR("is subnet"); #define OID_INET_SUB_OP 931 -DATA(insert OID = 932 ( "<<=" PGNSP PGUID b f f 869 869 16 934 0 network_subeq - - )); +DATA(insert OID = 932 ( "<<=" PGNSP PGUID b f f 869 869 16 934 0 network_subeq networksel networkjoinsel )); DESCR("is subnet or equal"); #define OID_INET_SUBEQ_OP 932 -DATA(insert OID = 933 ( ">>" PGNSP PGUID b f f 869 869 16 931 0 network_sup - - )); +DATA(insert OID = 933 ( ">>" PGNSP PGUID b f f 869 869 16 931 0 network_sup networksel networkjoinsel )); DESCR("is supernet"); #define OID_INET_SUP_OP 933 -DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f f 869 869 16 932 0 network_supeq - - )); +DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f f 869 869 16 932 0 network_supeq networksel networkjoinsel )); DESCR("is supernet or equal"); #define OID_INET_SUPEQ_OP 934 +DATA(insert OID = 3552 ( "&&" PGNSP PGUID b f f 869 869 16 3552 0 network_overlap networksel networkjoinsel )); +DESCR("overlaps (is subnet or supernet)"); DATA(insert OID = 2634 ( "~" PGNSP PGUID l f f 0 869 869 0 0 inetnot - - )); DESCR("bitwise not"); @@ -1588,6 +1594,22 @@ DESCR("less than or equal"); DATA(insert OID = 2977 ( ">=" PGNSP PGUID b f f 2950 2950 16 2976 2974 uuid_ge scalargtsel scalargtjoinsel )); DESCR("greater than or equal"); +/* pg_lsn operators */ +DATA(insert OID = 3222 ( "=" PGNSP PGUID b t t 3220 3220 16 3222 3223 pg_lsn_eq eqsel eqjoinsel )); +DESCR("equal"); +DATA(insert OID = 3223 ( "<>" PGNSP PGUID b f f 3220 3220 16 3223 3222 pg_lsn_ne neqsel neqjoinsel )); +DESCR("not equal"); +DATA(insert OID = 3224 ( "<" PGNSP PGUID b f f 3220 3220 16 3225 3227 pg_lsn_lt scalarltsel scalarltjoinsel )); +DESCR("less than"); +DATA(insert OID = 3225 ( ">" PGNSP PGUID b f f 3220 3220 16 3224 3226 pg_lsn_gt scalargtsel scalargtjoinsel )); +DESCR("greater than"); +DATA(insert OID = 3226 ( "<=" PGNSP PGUID b f f 3220 3220 16 3227 3225 pg_lsn_le scalarltsel scalarltjoinsel )); +DESCR("less than or equal"); +DATA(insert OID = 3227 ( ">=" PGNSP PGUID b f f 3220 3220 16 3226 3224 pg_lsn_ge scalargtsel scalargtjoinsel )); +DESCR("greater than or equal"); +DATA(insert OID = 3228 ( "-" PGNSP PGUID b f f 3220 3220 1700 0 0 pg_lsn_mi - - )); +DESCR("minus"); + /* enum operators */ DATA(insert OID = 3516 ( "=" PGNSP PGUID b t t 3500 3500 16 3516 3517 enum_eq eqsel eqjoinsel )); DESCR("equal"); @@ -1671,37 +1693,64 @@ DESCR("less than or equal"); DATA(insert OID = 2993 ( ">=" PGNSP PGUID b f f 2249 2249 16 2992 2990 record_ge scalargtsel scalargtjoinsel )); DESCR("greater than or equal"); +/* byte-oriented tests for identical rows and fast sorting */ +DATA(insert OID = 3188 ( "*=" PGNSP PGUID b t f 2249 2249 16 3188 3189 record_image_eq eqsel eqjoinsel )); +DESCR("identical"); +DATA(insert OID = 3189 ( "*<>" PGNSP PGUID b f f 2249 2249 16 3189 3188 record_image_ne neqsel neqjoinsel )); +DESCR("not identical"); +DATA(insert OID = 3190 ( "*<" PGNSP PGUID b f f 2249 2249 16 3191 3193 record_image_lt scalarltsel scalarltjoinsel )); +DESCR("less than"); +DATA(insert OID = 3191 ( "*>" PGNSP PGUID b f f 2249 2249 16 3190 3192 record_image_gt scalargtsel scalargtjoinsel )); +DESCR("greater than"); +DATA(insert OID = 3192 ( "*<=" PGNSP PGUID b f f 2249 2249 16 3193 3191 record_image_le scalarltsel scalarltjoinsel )); +DESCR("less than or equal"); +DATA(insert OID = 3193 ( "*>=" PGNSP PGUID b f f 2249 2249 16 3192 3190 record_image_ge scalargtsel scalargtjoinsel )); +DESCR("greater than or equal"); + /* generic range type operators */ DATA(insert OID = 3882 ( "=" PGNSP PGUID b t t 3831 3831 16 3882 3883 range_eq eqsel eqjoinsel )); DESCR("equal"); DATA(insert OID = 3883 ( "<>" PGNSP PGUID b f f 3831 3831 16 3883 3882 range_ne neqsel neqjoinsel )); DESCR("not equal"); -DATA(insert OID = 3884 ( "<" PGNSP PGUID b f f 3831 3831 16 3887 3886 range_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 3884 ( "<" PGNSP PGUID b f f 3831 3831 16 3887 3886 range_lt rangesel scalarltjoinsel )); DESCR("less than"); -DATA(insert OID = 3885 ( "<=" PGNSP PGUID b f f 3831 3831 16 3886 3887 range_le scalarltsel scalarltjoinsel )); +#define OID_RANGE_LESS_OP 3884 +DATA(insert OID = 3885 ( "<=" PGNSP PGUID b f f 3831 3831 16 3886 3887 range_le rangesel scalarltjoinsel )); DESCR("less than or equal"); -DATA(insert OID = 3886 ( ">=" PGNSP PGUID b f f 3831 3831 16 3885 3884 range_ge scalargtsel scalargtjoinsel )); +#define OID_RANGE_LESS_EQUAL_OP 3885 +DATA(insert OID = 3886 ( ">=" PGNSP PGUID b f f 3831 3831 16 3885 3884 range_ge rangesel scalargtjoinsel )); DESCR("greater than or equal"); -DATA(insert OID = 3887 ( ">" PGNSP PGUID b f f 3831 3831 16 3884 3885 range_gt scalargtsel scalargtjoinsel )); +#define OID_RANGE_GREATER_OP 3886 +DATA(insert OID = 3887 ( ">" PGNSP PGUID b f f 3831 3831 16 3884 3885 range_gt rangesel scalargtjoinsel )); DESCR("greater than"); -DATA(insert OID = 3888 ( "&&" PGNSP PGUID b f f 3831 3831 16 3888 0 range_overlaps areasel areajoinsel )); +#define OID_RANGE_GREATER_EQUAL_OP 3887 +DATA(insert OID = 3888 ( "&&" PGNSP PGUID b f f 3831 3831 16 3888 0 range_overlaps rangesel areajoinsel )); DESCR("overlaps"); -DATA(insert OID = 3889 ( "@>" PGNSP PGUID b f f 3831 2283 16 3891 0 range_contains_elem contsel contjoinsel )); +#define OID_RANGE_OVERLAP_OP 3888 +DATA(insert OID = 3889 ( "@>" PGNSP PGUID b f f 3831 2283 16 3891 0 range_contains_elem rangesel contjoinsel )); DESCR("contains"); -DATA(insert OID = 3890 ( "@>" PGNSP PGUID b f f 3831 3831 16 3892 0 range_contains contsel contjoinsel )); +#define OID_RANGE_CONTAINS_ELEM_OP 3889 +DATA(insert OID = 3890 ( "@>" PGNSP PGUID b f f 3831 3831 16 3892 0 range_contains rangesel contjoinsel )); DESCR("contains"); -DATA(insert OID = 3891 ( "<@" PGNSP PGUID b f f 2283 3831 16 3889 0 elem_contained_by_range contsel contjoinsel )); +#define OID_RANGE_CONTAINS_OP 3890 +DATA(insert OID = 3891 ( "<@" PGNSP PGUID b f f 2283 3831 16 3889 0 elem_contained_by_range rangesel contjoinsel )); DESCR("is contained by"); -DATA(insert OID = 3892 ( "<@" PGNSP PGUID b f f 3831 3831 16 3890 0 range_contained_by contsel contjoinsel )); +#define OID_RANGE_ELEM_CONTAINED_OP 3891 +DATA(insert OID = 3892 ( "<@" PGNSP PGUID b f f 3831 3831 16 3890 0 range_contained_by rangesel contjoinsel )); DESCR("is contained by"); -DATA(insert OID = 3893 ( "<<" PGNSP PGUID b f f 3831 3831 16 3894 0 range_before scalarltsel scalarltjoinsel )); +#define OID_RANGE_CONTAINED_OP 3892 +DATA(insert OID = 3893 ( "<<" PGNSP PGUID b f f 3831 3831 16 3894 0 range_before rangesel scalarltjoinsel )); DESCR("is left of"); -DATA(insert OID = 3894 ( ">>" PGNSP PGUID b f f 3831 3831 16 3893 0 range_after scalargtsel scalargtjoinsel )); +#define OID_RANGE_LEFT_OP 3893 +DATA(insert OID = 3894 ( ">>" PGNSP PGUID b f f 3831 3831 16 3893 0 range_after rangesel scalargtjoinsel )); DESCR("is right of"); -DATA(insert OID = 3895 ( "&<" PGNSP PGUID b f f 3831 3831 16 0 0 range_overleft scalarltsel scalarltjoinsel )); +#define OID_RANGE_RIGHT_OP 3894 +DATA(insert OID = 3895 ( "&<" PGNSP PGUID b f f 3831 3831 16 0 0 range_overleft rangesel scalarltjoinsel )); DESCR("overlaps or is left of"); -DATA(insert OID = 3896 ( "&>" PGNSP PGUID b f f 3831 3831 16 0 0 range_overright scalargtsel scalargtjoinsel )); +#define OID_RANGE_OVERLAPS_LEFT_OP 3895 +DATA(insert OID = 3896 ( "&>" PGNSP PGUID b f f 3831 3831 16 0 0 range_overright rangesel scalargtjoinsel )); DESCR("overlaps or is right of"); +#define OID_RANGE_OVERLAPS_RIGHT_OP 3896 DATA(insert OID = 3897 ( "-|-" PGNSP PGUID b f f 3831 3831 16 3897 0 range_adjacent contsel contjoinsel )); DESCR("is adjacent to"); DATA(insert OID = 3898 ( "+" PGNSP PGUID b f f 3831 3831 3831 3898 0 range_union - - )); @@ -1710,12 +1759,58 @@ DATA(insert OID = 3899 ( "-" PGNSP PGUID b f f 3831 3831 3831 0 0 range_minu DESCR("range difference"); DATA(insert OID = 3900 ( "*" PGNSP PGUID b f f 3831 3831 3831 3900 0 range_intersect - - )); DESCR("range intersection"); - +DATA(insert OID = 3962 ( "->" PGNSP PGUID b f f 114 25 114 0 0 json_object_field - - )); +DESCR("get json object field"); +DATA(insert OID = 3963 ( "->>" PGNSP PGUID b f f 114 25 25 0 0 json_object_field_text - - )); +DESCR("get json object field as text"); +DATA(insert OID = 3964 ( "->" PGNSP PGUID b f f 114 23 114 0 0 json_array_element - - )); +DESCR("get json array element"); +DATA(insert OID = 3965 ( "->>" PGNSP PGUID b f f 114 23 25 0 0 json_array_element_text - - )); +DESCR("get json array element as text"); +DATA(insert OID = 3966 ( "#>" PGNSP PGUID b f f 114 1009 114 0 0 json_extract_path_op - - )); +DESCR("get value from json with path elements"); +DATA(insert OID = 3967 ( "#>>" PGNSP PGUID b f f 114 1009 25 0 0 json_extract_path_text_op - - )); +DESCR("get value from json as text with path elements"); +DATA(insert OID = 3211 ( "->" PGNSP PGUID b f f 3802 25 3802 0 0 jsonb_object_field - - )); +DESCR("get jsonb object field"); +DATA(insert OID = 3477 ( "->>" PGNSP PGUID b f f 3802 25 25 0 0 jsonb_object_field_text - - )); +DESCR("get jsonb object field as text"); +DATA(insert OID = 3212 ( "->" PGNSP PGUID b f f 3802 23 3802 0 0 jsonb_array_element - - )); +DESCR("get jsonb array element"); +DATA(insert OID = 3481 ( "->>" PGNSP PGUID b f f 3802 23 25 0 0 jsonb_array_element_text - - )); +DESCR("get jsonb array element as text"); +DATA(insert OID = 3213 ( "#>" PGNSP PGUID b f f 3802 1009 3802 0 0 jsonb_extract_path_op - - )); +DESCR("get value from jsonb with path elements"); +DATA(insert OID = 3206 ( "#>>" PGNSP PGUID b f f 3802 1009 25 0 0 jsonb_extract_path_text_op - - )); +DESCR("get value from jsonb as text with path elements"); +DATA(insert OID = 3240 ( "=" PGNSP PGUID b t t 3802 3802 16 3240 3241 jsonb_eq eqsel eqjoinsel )); +DESCR("equal"); +DATA(insert OID = 3241 ( "<>" PGNSP PGUID b f f 3802 3802 16 3241 3240 jsonb_ne neqsel neqjoinsel )); +DESCR("not equal"); +DATA(insert OID = 3242 ( "<" PGNSP PGUID b f f 3802 3802 16 3243 3245 jsonb_lt scalarltsel scalarltjoinsel )); +DESCR("less than"); +DATA(insert OID = 3243 ( ">" PGNSP PGUID b f f 3802 3802 16 3242 3244 jsonb_gt scalargtsel scalargtjoinsel )); +DESCR("greater than"); +DATA(insert OID = 3244 ( "<=" PGNSP PGUID b f f 3802 3802 16 3245 3243 jsonb_le scalarltsel scalarltjoinsel )); +DESCR("less than or equal to"); +DATA(insert OID = 3245 ( ">=" PGNSP PGUID b f f 3802 3802 16 3244 3242 jsonb_ge scalargtsel scalargtjoinsel )); +DESCR("greater than or equal to"); +/* No commutator? */ +DATA(insert OID = 3246 ( "@>" PGNSP PGUID b f f 3802 3802 16 0 3250 jsonb_contains contsel contjoinsel )); +DESCR("contains"); +DATA(insert OID = 3247 ( "?" PGNSP PGUID b f f 3802 25 16 0 0 jsonb_exists contsel contjoinsel )); +DESCR("exists"); +DATA(insert OID = 3248 ( "?|" PGNSP PGUID b f f 3802 1009 16 0 0 jsonb_exists_any contsel contjoinsel )); +DESCR("exists any"); +DATA(insert OID = 3249 ( "?&" PGNSP PGUID b f f 3802 1009 16 0 0 jsonb_exists_all contsel contjoinsel )); +DESCR("exists all"); +DATA(insert OID = 3250 ( "<@" PGNSP PGUID b f f 3802 3802 16 0 3246 jsonb_contained contsel contjoinsel )); +DESCR("contained"); /* * function prototypes */ -extern void OperatorCreate(const char *operatorName, +extern Oid OperatorCreate(const char *operatorName, Oid operatorNamespace, Oid leftTypeId, Oid rightTypeId, diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 41ebccccbc..26297ced0d 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_opfamily.h @@ -78,6 +78,7 @@ DATA(insert OID = 1971 ( 405 float_ops PGNSP PGUID )); DATA(insert OID = 1974 ( 403 network_ops PGNSP PGUID )); #define NETWORK_BTREE_FAM_OID 1974 DATA(insert OID = 1975 ( 405 network_ops PGNSP PGUID )); +DATA(insert OID = 3550 ( 783 network_ops PGNSP PGUID )); DATA(insert OID = 1976 ( 403 integer_ops PGNSP PGUID )); #define INTEGER_BTREE_FAM_OID 1976 DATA(insert OID = 1977 ( 405 integer_ops PGNSP PGUID )); @@ -96,6 +97,7 @@ DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID )); DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID )); DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID )); DATA(insert OID = 2994 ( 403 record_ops PGNSP PGUID )); +DATA(insert OID = 3194 ( 403 record_image_ops PGNSP PGUID )); DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID )); #define TEXT_BTREE_FAM_OID 1994 DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID )); @@ -132,6 +134,8 @@ DATA(insert OID = 1029 ( 783 point_ops PGNSP PGUID )); DATA(insert OID = 2745 ( 2742 array_ops PGNSP PGUID )); DATA(insert OID = 2968 ( 403 uuid_ops PGNSP PGUID )); DATA(insert OID = 2969 ( 405 uuid_ops PGNSP PGUID )); +DATA(insert OID = 3253 ( 403 pg_lsn_ops PGNSP PGUID )); +DATA(insert OID = 3254 ( 405 pg_lsn_ops PGNSP PGUID )); DATA(insert OID = 3522 ( 403 enum_ops PGNSP PGUID )); DATA(insert OID = 3523 ( 405 enum_ops PGNSP PGUID )); DATA(insert OID = 3626 ( 403 tsvector_ops PGNSP PGUID )); @@ -142,9 +146,15 @@ DATA(insert OID = 3702 ( 783 tsquery_ops PGNSP PGUID )); DATA(insert OID = 3901 ( 403 range_ops PGNSP PGUID )); DATA(insert OID = 3903 ( 405 range_ops PGNSP PGUID )); DATA(insert OID = 3919 ( 783 range_ops PGNSP PGUID )); +DATA(insert OID = 3474 ( 4000 range_ops PGNSP PGUID )); DATA(insert OID = 4015 ( 4000 quad_point_ops PGNSP PGUID )); DATA(insert OID = 4016 ( 4000 kd_point_ops PGNSP PGUID )); DATA(insert OID = 4017 ( 4000 text_ops PGNSP PGUID )); #define TEXT_SPGIST_FAM_OID 4017 +DATA(insert OID = 4033 ( 403 jsonb_ops PGNSP PGUID )); +DATA(insert OID = 4034 ( 405 jsonb_ops PGNSP PGUID )); +DATA(insert OID = 4035 ( 783 jsonb_ops PGNSP PGUID )); +DATA(insert OID = 4036 ( 2742 jsonb_ops PGNSP PGUID )); +DATA(insert OID = 4037 ( 2742 jsonb_path_ops PGNSP PGUID )); #endif /* PG_OPFAMILY_H */ diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h index d8927adcbe..c4eb4e3323 100644 --- a/src/include/catalog/pg_pltemplate.h +++ b/src/include/catalog/pg_pltemplate.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_pltemplate.h diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index d434303e62..2eed6e9d7e 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_proc.h @@ -55,8 +55,8 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81) BKI_SCHEMA_MACRO bool proisstrict; /* strict with respect to NULLs? */ bool proretset; /* returns a set? */ char provolatile; /* see PROVOLATILE_ categories below */ - int2 pronargs; /* number of arguments */ - int2 pronargdefaults; /* number of arguments with defaults */ + int16 pronargs; /* number of arguments */ + int16 pronargdefaults; /* number of arguments with defaults */ Oid prorettype; /* OID of result type */ /* @@ -178,6 +178,10 @@ DATA(insert OID = 44 ( regprocin PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 DESCR("I/O"); DATA(insert OID = 45 ( regprocout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "24" _null_ _null_ _null_ _null_ regprocout _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3494 ( to_regproc PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 24 "2275" _null_ _null_ _null_ _null_ to_regproc _null_ _null_ _null_ )); +DESCR("convert proname to regproc"); +DATA(insert OID = 3479 ( to_regprocedure PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2202 "2275" _null_ _null_ _null_ _null_ to_regprocedure _null_ _null_ _null_ )); +DESCR("convert proname to regprocedure"); DATA(insert OID = 46 ( textin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "2275" _null_ _null_ _null_ _null_ textin _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 47 ( textout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "25" _null_ _null_ _null_ _null_ textout _null_ _null_ _null_ )); @@ -845,6 +849,8 @@ DATA(insert OID = 2092 ( array_upper PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 DESCR("array upper dimension"); DATA(insert OID = 2176 ( array_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "2277 23" _null_ _null_ _null_ _null_ array_length _null_ _null_ _null_ )); DESCR("array length"); +DATA(insert OID = 3179 ( cardinality PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "2277" _null_ _null_ _null_ _null_ array_cardinality _null_ _null_ _null_ )); +DESCR("array cardinality"); DATA(insert OID = 378 ( array_append PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2277 2283" _null_ _null_ _null_ _null_ array_push _null_ _null_ _null_ )); DESCR("append element onto end of array"); DATA(insert OID = 379 ( array_prepend PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2283 2277" _null_ _null_ _null_ _null_ array_push _null_ _null_ _null_ )); @@ -872,9 +878,13 @@ DATA(insert OID = 1286 ( array_fill PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 22 DESCR("array constructor with value"); DATA(insert OID = 2331 ( unnest PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2283 "2277" _null_ _null_ _null_ _null_ array_unnest _null_ _null_ _null_ )); DESCR("expand array to set of rows"); +DATA(insert OID = 3167 ( array_remove PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2277 2283" _null_ _null_ _null_ _null_ array_remove _null_ _null_ _null_ )); +DESCR("remove any occurrences of an element from an array"); +DATA(insert OID = 3168 ( array_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2277 "2277 2283 2283" _null_ _null_ _null_ _null_ array_replace _null_ _null_ _null_ )); +DESCR("replace any occurrences of an element in an array"); DATA(insert OID = 2333 ( array_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ array_agg_transfn _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 2334 ( array_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 2277 "2281" _null_ _null_ _null_ _null_ array_agg_finalfn _null_ _null_ _null_ )); +DATA(insert OID = 2334 ( array_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2281 2283" _null_ _null_ _null_ _null_ array_agg_finalfn _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 2335 ( array_agg PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 2277 "2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); DESCR("concatenate aggregate input into an array"); @@ -1041,14 +1051,29 @@ DATA(insert OID = 955 ( lowrite PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 23 DESCR("large object write"); DATA(insert OID = 956 ( lo_lseek PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 23 "23 23 23" _null_ _null_ _null_ _null_ lo_lseek _null_ _null_ _null_ )); DESCR("large object seek"); +DATA(insert OID = 3170 ( lo_lseek64 PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 20 "23 20 23" _null_ _null_ _null_ _null_ lo_lseek64 _null_ _null_ _null_ )); +DESCR("large object seek (64 bit)"); DATA(insert OID = 957 ( lo_creat PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 26 "23" _null_ _null_ _null_ _null_ lo_creat _null_ _null_ _null_ )); DESCR("large object create"); DATA(insert OID = 715 ( lo_create PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 26 "26" _null_ _null_ _null_ _null_ lo_create _null_ _null_ _null_ )); DESCR("large object create"); DATA(insert OID = 958 ( lo_tell PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 23 "23" _null_ _null_ _null_ _null_ lo_tell _null_ _null_ _null_ )); DESCR("large object position"); +DATA(insert OID = 3171 ( lo_tell64 PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 20 "23" _null_ _null_ _null_ _null_ lo_tell64 _null_ _null_ _null_ )); +DESCR("large object position (64 bit)"); DATA(insert OID = 1004 ( lo_truncate PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 23 "23 23" _null_ _null_ _null_ _null_ lo_truncate _null_ _null_ _null_ )); DESCR("truncate large object"); +DATA(insert OID = 3172 ( lo_truncate64 PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 23 "23 20" _null_ _null_ _null_ _null_ lo_truncate64 _null_ _null_ _null_ )); +DESCR("truncate large object (64 bit)"); + +DATA(insert OID = 3457 ( lo_create PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 26 "26 17" _null_ _null_ _null_ _null_ lo_create_bytea _null_ _null_ _null_ )); +DESCR("create new large object with content"); +DATA(insert OID = 3458 ( lo_get PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 17 "26" _null_ _null_ _null_ _null_ lo_get _null_ _null_ _null_ )); +DESCR("read entire large object"); +DATA(insert OID = 3459 ( lo_get PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 17 "26 20 23" _null_ _null_ _null_ _null_ lo_get_fragment _null_ _null_ _null_ )); +DESCR("read large object from offset for length"); +DATA(insert OID = 3460 ( lo_put PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 2278 "26 20 17" _null_ _null_ _null_ _null_ lo_put _null_ _null_ _null_ )); +DESCR("write data at offset"); DATA(insert OID = 959 ( on_pl PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "600 628" _null_ _null_ _null_ _null_ on_pl _null_ _null_ _null_ )); DATA(insert OID = 960 ( on_sl PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "601 628" _null_ _null_ _null_ _null_ on_sl _null_ _null_ _null_ )); @@ -1293,8 +1318,12 @@ DESCR("truncate interval to specified units"); DATA(insert OID = 1219 ( int8inc PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 20 "20" _null_ _null_ _null_ _null_ int8inc _null_ _null_ _null_ )); DESCR("increment"); +DATA(insert OID = 3546 ( int8dec PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 20 "20" _null_ _null_ _null_ _null_ int8dec _null_ _null_ _null_ )); +DESCR("decrement"); DATA(insert OID = 2804 ( int8inc_any PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 20 "20 2276" _null_ _null_ _null_ _null_ int8inc_any _null_ _null_ _null_ )); DESCR("increment, ignores second argument"); +DATA(insert OID = 3547 ( int8dec_any PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 20 "20 2276" _null_ _null_ _null_ _null_ int8dec_any _null_ _null_ _null_ )); +DESCR("decrement, ignores second argument"); DATA(insert OID = 1230 ( int8abs PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 20 "20" _null_ _null_ _null_ _null_ int8abs _null_ _null_ _null_ )); DATA(insert OID = 1236 ( int8larger PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 20 "20 20" _null_ _null_ _null_ _null_ int8larger _null_ _null_ _null_ )); @@ -1446,7 +1475,7 @@ DESCR("natural exponential (e^x)"); /* * This form of obj_description is now deprecated, since it will fail if - * OIDs are not unique across system catalogs. Use the other form instead. + * OIDs are not unique across system catalogs. Use the other form instead. */ DATA(insert OID = 1348 ( obj_description PGNSP PGUID 14 100 0 0 0 f f f f t f s 1 0 25 "26" _null_ _null_ _null_ _null_ "select description from pg_catalog.pg_description where objoid = $1 and objsubid = 0" _null_ _null_ _null_ )); DESCR("deprecated, use two-argument form instead"); @@ -1751,7 +1780,7 @@ DATA(insert OID = 1576 ( setval PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 20 " DESCR("set sequence value"); DATA(insert OID = 1765 ( setval PGNSP PGUID 12 1 0 0 0 f f f f t f v 3 0 20 "2205 20 16" _null_ _null_ _null_ _null_ setval3_oid _null_ _null_ _null_ )); DESCR("set sequence value and is_called status"); -DATA(insert OID = 3078 ( pg_sequence_parameters PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2249 "26" "{23,20,20,20,20,16}" "{i,o,o,o,o,o}" "{sequence_oid,start_value,minimum_value,maximum_value,increment,cycle_option}" _null_ pg_sequence_parameters _null_ _null_ _null_)); +DATA(insert OID = 3078 ( pg_sequence_parameters PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2249 "26" "{26,20,20,20,20,16}" "{i,o,o,o,o,o}" "{sequence_oid,start_value,minimum_value,maximum_value,increment,cycle_option}" _null_ pg_sequence_parameters _null_ _null_ _null_)); DESCR("sequence parameters, for use by information schema"); DATA(insert OID = 1579 ( varbit_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1562 "2275 26 23" _null_ _null_ _null_ _null_ varbit_in _null_ _null_ _null_ )); @@ -1959,6 +1988,8 @@ DATA(insert OID = 2232 ( pg_get_function_identity_arguments PGNSP PGUID 12 1 DESCR("identity argument list of a function"); DATA(insert OID = 2165 ( pg_get_function_result PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 25 "26" _null_ _null_ _null_ _null_ pg_get_function_result _null_ _null_ _null_ )); DESCR("result type of a function"); +DATA(insert OID = 3808 ( pg_get_function_arg_default PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 25 "26 23" _null_ _null_ _null_ _null_ pg_get_function_arg_default _null_ _null_ _null_ )); +DESCR("function argument default"); DATA(insert OID = 1686 ( pg_get_keywords PGNSP PGUID 12 10 400 0 0 f f f f t t s 0 0 2249 "" "{25,18,25}" "{o,o,o}" "{word,catcode,catdesc}" _null_ pg_get_keywords _null_ _null_ _null_ )); DESCR("list of SQL keywords"); @@ -1971,6 +2002,11 @@ DESCR("type of the argument"); DATA(insert OID = 3162 ( pg_collation_for PGNSP PGUID 12 1 0 0 0 f f f f f f s 1 0 25 "2276" _null_ _null_ _null_ _null_ pg_collation_for _null_ _null_ _null_ )); DESCR("collation of the argument; implementation of the COLLATION FOR expression"); +DATA(insert OID = 3842 ( pg_relation_is_updatable PGNSP PGUID 12 10 0 0 0 f f f f t f s 2 0 23 "2205 16" _null_ _null_ _null_ _null_ pg_relation_is_updatable _null_ _null_ _null_ )); +DESCR("is a relation insertable/updatable/deletable"); +DATA(insert OID = 3843 ( pg_column_is_updatable PGNSP PGUID 12 10 0 0 0 f f f f t f s 3 0 16 "2205 21 16" _null_ _null_ _null_ _null_ pg_column_is_updatable _null_ _null_ _null_ )); +DESCR("is a column updatable"); + /* Deferrable unique constraint trigger */ DATA(insert OID = 1250 ( unique_key_recheck PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 2279 "" _null_ _null_ _null_ _null_ unique_key_recheck _null_ _null_ _null_ )); DESCR("deferred UNIQUE constraint check"); @@ -2095,6 +2131,7 @@ DATA(insert OID = 927 ( network_sub PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1 DATA(insert OID = 928 ( network_subeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_subeq _null_ _null_ _null_ )); DATA(insert OID = 929 ( network_sup PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_sup _null_ _null_ _null_ )); DATA(insert OID = 930 ( network_supeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_supeq _null_ _null_ _null_ )); +DATA(insert OID = 3551 ( network_overlap PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_overlap _null_ _null_ _null_ )); /* inet/cidr functions */ DATA(insert OID = 598 ( abbrev PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "869" _null_ _null_ _null_ _null_ inet_abbrev _null_ _null_ _null_ )); @@ -2141,6 +2178,28 @@ DATA(insert OID = 2631 ( int8pl_inet PGNSP PGUID 14 1 0 0 0 f f f f t f i 2 0 DATA(insert OID = 2632 ( inetmi_int8 PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 20" _null_ _null_ _null_ _null_ inetmi_int8 _null_ _null_ _null_ )); DATA(insert OID = 2633 ( inetmi PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 20 "869 869" _null_ _null_ _null_ _null_ inetmi _null_ _null_ _null_ )); +/* GiST support for inet and cidr */ +DATA(insert OID = 3553 ( inet_gist_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 5 0 16 "2281 869 23 26 2281" _null_ _null_ _null_ _null_ inet_gist_consistent _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3554 ( inet_gist_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ inet_gist_union _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3555 ( inet_gist_compress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_compress _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3556 ( inet_gist_decompress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_decompress _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3557 ( inet_gist_penalty PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_ inet_gist_penalty _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3558 ( inet_gist_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ inet_gist_picksplit _null_ _null_ _null_ )); +DESCR("GiST support"); +DATA(insert OID = 3559 ( inet_gist_same PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "869 869 2281" _null_ _null_ _null_ _null_ inet_gist_same _null_ _null_ _null_ )); +DESCR("GiST support"); + +/* Selectivity estimation for inet and cidr */ +DATA(insert OID = 3560 ( networksel PGNSP PGUID 12 1 0 0 0 f f f f t f s 4 0 701 "2281 26 2281 23" _null_ _null_ _null_ _null_ networksel _null_ _null_ _null_ )); +DESCR("restriction selectivity for network operators"); +DATA(insert OID = 3561 ( networkjoinsel PGNSP PGUID 12 1 0 0 0 f f f f t f s 5 0 701 "2281 26 2281 21 2281" _null_ _null_ _null_ _null_ networkjoinsel _null_ _null_ _null_ )); +DESCR("join selectivity for network operators"); + DATA(insert OID = 1690 ( time_mi_time PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1186 "1083 1083" _null_ _null_ _null_ _null_ time_mi_time _null_ _null_ _null_ )); DATA(insert OID = 1691 ( boolle PGNSP PGUID 12 1 0 0 0 f f f t t f i 2 0 16 "16 16" _null_ _null_ _null_ _null_ boolle _null_ _null_ _null_ )); @@ -2371,27 +2430,37 @@ DATA(insert OID = 2513 ( float8_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i DESCR("aggregate final function"); DATA(insert OID = 1832 ( float8_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "1022" _null_ _null_ _null_ _null_ float8_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); -DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ )); +DATA(insert OID = 1833 ( numeric_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_accum _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 2858 ( numeric_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3548 ( numeric_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 1700" _null_ _null_ _null_ _null_ numeric_accum_inv _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 2858 ( numeric_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1700" _null_ _null_ _null_ _null_ numeric_avg_accum _null_ _null_ _null_ )); +DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 1834 ( int2_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 21" _null_ _null_ _null_ _null_ int2_accum _null_ _null_ _null_ )); +DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 1835 ( int4_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 23" _null_ _null_ _null_ _null_ int4_accum _null_ _null_ _null_ )); +DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 1836 ( int8_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_accum _null_ _null_ _null_ )); +DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 2746 ( int8_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 20" _null_ _null_ _null_ _null_ int8_avg_accum _null_ _null_ _null_ )); +DATA(insert OID = 3567 ( int2_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 21" _null_ _null_ _null_ _null_ int2_accum_inv _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ )); +DATA(insert OID = 3568 ( int4_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 23" _null_ _null_ _null_ _null_ int4_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3569 ( int8_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 20" _null_ _null_ _null_ _null_ int8_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3178 ( numeric_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_sum _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 1837 ( numeric_avg PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_avg _null_ _null_ _null_ )); DESCR("aggregate final function"); -DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ )); +DATA(insert OID = 2514 ( numeric_var_pop PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_pop _null_ _null_ _null_ )); DESCR("aggregate final function"); -DATA(insert OID = 1838 ( numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ )); +DATA(insert OID = 1838 ( numeric_var_samp PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_var_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); -DATA(insert OID = 2596 ( numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_stddev_pop _null_ _null_ _null_ )); +DATA(insert OID = 2596 ( numeric_stddev_pop PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_stddev_pop _null_ _null_ _null_ )); DESCR("aggregate final function"); -DATA(insert OID = 1839 ( numeric_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1231" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ )); +DATA(insert OID = 1839 ( numeric_stddev_samp PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 1700 "2281" _null_ _null_ _null_ _null_ numeric_stddev_samp _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 1840 ( int2_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 21" _null_ _null_ _null_ _null_ int2_sum _null_ _null_ _null_ )); DESCR("aggregate transition function"); @@ -2401,14 +2470,22 @@ DATA(insert OID = 1842 ( int8_sum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 DESCR("aggregate transition function"); DATA(insert OID = 1843 ( interval_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1186" _null_ _null_ _null_ _null_ interval_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); +DATA(insert OID = 3549 ( interval_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1186" _null_ _null_ _null_ _null_ interval_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); DATA(insert OID = 1844 ( interval_avg PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1186 "1187" _null_ _null_ _null_ _null_ interval_avg _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 1962 ( int2_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 21" _null_ _null_ _null_ _null_ int2_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); DATA(insert OID = 1963 ( int4_avg_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 23" _null_ _null_ _null_ _null_ int4_avg_accum _null_ _null_ _null_ )); DESCR("aggregate transition function"); +DATA(insert OID = 3570 ( int2_avg_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 21" _null_ _null_ _null_ _null_ int2_avg_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3571 ( int4_avg_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 23" _null_ _null_ _null_ _null_ int4_avg_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); DATA(insert OID = 1964 ( int8_avg PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 1700 "1016" _null_ _null_ _null_ _null_ int8_avg _null_ _null_ _null_ )); DESCR("aggregate final function"); +DATA(insert OID = 3572 ( int2int4_sum PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 20 "1016" _null_ _null_ _null_ _null_ int2int4_sum _null_ _null_ _null_ )); +DESCR("aggregate final function"); DATA(insert OID = 2805 ( int8inc_float8_float8 PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 20 "20 701 701" _null_ _null_ _null_ _null_ int8inc_float8_float8 _null_ _null_ _null_ )); DESCR("aggregate transition function"); DATA(insert OID = 2806 ( float8_regr_accum PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1022 "1022 701 701" _null_ _null_ _null_ _null_ float8_regr_accum _null_ _null_ _null_ )); @@ -2439,19 +2516,19 @@ DESCR("aggregate final function"); DATA(insert OID = 3535 ( string_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2281 "2281 25 25" _null_ _null_ _null_ _null_ string_agg_transfn _null_ _null_ _null_ )); DESCR("aggregate transition function"); #ifdef PGXC -DATA(insert OID = 2966 ( float8_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1022 "1022 1022" _null_ _null_ _null_ _null_ float8_collect _null_ _null_ _null_ )); +DATA(insert OID = 6000 ( float8_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1022 "1022 1022" _null_ _null_ _null_ _null_ float8_collect _null_ _null_ _null_ )); DESCR("aggregate collection function"); -DATA(insert OID = 2964 ( numeric_avg_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1231" _null_ _null_ _null_ _null_ numeric_avg_collect _null_ _null_ _null_ )); +DATA(insert OID = 6001 ( numeric_avg_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1231" _null_ _null_ _null_ _null_ numeric_avg_collect _null_ _null_ _null_ )); DESCR("aggregate collection function"); -DATA(insert OID = 2968 ( numeric_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1231" _null_ _null_ _null_ _null_ numeric_collect _null_ _null_ _null_ )); +DATA(insert OID = 6002 ( numeric_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1231 "1231 1231" _null_ _null_ _null_ _null_ numeric_collect _null_ _null_ _null_ )); DESCR("aggregate collection function"); -DATA(insert OID = 2967 ( interval_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1187" _null_ _null_ _null_ _null_ interval_collect _null_ _null_ _null_ )); +DATA(insert OID = 6003 ( interval_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1187 "1187 1187" _null_ _null_ _null_ _null_ interval_collect _null_ _null_ _null_ )); DESCR("aggregate transition function"); -DATA(insert OID = 2965 ( int8_avg_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 1016" _null_ _null_ _null_ _null_ int8_avg_collect _null_ _null_ _null_ )); +DATA(insert OID = 6004 ( int8_avg_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1016 "1016 1016" _null_ _null_ _null_ _null_ int8_avg_collect _null_ _null_ _null_ )); DESCR("AVG(int) collection function"); -DATA(insert OID = 2996 ( int8_sum_to_int8 PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 20" _null_ _null_ _null_ _null_ int8_sum_to_int8 _null_ _null_ _null_ )); +DATA(insert OID = 6005 ( int8_sum_to_int8 PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 20 "20 20" _null_ _null_ _null_ _null_ int8_sum_to_int8 _null_ _null_ _null_ )); DESCR("SUM(int) collection function"); -DATA(insert OID = 2995 ( float8_regr_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1022 "1022 1022" _null_ _null_ _null_ _null_ float8_regr_collect _null_ _null_ _null_ )); +DATA(insert OID = 6006 ( float8_regr_collect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1022 "1022 1022" _null_ _null_ _null_ _null_ float8_regr_collect _null_ _null_ _null_ )); DESCR("REGR_...(double, double) collection function"); #endif DATA(insert OID = 3536 ( string_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 25 "2281" _null_ _null_ _null_ _null_ string_agg_finalfn _null_ _null_ _null_ )); @@ -2599,6 +2676,8 @@ DATA(insert OID = 2878 ( pg_stat_get_live_tuples PGNSP PGUID 12 1 0 0 0 f f f f DESCR("statistics: number of live tuples"); DATA(insert OID = 2879 ( pg_stat_get_dead_tuples PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_dead_tuples _null_ _null_ _null_ )); DESCR("statistics: number of dead tuples"); +DATA(insert OID = 3177 ( pg_stat_get_mod_since_analyze PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_mod_since_analyze _null_ _null_ _null_ )); +DESCR("statistics: number of tuples changed since last analyze"); DATA(insert OID = 1934 ( pg_stat_get_blocks_fetched PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_blocks_fetched _null_ _null_ _null_ )); DESCR("statistics: number of blocks fetched"); DATA(insert OID = 1935 ( pg_stat_get_blocks_hit PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 20 "26" _null_ _null_ _null_ _null_ pg_stat_get_blocks_hit _null_ _null_ _null_ )); @@ -2621,9 +2700,9 @@ DATA(insert OID = 3057 ( pg_stat_get_autoanalyze_count PGNSP PGUID 12 1 0 0 0 f DESCR("statistics: number of auto analyzes for a table"); DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 0 f f f f t t s 0 0 23 "" _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ )); DESCR("statistics: currently active backend IDs"); -DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port}" _null_ pg_stat_get_activity _null_ _null_ _null_ )); +DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23,28,28}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin}" _null_ pg_stat_get_activity _null_ _null_ _null_ )); DESCR("statistics: information about currently active backends"); -DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{23,25,25,25,25,25,23,25}" "{o,o,o,o,o,o,o,o}" "{pid,state,sent_location,write_location,flush_location,replay_location,sync_priority,sync_state}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ )); +DATA(insert OID = 3099 ( pg_stat_get_wal_senders PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{23,25,3220,3220,3220,3220,23,25}" "{o,o,o,o,o,o,o,o}" "{pid,state,sent_location,write_location,flush_location,replay_location,sync_priority,sync_state}" _null_ pg_stat_get_wal_senders _null_ _null_ _null_ )); DESCR("statistics: information about currently active replication"); DATA(insert OID = 2026 ( pg_backend_pid PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 23 "" _null_ _null_ _null_ _null_ pg_backend_pid _null_ _null_ _null_ )); DESCR("statistics: current backend PID"); @@ -2691,6 +2770,8 @@ DATA(insert OID = 2844 ( pg_stat_get_db_blk_read_time PGNSP PGUID 12 1 0 0 0 f DESCR("statistics: block read time, in msec"); DATA(insert OID = 2845 ( pg_stat_get_db_blk_write_time PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 701 "26" _null_ _null_ _null_ _null_ pg_stat_get_db_blk_write_time _null_ _null_ _null_ )); DESCR("statistics: block write time, in msec"); +DATA(insert OID = 3195 ( pg_stat_get_archiver PGNSP PGUID 12 1 0 0 0 f f f f f f s 0 0 2249 "" "{20,25,1184,20,25,1184,1184}" "{o,o,o,o,o,o,o}" "{archived_count,last_archived_wal,last_archived_time,failed_count,last_failed_wal,last_failed_time,stats_reset}" _null_ pg_stat_get_archiver _null_ _null_ _null_ )); +DESCR("statistics: information about WAL archiver"); DATA(insert OID = 2769 ( pg_stat_get_bgwriter_timed_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_timed_checkpoints _null_ _null_ _null_ )); DESCR("statistics: number of timed checkpoints started by the bgwriter"); DATA(insert OID = 2770 ( pg_stat_get_bgwriter_requested_checkpoints PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 20 "" _null_ _null_ _null_ _null_ pg_stat_get_bgwriter_requested_checkpoints _null_ _null_ _null_ )); @@ -2915,33 +2996,38 @@ DATA(insert OID = 1371 ( pg_lock_status PGNSP PGUID 12 1 1000 0 0 f f f f t t DESCR("view system lock information"); DATA(insert OID = 1065 ( pg_prepared_xact PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{28,25,1184,26,26}" "{o,o,o,o,o}" "{transaction,gid,prepared,ownerid,dbid}" _null_ pg_prepared_xact _null_ _null_ _null_ )); DESCR("view two-phase transactions"); +DATA(insert OID = 3819 ( pg_get_multixact_members PGNSP PGUID 12 1 1000 0 0 f f f f t t v 1 0 2249 "28" "{28,28,25}" "{i,o,o}" "{multixid,xid,mode}" _null_ pg_get_multixact_members _null_ _null_ _null_ )); +DESCR("view members of a multixactid"); DATA(insert OID = 3537 ( pg_describe_object PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 25 "26 26 23" _null_ _null_ _null_ _null_ pg_describe_object _null_ _null_ _null_ )); DESCR("get identification of SQL object"); -DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3839 ( pg_identify_object PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 2249 "26 26 23" "{26,26,23,25,25,25,25}" "{i,i,i,o,o,o,o}" "{classid,objid,subobjid,type,schema,name,identity}" _null_ pg_identify_object _null_ _null_ _null_ )); +DESCR("get machine-parseable identification of SQL object"); + +DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_table_is_visible _null_ _null_ _null_ )); DESCR("is table visible in search path?"); -DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_type_is_visible _null_ _null_ _null_ )); DESCR("is type visible in search path?"); -DATA(insert OID = 2081 ( pg_function_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_function_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 2081 ( pg_function_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_function_is_visible _null_ _null_ _null_ )); DESCR("is function visible in search path?"); -DATA(insert OID = 2082 ( pg_operator_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_operator_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 2082 ( pg_operator_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_operator_is_visible _null_ _null_ _null_ )); DESCR("is operator visible in search path?"); -DATA(insert OID = 2083 ( pg_opclass_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_opclass_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 2083 ( pg_opclass_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_opclass_is_visible _null_ _null_ _null_ )); DESCR("is opclass visible in search path?"); -DATA(insert OID = 3829 ( pg_opfamily_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_opfamily_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3829 ( pg_opfamily_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_opfamily_is_visible _null_ _null_ _null_ )); DESCR("is opfamily visible in search path?"); -DATA(insert OID = 2093 ( pg_conversion_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_conversion_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 2093 ( pg_conversion_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_conversion_is_visible _null_ _null_ _null_ )); DESCR("is conversion visible in search path?"); -DATA(insert OID = 3756 ( pg_ts_parser_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_parser_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3756 ( pg_ts_parser_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_parser_is_visible _null_ _null_ _null_ )); DESCR("is text search parser visible in search path?"); -DATA(insert OID = 3757 ( pg_ts_dict_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_dict_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3757 ( pg_ts_dict_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_dict_is_visible _null_ _null_ _null_ )); DESCR("is text search dictionary visible in search path?"); -DATA(insert OID = 3768 ( pg_ts_template_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_template_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3768 ( pg_ts_template_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_template_is_visible _null_ _null_ _null_ )); DESCR("is text search template visible in search path?"); -DATA(insert OID = 3758 ( pg_ts_config_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_config_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3758 ( pg_ts_config_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_ts_config_is_visible _null_ _null_ _null_ )); DESCR("is text search configuration visible in search path?"); -DATA(insert OID = 3815 ( pg_collation_is_visible PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_collation_is_visible _null_ _null_ _null_ )); +DATA(insert OID = 3815 ( pg_collation_is_visible PGNSP PGUID 12 10 0 0 0 f f f f t f s 1 0 16 "26" _null_ _null_ _null_ _null_ pg_collation_is_visible _null_ _null_ _null_ )); DESCR("is collation visible in search path?"); DATA(insert OID = 2854 ( pg_my_temp_schema PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 26 "" _null_ _null_ _null_ _null_ pg_my_temp_schema _null_ _null_ _null_ )); @@ -2953,24 +3039,28 @@ DATA(insert OID = 2171 ( pg_cancel_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v DESCR("cancel a server process' current query"); DATA(insert OID = 2096 ( pg_terminate_backend PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 16 "23" _null_ _null_ _null_ _null_ pg_terminate_backend _null_ _null_ _null_ )); DESCR("terminate a server process"); -DATA(insert OID = 2172 ( pg_start_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 25 "25 16" _null_ _null_ _null_ _null_ pg_start_backup _null_ _null_ _null_ )); +DATA(insert OID = 2172 ( pg_start_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 3220 "25 16" _null_ _null_ _null_ _null_ pg_start_backup _null_ _null_ _null_ )); DESCR("prepare for taking an online backup"); -DATA(insert OID = 2173 ( pg_stop_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_stop_backup _null_ _null_ _null_ )); +DATA(insert OID = 2173 ( pg_stop_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_stop_backup _null_ _null_ _null_ )); DESCR("finish taking an online backup"); -DATA(insert OID = 2848 ( pg_switch_xlog PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_switch_xlog _null_ _null_ _null_ )); +DATA(insert OID = 3813 ( pg_is_in_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pg_is_in_backup _null_ _null_ _null_ )); +DESCR("true if server is in online backup"); +DATA(insert OID = 3814 ( pg_backup_start_time PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 1184 "" _null_ _null_ _null_ _null_ pg_backup_start_time _null_ _null_ _null_ )); +DESCR("start time of an online backup"); +DATA(insert OID = 2848 ( pg_switch_xlog PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_switch_xlog _null_ _null_ _null_ )); DESCR("switch to new xlog file"); -DATA(insert OID = 3098 ( pg_create_restore_point PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 25 "25" _null_ _null_ _null_ _null_ pg_create_restore_point _null_ _null_ _null_ )); +DATA(insert OID = 3098 ( pg_create_restore_point PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 3220 "25" _null_ _null_ _null_ _null_ pg_create_restore_point _null_ _null_ _null_ )); DESCR("create a named restore point"); -DATA(insert OID = 2849 ( pg_current_xlog_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_current_xlog_location _null_ _null_ _null_ )); +DATA(insert OID = 2849 ( pg_current_xlog_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_current_xlog_location _null_ _null_ _null_ )); DESCR("current xlog write location"); -DATA(insert OID = 2852 ( pg_current_xlog_insert_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_current_xlog_insert_location _null_ _null_ _null_ )); +DATA(insert OID = 2852 ( pg_current_xlog_insert_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_current_xlog_insert_location _null_ _null_ _null_ )); DESCR("current xlog insert location"); -DATA(insert OID = 2850 ( pg_xlogfile_name_offset PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2249 "25" "{25,25,23}" "{i,o,o}" "{wal_location,file_name,file_offset}" _null_ pg_xlogfile_name_offset _null_ _null_ _null_ )); +DATA(insert OID = 2850 ( pg_xlogfile_name_offset PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2249 "3220" "{3220,25,23}" "{i,o,o}" "{wal_location,file_name,file_offset}" _null_ pg_xlogfile_name_offset _null_ _null_ _null_ )); DESCR("xlog filename and byte offset, given an xlog location"); -DATA(insert OID = 2851 ( pg_xlogfile_name PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "25" _null_ _null_ _null_ _null_ pg_xlogfile_name _null_ _null_ _null_ )); +DATA(insert OID = 2851 ( pg_xlogfile_name PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "3220" _null_ _null_ _null_ _null_ pg_xlogfile_name _null_ _null_ _null_ )); DESCR("xlog filename, given an xlog location"); -DATA(insert OID = 3165 ( pg_xlog_location_diff PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1700 "25 25" _null_ _null_ _null_ _null_ pg_xlog_location_diff _null_ _null_ _null_ )); +DATA(insert OID = 3165 ( pg_xlog_location_diff PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1700 "3220 3220" _null_ _null_ _null_ _null_ pg_xlog_location_diff _null_ _null_ _null_ )); DESCR("difference in bytes, given two xlog locations"); DATA(insert OID = 3809 ( pg_export_snapshot PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_export_snapshot _null_ _null_ _null_ )); @@ -2979,9 +3069,9 @@ DESCR("export a snapshot"); DATA(insert OID = 3810 ( pg_is_in_recovery PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pg_is_in_recovery _null_ _null_ _null_ )); DESCR("true if server is in recovery"); -DATA(insert OID = 3820 ( pg_last_xlog_receive_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_last_xlog_receive_location _null_ _null_ _null_ )); +DATA(insert OID = 3820 ( pg_last_xlog_receive_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_last_xlog_receive_location _null_ _null_ _null_ )); DESCR("current xlog flush location"); -DATA(insert OID = 3821 ( pg_last_xlog_replay_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_last_xlog_replay_location _null_ _null_ _null_ )); +DATA(insert OID = 3821 ( pg_last_xlog_replay_location PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 3220 "" _null_ _null_ _null_ _null_ pg_last_xlog_replay_location _null_ _null_ _null_ )); DESCR("last xlog replay location"); DATA(insert OID = 3830 ( pg_last_xact_replay_timestamp PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 1184 "" _null_ _null_ _null_ _null_ pg_last_xact_replay_timestamp _null_ _null_ _null_ )); DESCR("timestamp of last replay xact"); @@ -3012,6 +3102,10 @@ DATA(insert OID = 2625 ( pg_ls_dir PGNSP PGUID 12 1 1000 0 0 f f f f t t v 1 0 DESCR("list all files in a directory"); DATA(insert OID = 2626 ( pg_sleep PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "701" _null_ _null_ _null_ _null_ pg_sleep _null_ _null_ _null_ )); DESCR("sleep for the specified time in seconds"); +DATA(insert OID = 3935 ( pg_sleep_for PGNSP PGUID 14 1 0 0 0 f f f f t f v 1 0 2278 "1186" _null_ _null_ _null_ _null_ "select pg_catalog.pg_sleep(extract(epoch from pg_catalog.clock_timestamp() operator(pg_catalog.+) $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))" _null_ _null_ _null_ )); +DESCR("sleep for the specified interval"); +DATA(insert OID = 3936 ( pg_sleep_until PGNSP PGUID 14 1 0 0 0 f f f f t f v 1 0 2278 "1184" _null_ _null_ _null_ _null_ "select pg_catalog.pg_sleep(extract(epoch from $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))" _null_ _null_ _null_ )); +DESCR("sleep until the specified time"); DATA(insert OID = 2971 ( text PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "16" _null_ _null_ _null_ _null_ booltext _null_ _null_ _null_ )); DESCR("convert boolean to text"); @@ -3278,6 +3372,10 @@ DATA(insert OID = 2214 ( regoperin PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2 DESCR("I/O"); DATA(insert OID = 2215 ( regoperout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2203" _null_ _null_ _null_ _null_ regoperout _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3492 ( to_regoper PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2203 "2275" _null_ _null_ _null_ _null_ to_regoper _null_ _null_ _null_ )); +DESCR("convert operator name to regoper"); +DATA(insert OID = 3476 ( to_regoperator PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2204 "2275" _null_ _null_ _null_ _null_ to_regoperator _null_ _null_ _null_ )); +DESCR("convert operator name to regoperator"); DATA(insert OID = 2216 ( regoperatorin PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2204 "2275" _null_ _null_ _null_ _null_ regoperatorin _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 2217 ( regoperatorout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2204" _null_ _null_ _null_ _null_ regoperatorout _null_ _null_ _null_ )); @@ -3286,10 +3384,14 @@ DATA(insert OID = 2218 ( regclassin PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2 DESCR("I/O"); DATA(insert OID = 2219 ( regclassout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2205" _null_ _null_ _null_ _null_ regclassout _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3495 ( to_regclass PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "2275" _null_ _null_ _null_ _null_ to_regclass _null_ _null_ _null_ )); +DESCR("convert classname to regclass"); DATA(insert OID = 2220 ( regtypein PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2206 "2275" _null_ _null_ _null_ _null_ regtypein _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 2221 ( regtypeout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2206" _null_ _null_ _null_ _null_ regtypeout _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3493 ( to_regtype PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2206 "2275" _null_ _null_ _null_ _null_ to_regtype _null_ _null_ _null_ )); +DESCR("convert type name to regtype"); DATA(insert OID = 1079 ( regclass PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "25" _null_ _null_ _null_ _null_ text_regclass _null_ _null_ _null_ )); DESCR("convert text to regclass"); @@ -3443,6 +3545,8 @@ DATA(insert OID = 2998 ( pg_indexes_size PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 DESCR("disk space usage for all indexes attached to the specified table"); DATA(insert OID = 2999 ( pg_relation_filenode PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 26 "2205" _null_ _null_ _null_ _null_ pg_relation_filenode _null_ _null_ _null_ )); DESCR("filenode identifier of relation"); +DATA(insert OID = 3454 ( pg_filenode_relation PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 2205 "26 26" _null_ _null_ _null_ _null_ pg_filenode_relation _null_ _null_ _null_ )); +DESCR("relation OID for filenode and tablespace"); DATA(insert OID = 3034 ( pg_relation_filepath PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 25 "2205" _null_ _null_ _null_ _null_ pg_relation_filepath _null_ _null_ _null_ )); DESCR("file path of relation"); @@ -3473,6 +3577,10 @@ DATA(insert OID = 2300 ( trigger_in PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 2 DESCR("I/O"); DATA(insert OID = 2301 ( trigger_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "2279" _null_ _null_ _null_ _null_ trigger_out _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3594 ( event_trigger_in PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 3838 "2275" _null_ _null_ _null_ _null_ event_trigger_in _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3595 ( event_trigger_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "3838" _null_ _null_ _null_ _null_ event_trigger_out _null_ _null_ _null_ )); +DESCR("I/O"); DATA(insert OID = 2302 ( language_handler_in PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 2280 "2275" _null_ _null_ _null_ _null_ language_handler_in _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 2303 ( language_handler_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "2280" _null_ _null_ _null_ _null_ language_handler_out _null_ _null_ _null_ )); @@ -3832,6 +3940,14 @@ DATA(insert OID = 2515 ( booland_statefunc PGNSP PGUID 12 1 0 0 0 f f f f t DESCR("aggregate transition function"); DATA(insert OID = 2516 ( boolor_statefunc PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "16 16" _null_ _null_ _null_ _null_ boolor_statefunc _null_ _null_ _null_ )); DESCR("aggregate transition function"); +DATA(insert OID = 3496 ( bool_accum PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 16" _null_ _null_ _null_ _null_ bool_accum _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3497 ( bool_accum_inv PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 16" _null_ _null_ _null_ _null_ bool_accum_inv _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3498 ( bool_alltrue PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ bool_alltrue _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3499 ( bool_anytrue PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ bool_anytrue _null_ _null_ _null_ )); +DESCR("aggregate final function"); DATA(insert OID = 2517 ( bool_and PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); DESCR("boolean-and aggregate"); /* ANY, SOME? These names conflict with subquery operators. See doc. */ @@ -3959,6 +4075,8 @@ DATA(insert OID = 2774 ( ginqueryarrayextract PGNSP PGUID 12 1 0 0 0 f f f f t DESCR("GIN array support"); DATA(insert OID = 2744 ( ginarrayconsistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 8 0 16 "2281 21 2277 23 2281 2281 2281 2281" _null_ _null_ _null_ _null_ ginarrayconsistent _null_ _null_ _null_ )); DESCR("GIN array support"); +DATA(insert OID = 3920 ( ginarraytriconsistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 16 "2281 21 2277 23 2281 2281 2281" _null_ _null_ _null_ _null_ ginarraytriconsistent _null_ _null_ _null_ )); +DESCR("GIN array support"); DATA(insert OID = 3076 ( ginarrayextract PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2277 2281" _null_ _null_ _null_ _null_ ginarrayextract_2args _null_ _null_ _null_ )); DESCR("GIN array support (obsolete)"); @@ -4084,13 +4202,13 @@ DATA(insert OID = 3053 ( xml_is_well_formed_content PGNSP PGUID 12 1 0 0 0 f f DESCR("determine if a string is well formed XML content"); /* json */ -DATA(insert OID = 321 ( json_in PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2275" _null_ _null_ _null_ _null_ json_in _null_ _null_ _null_ )); +DATA(insert OID = 321 ( json_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 114 "2275" _null_ _null_ _null_ _null_ json_in _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 322 ( json_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "114" _null_ _null_ _null_ _null_ json_out _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 323 ( json_recv PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2281" _null_ _null_ _null_ _null_ json_recv _null_ _null_ _null_ )); +DATA(insert OID = 323 ( json_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 114 "2281" _null_ _null_ _null_ _null_ json_recv _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 324 ( json_send PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "114" _null_ _null_ _null_ _null_ json_send _null_ _null_ _null_ )); +DATA(insert OID = 324 ( json_send PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "114" _null_ _null_ _null_ _null_ json_send _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 3153 ( array_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2277" _null_ _null_ _null_ _null_ array_to_json _null_ _null_ _null_ )); DESCR("map array to json"); @@ -4100,6 +4218,65 @@ DATA(insert OID = 3155 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 DESCR("map row to json"); DATA(insert OID = 3156 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "2249 16" _null_ _null_ _null_ _null_ row_to_json_pretty _null_ _null_ _null_ )); DESCR("map row to json with optional pretty printing"); +DATA(insert OID = 3173 ( json_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ json_agg_transfn _null_ _null_ _null_ )); +DESCR("json aggregate transition function"); +DATA(insert OID = 3174 ( json_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 114 "2281" _null_ _null_ _null_ _null_ json_agg_finalfn _null_ _null_ _null_ )); +DESCR("json aggregate final function"); +DATA(insert OID = 3175 ( json_agg PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 114 "2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("aggregate input into json"); +DATA(insert OID = 3180 ( json_object_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2281 "2281 2276 2276" _null_ _null_ _null_ _null_ json_object_agg_transfn _null_ _null_ _null_ )); +DESCR("json object aggregate transition function"); +DATA(insert OID = 3196 ( json_object_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 114 "2281" _null_ _null_ _null_ _null_ json_object_agg_finalfn _null_ _null_ _null_ )); +DESCR("json object aggregate final function"); +DATA(insert OID = 3197 ( json_object_agg PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 114 "2276 2276" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("aggregate input into a json object"); +DATA(insert OID = 3198 ( json_build_array PGNSP PGUID 12 1 0 2276 0 f f f f f f i 1 0 114 "2276" "{2276}" "{v}" _null_ _null_ json_build_array _null_ _null_ _null_ )); +DESCR("build a json array from any inputs"); +DATA(insert OID = 3199 ( json_build_array PGNSP PGUID 12 1 0 0 0 f f f f f f i 0 0 114 "" _null_ _null_ _null_ _null_ json_build_array_noargs _null_ _null_ _null_ )); +DESCR("build an empty json array"); +DATA(insert OID = 3200 ( json_build_object PGNSP PGUID 12 1 0 2276 0 f f f f f f i 1 0 114 "2276" "{2276}" "{v}" _null_ _null_ json_build_object _null_ _null_ _null_ )); +DESCR("build a json object from pairwise key/value inputs"); +DATA(insert OID = 3201 ( json_build_object PGNSP PGUID 12 1 0 0 0 f f f f f f i 0 0 114 "" _null_ _null_ _null_ _null_ json_build_object_noargs _null_ _null_ _null_ )); +DESCR("build an empty json object"); +DATA(insert OID = 3202 ( json_object PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "1009" _null_ _null_ _null_ _null_ json_object _null_ _null_ _null_ )); +DESCR("map text arrayof key value pais to json object"); +DATA(insert OID = 3203 ( json_object PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "1009 1009" _null_ _null_ _null_ _null_ json_object_two_arg _null_ _null_ _null_ )); +DESCR("map text arrayof key value pais to json object"); +DATA(insert OID = 3176 ( to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 114 "2283" _null_ _null_ _null_ _null_ to_json _null_ _null_ _null_ )); +DESCR("map input to json"); + +DATA(insert OID = 3947 ( json_object_field PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 114 "114 25" _null_ _null_ "{from_json, field_name}" _null_ json_object_field _null_ _null_ _null_ )); +DATA(insert OID = 3948 ( json_object_field_text PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "114 25" _null_ _null_ "{from_json, field_name}" _null_ json_object_field_text _null_ _null_ _null_ )); +DATA(insert OID = 3949 ( json_array_element PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 114 "114 23" _null_ _null_ "{from_json, element_index}" _null_ json_array_element _null_ _null_ _null_ )); +DATA(insert OID = 3950 ( json_array_element_text PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "114 23" _null_ _null_ "{from_json, element_index}" _null_ json_array_element_text _null_ _null_ _null_ )); +DATA(insert OID = 3951 ( json_extract_path PGNSP PGUID 12 1 0 25 0 f f f f t f i 2 0 114 "114 1009" "{114,1009}" "{i,v}" "{from_json,path_elems}" _null_ json_extract_path _null_ _null_ _null_ )); +DESCR("get value from json with path elements"); +DATA(insert OID = 3952 ( json_extract_path_op PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 114 "114 1009" _null_ _null_ "{from_json,path_elems}" _null_ json_extract_path _null_ _null_ _null_ )); +DATA(insert OID = 3953 ( json_extract_path_text PGNSP PGUID 12 1 0 25 0 f f f f t f i 2 0 25 "114 1009" "{114,1009}" "{i,v}" "{from_json,path_elems}" _null_ json_extract_path_text _null_ _null_ _null_ )); +DESCR("get value from json as text with path elements"); +DATA(insert OID = 3954 ( json_extract_path_text_op PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "114 1009" _null_ _null_ "{from_json,path_elems}" _null_ json_extract_path_text _null_ _null_ _null_ )); +DATA(insert OID = 3955 ( json_array_elements PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 114 "114" "{114,114}" "{i,o}" "{from_json,value}" _null_ json_array_elements _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3969 ( json_array_elements_text PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 25 "114" "{114,25}" "{i,o}" "{from_json,value}" _null_ json_array_elements_text _null_ _null_ _null_ )); +DESCR("elements of json array"); +DATA(insert OID = 3956 ( json_array_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "114" _null_ _null_ _null_ _null_ json_array_length _null_ _null_ _null_ )); +DESCR("length of json array"); +DATA(insert OID = 3957 ( json_object_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 25 "114" _null_ _null_ _null_ _null_ json_object_keys _null_ _null_ _null_ )); +DESCR("get json object keys"); +DATA(insert OID = 3958 ( json_each PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2249 "114" "{114,25,114}" "{i,o,o}" "{from_json,key,value}" _null_ json_each _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3959 ( json_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2249 "114" "{114,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ json_each_text _null_ _null_ _null_ )); +DESCR("key value pairs of a json object"); +DATA(insert OID = 3960 ( json_populate_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 3 0 2283 "2283 114 16" _null_ _null_ _null_ _null_ json_populate_record _null_ _null_ _null_ )); +DESCR("get record fields from a json object"); +DATA(insert OID = 3961 ( json_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 114 16" _null_ _null_ _null_ _null_ json_populate_recordset _null_ _null_ _null_ )); +DESCR("get set of records with fields from a json array of objects"); +DATA(insert OID = 3204 ( json_to_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2249 "114 16" _null_ _null_ _null_ _null_ json_to_record _null_ _null_ _null_ )); +DESCR("get record fields from a json object"); +DATA(insert OID = 3205 ( json_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 2 0 2249 "114 16" _null_ _null_ _null_ _null_ json_to_recordset _null_ _null_ _null_ )); +DESCR("get set of records with fields from a json array of objects"); +DATA(insert OID = 3968 ( json_typeof PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "114" _null_ _null_ _null_ _null_ json_typeof _null_ _null_ _null_ )); +DESCR("get the type of a json value"); /* uuid */ DATA(insert OID = 2952 ( uuid_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2950 "2275" _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ )); @@ -4121,6 +4298,27 @@ DESCR("I/O"); DATA(insert OID = 2963 ( uuid_hash PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "2950" _null_ _null_ _null_ _null_ uuid_hash _null_ _null_ _null_ )); DESCR("hash"); +/* pg_lsn */ +DATA(insert OID = 3229 ( pg_lsn_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3220 "2275" _null_ _null_ _null_ _null_ pg_lsn_in _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3230 ( pg_lsn_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "3220" _null_ _null_ _null_ _null_ pg_lsn_out _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3231 ( pg_lsn_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_lt _null_ _null_ _null_ )); +DATA(insert OID = 3232 ( pg_lsn_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_le _null_ _null_ _null_ )); +DATA(insert OID = 3233 ( pg_lsn_eq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_eq _null_ _null_ _null_ )); +DATA(insert OID = 3234 ( pg_lsn_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_ge _null_ _null_ _null_ )); +DATA(insert OID = 3235 ( pg_lsn_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_gt _null_ _null_ _null_ )); +DATA(insert OID = 3236 ( pg_lsn_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_ne _null_ _null_ _null_ )); +DATA(insert OID = 3237 ( pg_lsn_mi PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1700 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_mi _null_ _null_ _null_ )); +DATA(insert OID = 3238 ( pg_lsn_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3220 "2281" _null_ _null_ _null_ _null_ pg_lsn_recv _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3239 ( pg_lsn_send PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "3220" _null_ _null_ _null_ _null_ pg_lsn_send _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3251 ( pg_lsn_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_cmp _null_ _null_ _null_ )); +DESCR("less-equal-greater"); +DATA(insert OID = 3252 ( pg_lsn_hash PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "3220" _null_ _null_ _null_ _null_ pg_lsn_hash _null_ _null_ _null_ )); +DESCR("hash"); + /* enum related procs */ DATA(insert OID = 3504 ( anyenum_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3500 "2275" _null_ _null_ _null_ _null_ anyenum_in _null_ _null_ _null_ )); DESCR("I/O"); @@ -4156,7 +4354,7 @@ DATA(insert OID = 3530 ( enum_range PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 22 DESCR("range between the two given enum values, as an ordered array"); DATA(insert OID = 3531 ( enum_range PGNSP PGUID 12 1 0 0 0 f f f f f f s 1 0 2277 "3500" _null_ _null_ _null_ _null_ enum_range_all _null_ _null_ _null_ )); DESCR("range of the given enum type, as an ordered array"); -DATA(insert OID = 3532 ( enum_recv PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 3500 "2275 26" _null_ _null_ _null_ _null_ enum_recv _null_ _null_ _null_ )); +DATA(insert OID = 3532 ( enum_recv PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 3500 "2281 26" _null_ _null_ _null_ _null_ enum_recv _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 3533 ( enum_send PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 17 "3500" _null_ _null_ _null_ _null_ enum_send _null_ _null_ _null_ )); DESCR("I/O"); @@ -4226,6 +4424,8 @@ DATA(insert OID = 3657 ( gin_extract_tsquery PGNSP PGUID 12 1 0 0 0 f f f f t f DESCR("GIN tsvector support"); DATA(insert OID = 3658 ( gin_tsquery_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 8 0 16 "2281 21 3615 23 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gin_tsquery_consistent _null_ _null_ _null_ )); DESCR("GIN tsvector support"); +DATA(insert OID = 3921 ( gin_tsquery_triconsistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 16 "2281 21 3615 23 2281 2281 2281" _null_ _null_ _null_ _null_ gin_tsquery_triconsistent _null_ _null_ _null_ )); +DESCR("GIN tsvector support"); DATA(insert OID = 3724 ( gin_cmp_tslexeme PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ gin_cmp_tslexeme _null_ _null_ _null_ )); DESCR("GIN tsvector support"); DATA(insert OID = 2700 ( gin_cmp_prefix PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 23 "25 25 21 2281" _null_ _null_ _null_ _null_ gin_cmp_prefix _null_ _null_ _null_ )); @@ -4398,6 +4598,87 @@ DESCR("I/O"); DATA(insert OID = 3774 ( regdictionarysend PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "3769" _null_ _null_ _null_ _null_ regdictionarysend _null_ _null_ _null_ )); DESCR("I/O"); +/* jsonb */ +DATA(insert OID = 3806 ( jsonb_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3802 "2275" _null_ _null_ _null_ _null_ jsonb_in _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3805 ( jsonb_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3802 "2281" _null_ _null_ _null_ _null_ jsonb_recv _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3804 ( jsonb_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "3802" _null_ _null_ _null_ _null_ jsonb_out _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3803 ( jsonb_send PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "3802" _null_ _null_ _null_ _null_ jsonb_send _null_ _null_ _null_ )); +DESCR("I/O"); + +DATA(insert OID = 3478 ( jsonb_object_field PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3802 "3802 25" _null_ _null_ "{from_json, field_name}" _null_ jsonb_object_field _null_ _null_ _null_ )); +DATA(insert OID = 3214 ( jsonb_object_field_text PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "3802 25" _null_ _null_ "{from_json, field_name}" _null_ jsonb_object_field_text _null_ _null_ _null_ )); +DATA(insert OID = 3215 ( jsonb_array_element PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3802 "3802 23" _null_ _null_ "{from_json, element_index}" _null_ jsonb_array_element _null_ _null_ _null_ )); +DATA(insert OID = 3216 ( jsonb_array_element_text PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "3802 23" _null_ _null_ "{from_json, element_index}" _null_ jsonb_array_element_text _null_ _null_ _null_ )); +DATA(insert OID = 3217 ( jsonb_extract_path PGNSP PGUID 12 1 0 25 0 f f f f t f i 2 0 3802 "3802 1009" "{3802,1009}" "{i,v}" "{from_json,path_elems}" _null_ jsonb_extract_path _null_ _null_ _null_ )); +DESCR("get value from jsonb with path elements"); +DATA(insert OID = 3939 ( jsonb_extract_path_op PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3802 "3802 1009" _null_ _null_ "{from_json,path_elems}" _null_ jsonb_extract_path _null_ _null_ _null_ )); +DATA(insert OID = 3940 ( jsonb_extract_path_text PGNSP PGUID 12 1 0 25 0 f f f f t f i 2 0 25 "3802 1009" "{3802,1009}" "{i,v}" "{from_json,path_elems}" _null_ jsonb_extract_path_text _null_ _null_ _null_ )); +DESCR("get value from jsonb as text with path elements"); +DATA(insert OID = 3218 ( jsonb_extract_path_text_op PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 25 "3802 1009" _null_ _null_ "{from_json,path_elems}" _null_ jsonb_extract_path_text _null_ _null_ _null_ )); +DATA(insert OID = 3219 ( jsonb_array_elements PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 3802 "3802" "{3802,3802}" "{i,o}" "{from_json,value}" _null_ jsonb_array_elements _null_ _null_ _null_ )); +DESCR("elements of a jsonb array"); +DATA(insert OID = 3465 ( jsonb_array_elements_text PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 25 "3802" "{3802,25}" "{i,o}" "{from_json,value}" _null_ jsonb_array_elements_text _null_ _null_ _null_ )); +DESCR("elements of jsonb array"); +DATA(insert OID = 3207 ( jsonb_array_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "3802" _null_ _null_ _null_ _null_ jsonb_array_length _null_ _null_ _null_ )); +DESCR("length of jsonb array"); +DATA(insert OID = 3931 ( jsonb_object_keys PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 25 "3802" _null_ _null_ _null_ _null_ jsonb_object_keys _null_ _null_ _null_ )); +DESCR("get jsonb object keys"); +DATA(insert OID = 3208 ( jsonb_each PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2249 "3802" "{3802,25,3802}" "{i,o,o}" "{from_json,key,value}" _null_ jsonb_each _null_ _null_ _null_ )); +DESCR("key value pairs of a jsonb object"); +DATA(insert OID = 3932 ( jsonb_each_text PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2249 "3802" "{3802,25,25}" "{i,o,o}" "{from_json,key,value}" _null_ jsonb_each_text _null_ _null_ _null_ )); +DESCR("key value pairs of a jsonb object"); +DATA(insert OID = 3209 ( jsonb_populate_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 3 0 2283 "2283 3802 16" _null_ _null_ _null_ _null_ jsonb_populate_record _null_ _null_ _null_ )); +DESCR("get record fields from a jsonb object"); +DATA(insert OID = 3475 ( jsonb_populate_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 3 0 2283 "2283 3802 16" _null_ _null_ _null_ _null_ jsonb_populate_recordset _null_ _null_ _null_ )); +DESCR("get set of records with fields from a jsonb array of objects"); +DATA(insert OID = 3490 ( jsonb_to_record PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2249 "3802 16" _null_ _null_ _null_ _null_ jsonb_to_record _null_ _null_ _null_ )); +DESCR("get record fields from a json object"); +DATA(insert OID = 3491 ( jsonb_to_recordset PGNSP PGUID 12 1 100 0 0 f f f f f t s 2 0 2249 "3802 16" _null_ _null_ _null_ _null_ jsonb_to_recordset _null_ _null_ _null_ )); +DESCR("get set of records with fields from a json array of objects"); +DATA(insert OID = 3210 ( jsonb_typeof PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "3802" _null_ _null_ _null_ _null_ jsonb_typeof _null_ _null_ _null_ )); +DESCR("get the type of a jsonb value"); +DATA(insert OID = 4038 ( jsonb_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_ne _null_ _null_ _null_ )); +DATA(insert OID = 4039 ( jsonb_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_lt _null_ _null_ _null_ )); +DATA(insert OID = 4040 ( jsonb_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_gt _null_ _null_ _null_ )); +DATA(insert OID = 4041 ( jsonb_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_le _null_ _null_ _null_ )); +DATA(insert OID = 4042 ( jsonb_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_ge _null_ _null_ _null_ )); +DATA(insert OID = 4043 ( jsonb_eq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_eq _null_ _null_ _null_ )); +DATA(insert OID = 4044 ( jsonb_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "3802 3802" _null_ _null_ _null_ _null_ jsonb_cmp _null_ _null_ _null_ )); +DESCR("less-equal-greater"); +DATA(insert OID = 4045 ( jsonb_hash PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "3802" _null_ _null_ _null_ _null_ jsonb_hash _null_ _null_ _null_ )); +DESCR("hash"); +DATA(insert OID = 4046 ( jsonb_contains PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_contains _null_ _null_ _null_ )); +DESCR("implementation of @> operator"); +DATA(insert OID = 4047 ( jsonb_exists PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 25" _null_ _null_ _null_ _null_ jsonb_exists _null_ _null_ _null_ )); +DESCR("implementation of ? operator"); +DATA(insert OID = 4048 ( jsonb_exists_any PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 1009" _null_ _null_ _null_ _null_ jsonb_exists_any _null_ _null_ _null_ )); +DESCR("implementation of ?| operator"); +DATA(insert OID = 4049 ( jsonb_exists_all PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 1009" _null_ _null_ _null_ _null_ jsonb_exists_all _null_ _null_ _null_ )); +DESCR("implementation of ?& operator"); +DATA(insert OID = 4050 ( jsonb_contained PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3802 3802" _null_ _null_ _null_ _null_ jsonb_contained _null_ _null_ _null_ )); +DESCR("implementation of <@ operator"); +DATA(insert OID = 3480 ( gin_compare_jsonb PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "25 25" _null_ _null_ _null_ _null_ gin_compare_jsonb _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3482 ( gin_extract_jsonb PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_ gin_extract_jsonb _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3483 ( gin_extract_jsonb_query PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 2281 "2277 2281 21 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gin_extract_jsonb_query _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3484 ( gin_consistent_jsonb PGNSP PGUID 12 1 0 0 0 f f f f t f i 8 0 16 "2281 21 2277 23 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gin_consistent_jsonb _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3488 ( gin_triconsistent_jsonb PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 16 "2281 21 2277 23 2281 2281 2281" _null_ _null_ _null_ _null_ gin_triconsistent_jsonb _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3485 ( gin_extract_jsonb_path PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_ gin_extract_jsonb_path _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3486 ( gin_extract_jsonb_query_path PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 2281 "2277 2281 21 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gin_extract_jsonb_query_path _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3487 ( gin_consistent_jsonb_path PGNSP PGUID 12 1 0 0 0 f f f f t f i 8 0 16 "2281 21 2277 23 2281 2281 2281 2281" _null_ _null_ _null_ _null_ gin_consistent_jsonb_path _null_ _null_ _null_ )); +DESCR("GIN support"); +DATA(insert OID = 3489 ( gin_triconsistent_jsonb_path PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 16 "2281 21 2277 23 2281 2281 2281" _null_ _null_ _null_ _null_ gin_triconsistent_jsonb_path _null_ _null_ _null_ )); +DESCR("GIN support"); + /* txid */ DATA(insert OID = 2939 ( txid_snapshot_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2970 "2275" _null_ _null_ _null_ _null_ txid_snapshot_in _null_ _null_ _null_ )); DESCR("I/O"); @@ -4420,7 +4701,7 @@ DESCR("get set of in-progress txids in snapshot"); DATA(insert OID = 2948 ( txid_visible_in_snapshot PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "20 2970" _null_ _null_ _null_ _null_ txid_visible_in_snapshot _null_ _null_ _null_ )); DESCR("is txid visible in snapshot?"); -/* record comparison */ +/* record comparison using normal comparison rules */ DATA(insert OID = 2981 ( record_eq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_eq _null_ _null_ _null_ )); DATA(insert OID = 2982 ( record_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_ne _null_ _null_ _null_ )); DATA(insert OID = 2983 ( record_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_lt _null_ _null_ _null_ )); @@ -4430,6 +4711,16 @@ DATA(insert OID = 2986 ( record_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 DATA(insert OID = 2987 ( btrecordcmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "2249 2249" _null_ _null_ _null_ _null_ btrecordcmp _null_ _null_ _null_ )); DESCR("less-equal-greater"); +/* record comparison using raw byte images */ +DATA(insert OID = 3181 ( record_image_eq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_eq _null_ _null_ _null_ )); +DATA(insert OID = 3182 ( record_image_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_ne _null_ _null_ _null_ )); +DATA(insert OID = 3183 ( record_image_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_lt _null_ _null_ _null_ )); +DATA(insert OID = 3184 ( record_image_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_gt _null_ _null_ _null_ )); +DATA(insert OID = 3185 ( record_image_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_le _null_ _null_ _null_ )); +DATA(insert OID = 3186 ( record_image_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2249 2249" _null_ _null_ _null_ _null_ record_image_ge _null_ _null_ _null_ )); +DATA(insert OID = 3187 ( btrecordimagecmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "2249 2249" _null_ _null_ _null_ _null_ btrecordimagecmp _null_ _null_ _null_ )); +DESCR("less-equal-greater based on byte images"); + /* Extensions */ DATA(insert OID = 3082 ( pg_available_extensions PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{19,25,25}" "{o,o,o}" "{name,default_version,comment}" _null_ pg_available_extensions _null_ _null_ _null_ )); DESCR("list available extensions"); @@ -4553,6 +4844,8 @@ DATA(insert OID = 3902 ( hash_range PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 DESCR("hash a range"); DATA(insert OID = 3916 ( range_typanalyze PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 16 "2281" _null_ _null_ _null_ _null_ range_typanalyze _null_ _null_ _null_ )); DESCR("range typanalyze"); +DATA(insert OID = 3169 ( rangesel PGNSP PGUID 12 1 0 0 0 f f f f t f s 4 0 701 "2281 26 2281 23" _null_ _null_ _null_ _null_ rangesel _null_ _null_ _null_ )); +DESCR("restriction selectivity for range operators"); DATA(insert OID = 3914 ( int4range_canonical PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3904 "3904" _null_ _null_ _null_ _null_ int4range_canonical _null_ _null_ _null_ )); DESCR("convert an int4 range to canonical form"); @@ -4598,6 +4891,20 @@ DESCR("int8range constructor"); DATA(insert OID = 3946 ( int8range PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 3926 "20 20 25" _null_ _null_ _null_ _null_ range_constructor3 _null_ _null_ _null_ )); DESCR("int8range constructor"); +/* date, time, timestamp constructors */ +DATA(insert OID = 3846 ( make_date PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1082 "23 23 23" _null_ _null_ "{year,month,day}" _null_ make_date _null_ _null_ _null_ )); +DESCR("construct date"); +DATA(insert OID = 3847 ( make_time PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1083 "23 23 701" _null_ _null_ "{hour,min,sec}" _null_ make_time _null_ _null_ _null_ )); +DESCR("construct time"); +DATA(insert OID = 3461 ( make_timestamp PGNSP PGUID 12 1 0 0 0 f f f f t f i 6 0 1114 "23 23 23 23 23 701" _null_ _null_ "{year,month,mday,hour,min,sec}" _null_ make_timestamp _null_ _null_ _null_ )); +DESCR("construct timestamp"); +DATA(insert OID = 3462 ( make_timestamptz PGNSP PGUID 12 1 0 0 0 f f f f t f s 6 0 1184 "23 23 23 23 23 701" _null_ _null_ "{year,month,mday,hour,min,sec}" _null_ make_timestamptz _null_ _null_ _null_ )); +DESCR("construct timestamp with time zone"); +DATA(insert OID = 3463 ( make_timestamptz PGNSP PGUID 12 1 0 0 0 f f f f t f s 7 0 1184 "23 23 23 23 23 701 25" _null_ _null_ "{year,month,mday,hour,min,sec,timezone}" _null_ make_timestamptz_at_timezone _null_ _null_ _null_ )); +DESCR("construct timestamp with time zone"); +DATA(insert OID = 3464 ( make_interval PGNSP PGUID 12 1 0 0 0 f f f f t f i 7 0 1186 "23 23 23 23 23 23 701" _null_ _null_ "{years,months,weeks,days,hours,mins,secs}" _null_ make_interval _null_ _null_ _null_ )); +DESCR("construct interval"); + /* spgist support functions */ DATA(insert OID = 4001 ( spggettuple PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ spggettuple _null_ _null_ _null_ )); DESCR("spgist(internal)"); @@ -4652,29 +4959,116 @@ DATA(insert OID = 4026 ( spg_kd_inner_consistent PGNSP PGUID 12 1 0 0 0 f f f f DESCR("SP-GiST support for k-d tree over point"); DATA(insert OID = 4027 ( spg_text_config PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_text_config _null_ _null_ _null_ )); -DESCR("SP-GiST support for suffix tree over text"); +DESCR("SP-GiST support for radix tree over text"); DATA(insert OID = 4028 ( spg_text_choose PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_text_choose _null_ _null_ _null_ )); -DESCR("SP-GiST support for suffix tree over text"); +DESCR("SP-GiST support for radix tree over text"); DATA(insert OID = 4029 ( spg_text_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_text_picksplit _null_ _null_ _null_ )); -DESCR("SP-GiST support for suffix tree over text"); +DESCR("SP-GiST support for radix tree over text"); DATA(insert OID = 4030 ( spg_text_inner_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_text_inner_consistent _null_ _null_ _null_ )); -DESCR("SP-GiST support for suffix tree over text"); +DESCR("SP-GiST support for radix tree over text"); DATA(insert OID = 4031 ( spg_text_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ spg_text_leaf_consistent _null_ _null_ _null_ )); -DESCR("SP-GiST support for suffix tree over text"); +DESCR("SP-GiST support for radix tree over text"); + +DATA(insert OID = 3469 ( spg_range_quad_config PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_config _null_ _null_ _null_ )); +DESCR("SP-GiST support for quad tree over range"); +DATA(insert OID = 3470 ( spg_range_quad_choose PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_choose _null_ _null_ _null_ )); +DESCR("SP-GiST support for quad tree over range"); +DATA(insert OID = 3471 ( spg_range_quad_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_picksplit _null_ _null_ _null_ )); +DESCR("SP-GiST support for quad tree over range"); +DATA(insert OID = 3472 ( spg_range_quad_inner_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2278 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_inner_consistent _null_ _null_ _null_ )); +DESCR("SP-GiST support for quad tree over range"); +DATA(insert OID = 3473 ( spg_range_quad_leaf_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "2281 2281" _null_ _null_ _null_ _null_ spg_range_quad_leaf_consistent _null_ _null_ _null_ )); +DESCR("SP-GiST support for quad tree over range"); + +/* replication slots */ +DATA(insert OID = 3779 ( pg_create_physical_replication_slot PGNSP PGUID 12 1 0 0 0 f f f f f f v 1 0 2249 "19" "{19,19,3220}" "{i,o,o}" "{slot_name,slot_name,xlog_position}" _null_ pg_create_physical_replication_slot _null_ _null_ _null_ )); +DESCR("create a physical replication slot"); +DATA(insert OID = 3780 ( pg_drop_replication_slot PGNSP PGUID 12 1 0 0 0 f f f f f f v 1 0 2278 "19" _null_ _null_ _null_ _null_ pg_drop_replication_slot _null_ _null_ _null_ )); +DESCR("drop a replication slot"); +DATA(insert OID = 3781 ( pg_get_replication_slots PGNSP PGUID 12 1 10 0 0 f f f f f t s 0 0 2249 "" "{19,19,25,26,16,28,28,3220}" "{o,o,o,o,o,o,o,o}" "{slot_name,plugin,slot_type,datoid,active,xmin,catalog_xmin,restart_lsn}" _null_ pg_get_replication_slots _null_ _null_ _null_ )); +DESCR("information about replication slots currently in use"); +DATA(insert OID = 3786 ( pg_create_logical_replication_slot PGNSP PGUID 12 1 0 0 0 f f f f f f v 2 0 2249 "19 19" "{19,19,25,3220}" "{i,i,o,o}" "{slot_name,plugin,slot_name,xlog_position}" _null_ pg_create_logical_replication_slot _null_ _null_ _null_ )); +DESCR("set up a logical replication slot"); +DATA(insert OID = 3782 ( pg_logical_slot_get_changes PGNSP PGUID 12 1000 1000 25 0 f f f f f t v 4 0 2249 "19 3220 23 1009" "{19,3220,23,1009,3220,28,25}" "{i,i,i,v,o,o,o}" "{slot_name,upto_lsn,upto_nchanges,options,location,xid,data}" _null_ pg_logical_slot_get_changes _null_ _null_ _null_ )); +DESCR("get changes from replication slot"); +DATA(insert OID = 3783 ( pg_logical_slot_get_binary_changes PGNSP PGUID 12 1000 1000 25 0 f f f f f t v 4 0 2249 "19 3220 23 1009" "{19,3220,23,1009,3220,28,17}" "{i,i,i,v,o,o,o}" "{slot_name,upto_lsn,upto_nchanges,options,location,xid,data}" _null_ pg_logical_slot_get_binary_changes _null_ _null_ _null_ )); +DESCR("get binary changes from replication slot"); +DATA(insert OID = 3784 ( pg_logical_slot_peek_changes PGNSP PGUID 12 1000 1000 25 0 f f f f f t v 4 0 2249 "19 3220 23 1009" "{19,3220,23,1009,3220,28,25}" "{i,i,i,v,o,o,o}" "{slot_name,upto_lsn,upto_nchanges,options,location,xid,data}" _null_ pg_logical_slot_peek_changes _null_ _null_ _null_ )); +DESCR("peek at changes from replication slot"); +DATA(insert OID = 3785 ( pg_logical_slot_peek_binary_changes PGNSP PGUID 12 1000 1000 25 0 f f f f f t v 4 0 2249 "19 3220 23 1009" "{19,3220,23,1009,3220,28,17}" "{i,i,i,v,o,o,o}" "{slot_name,upto_lsn,upto_nchanges,options,location,xid,data}" _null_ pg_logical_slot_peek_binary_changes _null_ _null_ _null_ )); +DESCR("peek at binary changes from replication slot"); + +/* event triggers */ +DATA(insert OID = 3566 ( pg_event_trigger_dropped_objects PGNSP PGUID 12 10 100 0 0 f f f f t t s 0 0 2249 "" "{26,26,23,25,25,25,25}" "{o,o,o,o,o,o,o}" "{classid, objid, objsubid, object_type, schema_name, object_name, object_identity}" _null_ pg_event_trigger_dropped_objects _null_ _null_ _null_ )); +DESCR("list objects dropped by the current command"); + +/* generic transition functions for ordered-set aggregates */ +DATA(insert OID = 3970 ( ordered_set_transition PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2276" _null_ _null_ _null_ _null_ ordered_set_transition _null_ _null_ _null_ )); +DESCR("aggregate transition function"); +DATA(insert OID = 3971 ( ordered_set_transition_multi PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 2281 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ ordered_set_transition_multi _null_ _null_ _null_ )); +DESCR("aggregate transition function"); + +/* inverse distribution aggregates (and their support functions) */ +DATA(insert OID = 3972 ( percentile_disc PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 2283 "701 2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("discrete percentile"); +DATA(insert OID = 3973 ( percentile_disc_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2283 "2281 701 2283" _null_ _null_ _null_ _null_ percentile_disc_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3974 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 701 "701 701" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("continuous distribution percentile"); +DATA(insert OID = 3975 ( percentile_cont_float8_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 701 "2281 701" _null_ _null_ _null_ _null_ percentile_cont_float8_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3976 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1186 "701 1186" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("continuous distribution percentile"); +DATA(insert OID = 3977 ( percentile_cont_interval_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 1186 "2281 701" _null_ _null_ _null_ _null_ percentile_cont_interval_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3978 ( percentile_disc PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 2277 "1022 2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple discrete percentiles"); +DATA(insert OID = 3979 ( percentile_disc_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2277 "2281 1022 2283" _null_ _null_ _null_ _null_ percentile_disc_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3980 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1022 "1022 701" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple continuous percentiles"); +DATA(insert OID = 3981 ( percentile_cont_float8_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 1022 "2281 1022" _null_ _null_ _null_ _null_ percentile_cont_float8_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3982 ( percentile_cont PGNSP PGUID 12 1 0 0 0 t f f f f f i 2 0 1187 "1022 1186" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("multiple continuous percentiles"); +DATA(insert OID = 3983 ( percentile_cont_interval_multi_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 1187 "2281 1022" _null_ _null_ _null_ _null_ percentile_cont_interval_multi_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3984 ( mode PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 2283 "2283" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("most common value"); +DATA(insert OID = 3985 ( mode_final PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2283 "2281 2283" _null_ _null_ _null_ _null_ mode_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); + +/* hypothetical-set aggregates (and their support functions) */ +DATA(insert OID = 3986 ( rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 20 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("rank of hypothetical row"); +DATA(insert OID = 3987 ( rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 20 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3988 ( percent_rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 701 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("fractional rank of hypothetical row"); +DATA(insert OID = 3989 ( percent_rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 701 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_percent_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3990 ( cume_dist PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 701 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("cumulative distribution of hypothetical row"); +DATA(insert OID = 3991 ( cume_dist_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 701 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_cume_dist_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); +DATA(insert OID = 3992 ( dense_rank PGNSP PGUID 12 1 0 2276 0 t f f f f f i 1 0 20 "2276" "{2276}" "{v}" _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); +DESCR("rank of hypothetical row without gaps"); +DATA(insert OID = 3993 ( dense_rank_final PGNSP PGUID 12 1 0 2276 0 f f f f f f i 2 0 20 "2281 2276" "{2281,2276}" "{i,v}" _null_ _null_ hypothetical_dense_rank_final _null_ _null_ _null_ )); +DESCR("aggregate final function"); #ifdef PGXC -DATA(insert OID = 3200 ( pgxc_pool_check PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_pool_check _null_ _null_ _null_ )); +DATA(insert OID = 6007 ( pgxc_pool_check PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_pool_check _null_ _null_ _null_ )); DESCR("check connection information consistency in pooler"); -DATA(insert OID = 3201 ( pgxc_pool_reload PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_pool_reload _null_ _null_ _null_ )); +DATA(insert OID = 6008 ( pgxc_pool_reload PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_pool_reload _null_ _null_ _null_ )); DESCR("reload connection information in pooler and reload server sessions"); -DATA(insert OID = 3202 ( pgxc_node_str PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 19 "" _null_ _null_ _null_ _null_ pgxc_node_str _null_ _null_ _null_ )); +DATA(insert OID = 6009 ( pgxc_node_str PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 19 "" _null_ _null_ _null_ _null_ pgxc_node_str _null_ _null_ _null_ )); DESCR("get the name of the node"); -DATA(insert OID = 3203 ( pgxc_is_committed PGNSP PGUID 12 1 1 0 0 f f f f t t s 1 0 16 "28" _null_ _null_ _null_ _null_ pgxc_is_committed _null_ _null_ _null_ )); +DATA(insert OID = 6010 ( pgxc_is_committed PGNSP PGUID 12 1 1 0 0 f f f f t t s 1 0 16 "28" _null_ _null_ _null_ _null_ pgxc_is_committed _null_ _null_ _null_ )); DESCR("is given GXID committed or aborted?"); -DATA(insert OID = 3205 ( pgxc_lock_for_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_lock_for_backup _null_ _null_ _null_ )); +DATA(insert OID = 6011 ( pgxc_lock_for_backup PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pgxc_lock_for_backup _null_ _null_ _null_ )); DESCR("lock the cluster for taking backup"); #ifdef XCP -DATA(insert OID = 3204 ( stormdb_promote_standby PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 2278 "" _null_ _null_ _null_ _null_ stormdb_promote_standby _null_ _null_ _null_ )); +DATA(insert OID = 6012 ( stormdb_promote_standby PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 2278 "" _null_ _null_ _null_ _null_ stormdb_promote_standby _null_ _null_ _null_ )); DESCR("touch trigger file on a standby machine to end replication"); #endif #endif @@ -4692,7 +5086,7 @@ DESCR("touch trigger file on a standby machine to end replication"); #define PROVOLATILE_VOLATILE 'v' /* can change even within a scan */ /* - * Symbolic values for proargmodes column. Note that these must agree with + * Symbolic values for proargmodes column. Note that these must agree with * the FunctionParameterMode enum in parsenodes.h; we declare them here to * be accessible from either header. */ diff --git a/src/include/catalog/pg_proc_fn.h b/src/include/catalog/pg_proc_fn.h index fcd09e7059..ab73bb50bf 100644 --- a/src/include/catalog/pg_proc_fn.h +++ b/src/include/catalog/pg_proc_fn.h @@ -4,7 +4,7 @@ * prototypes for functions in catalog/pg_proc.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_proc_fn.h diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h index 9b2be92fc9..664e771a4f 100644 --- a/src/include/catalog/pg_range.h +++ b/src/include/catalog/pg_range.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_range.h diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h index 5171522da0..37629fef3b 100644 --- a/src/include/catalog/pg_rewrite.h +++ b/src/include/catalog/pg_rewrite.h @@ -8,7 +8,7 @@ * --- ie, rule names are only unique among the rules of a given table. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_rewrite.h @@ -25,7 +25,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_rewrite definition. cpp turns this into + * pg_rewrite definition. cpp turns this into * typedef struct FormData_pg_rewrite * ---------------- */ @@ -35,7 +35,6 @@ CATALOG(pg_rewrite,2618) { NameData rulename; Oid ev_class; - int2 ev_attr; char ev_type; char ev_enabled; bool is_instead; @@ -57,14 +56,13 @@ typedef FormData_pg_rewrite *Form_pg_rewrite; * compiler constants for pg_rewrite * ---------------- */ -#define Natts_pg_rewrite 8 +#define Natts_pg_rewrite 7 #define Anum_pg_rewrite_rulename 1 #define Anum_pg_rewrite_ev_class 2 -#define Anum_pg_rewrite_ev_attr 3 -#define Anum_pg_rewrite_ev_type 4 -#define Anum_pg_rewrite_ev_enabled 5 -#define Anum_pg_rewrite_is_instead 6 -#define Anum_pg_rewrite_ev_qual 7 -#define Anum_pg_rewrite_ev_action 8 +#define Anum_pg_rewrite_ev_type 3 +#define Anum_pg_rewrite_ev_enabled 4 +#define Anum_pg_rewrite_is_instead 5 +#define Anum_pg_rewrite_ev_qual 6 +#define Anum_pg_rewrite_ev_action 7 #endif /* PG_REWRITE_H */ diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h index 917efcf8ca..3c219468fd 100644 --- a/src/include/catalog/pg_seclabel.h +++ b/src/include/catalog/pg_seclabel.h @@ -3,7 +3,7 @@ * pg_seclabel.h * definition of the system "security label" relation (pg_seclabel) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- @@ -24,7 +24,7 @@ CATALOG(pg_seclabel,3596) BKI_WITHOUT_OIDS { Oid objoid; /* OID of the object itself */ Oid classoid; /* OID of table containing the object */ - int4 objsubid; /* column number, or 0 if not used */ + int32 objsubid; /* column number, or 0 if not used */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ text provider; /* name of label provider */ diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h index 394fe43c58..346dc2e393 100644 --- a/src/include/catalog/pg_shdepend.h +++ b/src/include/catalog/pg_shdepend.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_shdepend.h @@ -33,13 +33,13 @@ CATALOG(pg_shdepend,1214) BKI_SHARED_RELATION BKI_WITHOUT_OIDS /* * Identification of the dependent (referencing) object. * - * These fields are all zeroes for a DEPENDENCY_PIN entry. Also, dbid can + * These fields are all zeroes for a DEPENDENCY_PIN entry. Also, dbid can * be zero to denote a shared object. */ Oid dbid; /* OID of database containing object */ Oid classid; /* OID of table containing object */ Oid objid; /* OID of object itself */ - int4 objsubid; /* column number, or 0 if not used */ + int32 objsubid; /* column number, or 0 if not used */ /* * Identification of the independent (referenced) object. This is always diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h index acd529b875..50a516ad1c 100644 --- a/src/include/catalog/pg_shdescription.h +++ b/src/include/catalog/pg_shdescription.h @@ -7,12 +7,12 @@ * NOTE: an object is identified by the OID of the row that primarily * defines the object, plus the OID of the table that that row appears in. * For example, a database is identified by the OID of its pg_database row - * plus the pg_class OID of table pg_database. This allows unique + * plus the pg_class OID of table pg_database. This allows unique * identification of objects without assuming that OIDs are unique * across tables. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_shdescription.h @@ -32,7 +32,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_shdescription definition. cpp turns this into + * pg_shdescription definition. cpp turns this into * typedef struct FormData_pg_shdescription * ---------------- */ diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h index 3d7a013e8c..409a56a0af 100644 --- a/src/include/catalog/pg_shseclabel.h +++ b/src/include/catalog/pg_shseclabel.h @@ -3,7 +3,7 @@ * pg_shseclabel.h * definition of the system "security label" relation (pg_shseclabel) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h index 3ad0c28110..e6c00f619f 100644 --- a/src/include/catalog/pg_statistic.h +++ b/src/include/catalog/pg_statistic.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_statistic.h @@ -32,14 +32,14 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS { /* These fields form the unique key for the entry: */ Oid starelid; /* relation containing attribute */ - int2 staattnum; /* attribute (column) stats are for */ + int16 staattnum; /* attribute (column) stats are for */ bool stainherit; /* true if inheritance children are included */ /* the fraction of the column's entries that are NULL: */ float4 stanullfrac; /* - * stawidth is the average width in bytes of non-null entries. For + * stawidth is the average width in bytes of non-null entries. For * fixed-width datatypes this is of course the same as the typlen, but for * var-width types it is more useful. Note that this is the average width * of the data as actually stored, post-TOASTing (eg, for a @@ -48,7 +48,7 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS * the statistic, which is to estimate sizes of in-memory hash tables of * tuples. */ - int4 stawidth; + int32 stawidth; /* ---------------- * stadistinct indicates the (approximate) number of distinct non-null @@ -59,7 +59,7 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS * The special negative case allows us to cope with columns that are * unique (stadistinct = -1) or nearly so (for example, a column in * which values appear about twice on the average could be represented - * by stadistinct = -0.5). Because the number-of-rows statistic in + * by stadistinct = -0.5). Because the number-of-rows statistic in * pg_class may be updated more frequently than pg_statistic is, it's * important to be able to describe such situations as a multiple of * the number of rows, rather than a fixed number of distinct values. @@ -71,8 +71,8 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS /* ---------------- * To allow keeping statistics on different kinds of datatypes, * we do not hard-wire any particular meaning for the remaining - * statistical fields. Instead, we provide several "slots" in which - * statistical data can be placed. Each slot includes: + * statistical fields. Instead, we provide several "slots" in which + * statistical data can be placed. Each slot includes: * kind integer code identifying kind of data (see below) * op OID of associated operator, if needed * numbers float4 array (for statistical values) @@ -84,11 +84,11 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS * ---------------- */ - int2 stakind1; - int2 stakind2; - int2 stakind3; - int2 stakind4; - int2 stakind5; + int16 stakind1; + int16 stakind2; + int16 stakind3; + int16 stakind4; + int16 stakind5; Oid staop1; Oid staop2; @@ -105,7 +105,7 @@ CATALOG(pg_statistic,2619) BKI_WITHOUT_OIDS /* * Values in these arrays are values of the column's data type, or of some - * related type such as an array element type. We presently have to cheat + * related type such as an array element type. We presently have to cheat * quite a bit to allow polymorphic arrays of this kind, but perhaps * someday it'll be a less bogus facility. */ @@ -168,8 +168,8 @@ typedef FormData_pg_statistic *Form_pg_statistic; * operators. * * Code reading the pg_statistic relation should not assume that a particular - * data "kind" will appear in any particular slot. Instead, search the - * stakind fields to see if the desired data is available. (The standard + * data "kind" will appear in any particular slot. Instead, search the + * stakind fields to see if the desired data is available. (The standard * function get_attstatsslot() may be used for this.) */ @@ -196,7 +196,7 @@ typedef FormData_pg_statistic *Form_pg_statistic; * the K most common non-null values appearing in the column, and stanumbers * contains their frequencies (fractions of total row count). The values * shall be ordered in decreasing frequency. Note that since the arrays are - * variable-size, K may be chosen by the statistics collector. Values should + * variable-size, K may be chosen by the statistics collector. Values should * not appear in MCV unless they have been observed to occur more than once; * a unique column will have no MCV slot. */ @@ -208,13 +208,13 @@ typedef FormData_pg_statistic *Form_pg_statistic; * more than one histogram could appear, if a datatype has more than one * useful sort operator.) stavalues contains M (>=2) non-null values that * divide the non-null column data values into M-1 bins of approximately equal - * population. The first stavalues item is the MIN and the last is the MAX. + * population. The first stavalues item is the MIN and the last is the MAX. * stanumbers is not used and should be NULL. IMPORTANT POINT: if an MCV * slot is also provided, then the histogram describes the data distribution * *after removing the values listed in MCV* (thus, it's a "compressed * histogram" in the technical parlance). This allows a more accurate * representation of the distribution of a column with some very-common - * values. In a column with only a few distinct values, it's possible that + * values. In a column with only a few distinct values, it's possible that * the MCV list describes the entire data population; in this case the * histogram reduces to empty and should be omitted. */ @@ -225,7 +225,7 @@ typedef FormData_pg_statistic *Form_pg_statistic; * of table tuples and the ordering of data values of this column, as seen * by the "<" operator identified by staop. (As with the histogram, more * than one entry could theoretically appear.) stavalues is not used and - * should be NULL. stanumbers contains a single entry, the correlation + * should be NULL. stanumbers contains a single entry, the correlation * coefficient between the sequence of data values and the sequence of * their actual tuple positions. The coefficient ranges from +1 to -1. */ @@ -234,7 +234,7 @@ typedef FormData_pg_statistic *Form_pg_statistic; /* * A "most common elements" slot is similar to a "most common values" slot, * except that it stores the most common non-null *elements* of the column - * values. This is useful when the column datatype is an array or some other + * values. This is useful when the column datatype is an array or some other * type with identifiable elements (for instance, tsvector). staop contains * the equality operator appropriate to the element type. stavalues contains * the most common element values, and stanumbers their frequencies. Unlike @@ -258,7 +258,7 @@ typedef FormData_pg_statistic *Form_pg_statistic; /* * A "distinct elements count histogram" slot describes the distribution of * the number of distinct element values present in each row of an array-type - * column. Only non-null rows are considered, and only non-null elements. + * column. Only non-null rows are considered, and only non-null elements. * staop contains the equality operator appropriate to the element type. * stavalues is not used and should be NULL. The last member of stanumbers is * the average count of distinct element values over all non-null rows. The @@ -268,4 +268,26 @@ typedef FormData_pg_statistic *Form_pg_statistic; */ #define STATISTIC_KIND_DECHIST 5 +/* + * A "length histogram" slot describes the distribution of range lengths in + * rows of a range-type column. stanumbers contains a single entry, the + * fraction of empty ranges. stavalues is a histogram of non-empty lengths, in + * a format similar to STATISTIC_KIND_HISTOGRAM: it contains M (>=2) range + * values that divide the column data values into M-1 bins of approximately + * equal population. The lengths are stores as float8s, as measured by the + * range type's subdiff function. Only non-null rows are considered. + */ +#define STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM 6 + +/* + * A "bounds histogram" slot is similar to STATISTIC_KIND_HISTOGRAM, but for + * a range-type column. stavalues contains M (>=2) range values that divide + * the column data values into M-1 bins of approximately equal population. + * Unlike a regular scalar histogram, this is actually two histograms combined + * into a single array, with the lower bounds of each value forming a + * histogram of lower bounds, and the upper bounds a histogram of upper + * bounds. Only non-NULL, non-empty ranges are included. + */ +#define STATISTIC_KIND_BOUNDS_HISTOGRAM 7 + #endif /* PG_STATISTIC_H */ diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index 777a8a1778..41fad464cf 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_tablespace.h diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h index 71afab58e5..600a2f76c6 100644 --- a/src/include/catalog/pg_trigger.h +++ b/src/include/catalog/pg_trigger.h @@ -5,7 +5,7 @@ * along with the relation's initial contents. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_trigger.h @@ -22,7 +22,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_trigger definition. cpp turns this into + * pg_trigger definition. cpp turns this into * typedef struct FormData_pg_trigger * * Note: when tgconstraint is nonzero, tgconstrrelid, tgconstrindid, @@ -38,7 +38,7 @@ CATALOG(pg_trigger,2620) Oid tgrelid; /* relation trigger is attached to */ NameData tgname; /* trigger's name */ Oid tgfoid; /* OID of function to be called */ - int2 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, + int16 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT, * ROW/STATEMENT; see below */ char tgenabled; /* trigger's firing configuration WRT * session_replication_role */ @@ -48,7 +48,7 @@ CATALOG(pg_trigger,2620) Oid tgconstraint; /* associated pg_constraint entry, if any */ bool tgdeferrable; /* constraint trigger is deferrable */ bool tginitdeferred; /* constraint trigger is deferred initially */ - int2 tgnargs; /* # of extra arguments in tgargs */ + int16 tgnargs; /* # of extra arguments in tgargs */ /* * Variable-length fields start here, but we allow direct access to diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h index 5b7b1acbd5..52e32ddf2f 100644 --- a/src/include/catalog/pg_ts_config.h +++ b/src/include/catalog/pg_ts_config.h @@ -4,7 +4,7 @@ * definition of configuration of tsearch * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_config.h diff --git a/src/include/catalog/pg_ts_config_map.h b/src/include/catalog/pg_ts_config_map.h index c377338174..a682a1ae80 100644 --- a/src/include/catalog/pg_ts_config_map.h +++ b/src/include/catalog/pg_ts_config_map.h @@ -4,7 +4,7 @@ * definition of token mappings for configurations of tsearch * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_config_map.h @@ -33,8 +33,8 @@ CATALOG(pg_ts_config_map,3603) BKI_WITHOUT_OIDS { Oid mapcfg; /* OID of configuration owning this entry */ - int4 maptokentype; /* token type from parser */ - int4 mapseqno; /* order in which to consult dictionaries */ + int32 maptokentype; /* token type from parser */ + int32 mapseqno; /* order in which to consult dictionaries */ Oid mapdict; /* dictionary to consult */ } FormData_pg_ts_config_map; diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h index 677a870b77..0968aeeada 100644 --- a/src/include/catalog/pg_ts_dict.h +++ b/src/include/catalog/pg_ts_dict.h @@ -4,7 +4,7 @@ * definition of dictionaries for tsearch * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_dict.h @@ -24,7 +24,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_ts_dict definition. cpp turns this into + * pg_ts_dict definition. cpp turns this into * typedef struct FormData_pg_ts_dict * ---------------- */ diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h index e892d1f5fc..b1b726f8e2 100644 --- a/src/include/catalog/pg_ts_parser.h +++ b/src/include/catalog/pg_ts_parser.h @@ -4,7 +4,7 @@ * definition of parsers for tsearch * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_parser.h diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h index 813912ee96..504075b99b 100644 --- a/src/include/catalog/pg_ts_template.h +++ b/src/include/catalog/pg_ts_template.h @@ -4,7 +4,7 @@ * definition of dictionary templates for tsearch * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_template.h @@ -24,7 +24,7 @@ #include "catalog/genbki.h" /* ---------------- - * pg_ts_template definition. cpp turns this into + * pg_ts_template definition. cpp turns this into * typedef struct FormData_pg_ts_template * ---------------- */ diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index f87ec04655..756c161e0c 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -10,7 +10,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_type.h @@ -47,16 +47,16 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * For a fixed-size type, typlen is the number of bytes we use to - * represent a value of this type, e.g. 4 for an int4. But for a + * represent a value of this type, e.g. 4 for an int4. But for a * variable-length type, typlen is negative. We use -1 to indicate a * "varlena" type (one that has a length word), -2 to indicate a * null-terminated C string. */ - int2 typlen; + int16 typlen; /* * typbyval determines whether internal Postgres routines pass a value of - * this type by value or by reference. typbyval had better be FALSE if + * this type by value or by reference. typbyval had better be FALSE if * the length is not 1, 2, or 4 (or 8 on 8-byte-Datum machines). * Variable-length types are always passed by reference. Note that * typbyval can be false even if the length would allow pass-by-value; @@ -76,7 +76,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * typcategory and typispreferred help the parser distinguish preferred * and non-preferred coercions. The category can be any single ASCII - * character (but not \0). The categories used for built-in types are + * character (but not \0). The categories used for built-in types are * identified by the TYPCATEGORY macros below. */ char typcategory; /* arbitrary type classification */ @@ -85,7 +85,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * If typisdefined is false, the entry is only a placeholder (forward - * reference). We know the type name, but not yet anything else about it. + * reference). We know the type name, but not yet anything else about it. */ bool typisdefined; @@ -146,7 +146,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO * 'd' = DOUBLE alignment (8 bytes on many machines, but by no means all). * * See include/access/tupmacs.h for the macros that compute these - * alignment requirements. Note also that we allow the nominal alignment + * alignment requirements. Note also that we allow the nominal alignment * to be violated when storing "packed" varlenas; the TOAST mechanism * takes care of hiding that from most code. * @@ -181,7 +181,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO /* * Domains use typbasetype to show the base (or domain) type that the - * domain is based on. Zero if the type is not a domain. + * domain is based on. Zero if the type is not a domain. */ Oid typbasetype; @@ -190,13 +190,13 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71) BKI_SCHEMA_MACRO * type (-1 if base type does not use a typmod). -1 if this type is not a * domain. */ - int4 typtypmod; + int32 typtypmod; /* * typndims is the declared number of dimensions for an array domain type * (i.e., typbasetype is an array type). Otherwise zero. */ - int4 typndims; + int32 typndims; /* * Collation: 0 if type cannot use collations, DEFAULT_COLLATION_OID for @@ -397,11 +397,10 @@ DATA(insert OID = 604 ( polygon PGNSP PGUID -1 f b G f t \054 0 0 1027 poly_ DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 -DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); -DESCR("geometric line (not implemented)"); +DATA(insert OID = 628 ( line PGNSP PGUID 24 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); +DESCR("geometric line"); #define LINEOID 628 DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); -DESCR(""); /* OIDS 700 - 799 */ @@ -452,6 +451,7 @@ DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in DATA(insert OID = 1002 ( _char PGNSP PGUID -1 f b A f t \054 0 18 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1003 ( _name PGNSP PGUID -1 f b A f t \054 0 19 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1005 ( _int2 PGNSP PGUID -1 f b A f t \054 0 21 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +#define INT2ARRAYOID 1005 DATA(insert OID = 1006 ( _int2vector PGNSP PGUID -1 f b A f t \054 0 22 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1007 ( _int4 PGNSP PGUID -1 f b A f t \054 0 23 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); #define INT4ARRAYOID 1007 @@ -459,6 +459,7 @@ DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_i DATA(insert OID = 1009 ( _text PGNSP PGUID -1 f b A f t \054 0 25 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ )); #define TEXTARRAYOID 1009 DATA(insert OID = 1028 ( _oid PGNSP PGUID -1 f b A f t \054 0 26 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +#define OIDARRAYOID 1028 DATA(insert OID = 1010 ( _tid PGNSP PGUID -1 f b A f t \054 0 27 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1011 ( _xid PGNSP PGUID -1 f b A f t \054 0 28 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1012 ( _cid PGNSP PGUID -1 f b A f t \054 0 29 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); @@ -578,11 +579,15 @@ DATA(insert OID = 2211 ( _regtype PGNSP PGUID -1 f b A f t \054 0 2206 0 arra /* uuid */ DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b U f t \054 0 0 2951 uuid_in uuid_out uuid_recv uuid_send - - - c p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("UUID datatype"); -#ifdef XCP -#define UUIDOID 2950 -#endif +#define UUIDOID 2950 DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b A f t \054 0 2950 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +/* pg_lsn */ +DATA(insert OID = 3220 ( pg_lsn PGNSP PGUID 8 FLOAT8PASSBYVAL b U f t \054 0 0 3221 pg_lsn_in pg_lsn_out pg_lsn_recv pg_lsn_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); +DESCR("PostgreSQL LSN datatype"); +#define LSNOID 3220 +DATA(insert OID = 3221 ( _pg_lsn PGNSP PGUID -1 f b A f t \054 0 3220 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); + /* text search */ DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b U f t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - ts_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("text representation for text search"); @@ -606,6 +611,12 @@ DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b A f t \054 0 3615 0 array_ DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b A f t \054 0 3734 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b A f t \054 0 3769 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +/* jsonb */ +DATA(insert OID = 3802 ( jsonb PGNSP PGUID -1 f b U f t \054 0 0 3807 jsonb_in jsonb_out jsonb_recv jsonb_send - - - i x f 0 -1 0 0 _null_ _null_ _null_ )); +DESCR("Binary JSON"); +#define JSONBOID 3802 +DATA(insert OID = 3807 ( _jsonb PGNSP PGUID -1 f b A f t \054 0 3802 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); + DATA(insert OID = 2970 ( txid_snapshot PGNSP PGUID -1 f b U f t \054 0 0 2949 txid_snapshot_in txid_snapshot_out txid_snapshot_recv txid_snapshot_send - - - d x f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("txid snapshot"); DATA(insert OID = 2949 ( _txid_snapshot PGNSP PGUID -1 f b A f t \054 0 2970 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); @@ -658,6 +669,8 @@ DATA(insert OID = 2278 ( void PGNSP PGUID 4 t p P f t \054 0 0 0 void_in void #define VOIDOID 2278 DATA(insert OID = 2279 ( trigger PGNSP PGUID 4 t p P f t \054 0 0 0 trigger_in trigger_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define TRIGGEROID 2279 +DATA(insert OID = 3838 ( event_trigger PGNSP PGUID 4 t p P f t \054 0 0 0 event_trigger_in event_trigger_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); +#define EVTTRIGGEROID 3838 DATA(insert OID = 2280 ( language_handler PGNSP PGUID 4 t p P f t \054 0 0 0 language_handler_in language_handler_out - - - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); #define LANGUAGE_HANDLEROID 2280 DATA(insert OID = 2281 ( internal PGNSP PGUID SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ _null_ )); diff --git a/src/include/catalog/pg_type_fn.h b/src/include/catalog/pg_type_fn.h index 30109b964a..234d706c1e 100644 --- a/src/include/catalog/pg_type_fn.h +++ b/src/include/catalog/pg_type_fn.h @@ -4,7 +4,7 @@ * prototypes for functions in catalog/pg_type.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_type_fn.h diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h index 1d2f9b0bd0..3144234798 100644 --- a/src/include/catalog/pg_user_mapping.h +++ b/src/include/catalog/pg_user_mapping.h @@ -3,7 +3,7 @@ * pg_user_mapping.h * definition of the system "user mapping" relation (pg_user_mapping) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_user_mapping.h diff --git a/src/include/catalog/pgxc_class.h b/src/include/catalog/pgxc_class.h index cb540bf584..164dbd9afc 100644 --- a/src/include/catalog/pgxc_class.h +++ b/src/include/catalog/pgxc_class.h @@ -12,9 +12,9 @@ CATALOG(pgxc_class,9001) BKI_WITHOUT_OIDS { Oid pcrelid; /* Table Oid */ char pclocatortype; /* Type of distribution */ - int2 pcattnum; /* Column number of distribution */ - int2 pchashalgorithm; /* Hashing algorithm */ - int2 pchashbuckets; /* Number of buckets */ + int16 pcattnum; /* Column number of distribution */ + int16 pchashalgorithm; /* Hashing algorithm */ + int16 pchashbuckets; /* Number of buckets */ /* VARIABLE LENGTH FIELDS: */ oidvector nodeoids; /* List of nodes used by table */ diff --git a/src/include/catalog/pgxc_node.h b/src/include/catalog/pgxc_node.h index e272243956..c55633cddd 100644 --- a/src/include/catalog/pgxc_node.h +++ b/src/include/catalog/pgxc_node.h @@ -36,7 +36,7 @@ CATALOG(pgxc_node,9015) BKI_SHARED_RELATION /* * Port number of the node to connect to */ - int4 node_port; + int32 node_port; /* * Host name of IP address of the node to connect to @@ -56,7 +56,7 @@ CATALOG(pgxc_node,9015) BKI_SHARED_RELATION /* * Node identifier to be used at places where a fixed length node identification is required */ - int4 node_id; + int32 node_id; } FormData_pgxc_node; typedef FormData_pgxc_node *Form_pgxc_node; diff --git a/src/include/catalog/storage.h b/src/include/catalog/storage.h index d5103a88f4..4b87a36191 100644 --- a/src/include/catalog/storage.h +++ b/src/include/catalog/storage.h @@ -4,7 +4,7 @@ * prototypes for functions in backend/catalog/storage.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/storage.h @@ -14,7 +14,6 @@ #ifndef STORAGE_H #define STORAGE_H -#include "access/xlog.h" #include "storage/block.h" #include "storage/relfilenode.h" #include "utils/relcache.h" @@ -34,9 +33,4 @@ extern void AtSubCommit_smgr(void); extern void AtSubAbort_smgr(void); extern void PostPrepare_smgr(void); -extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum); - -extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record); -extern void smgr_desc(StringInfo buf, uint8 xl_info, char *rec); - #endif /* STORAGE_H */ diff --git a/src/include/catalog/storage_xlog.h b/src/include/catalog/storage_xlog.h new file mode 100644 index 0000000000..43bf277f35 --- /dev/null +++ b/src/include/catalog/storage_xlog.h @@ -0,0 +1,49 @@ +/*------------------------------------------------------------------------- + * + * storage_xlog.h + * prototypes for XLog support for backend/catalog/storage.c + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/storage_xlog.h + * + *------------------------------------------------------------------------- + */ +#ifndef STORAGE_XLOG_H +#define STORAGE_XLOG_H + +#include "access/xlog.h" +#include "storage/block.h" +#include "storage/relfilenode.h" + +/* + * Declarations for smgr-related XLOG records + * + * Note: we log file creation and truncation here, but logging of deletion + * actions is handled by xact.c, because it is part of transaction commit. + */ + +/* XLOG gives us high 4 bits */ +#define XLOG_SMGR_CREATE 0x10 +#define XLOG_SMGR_TRUNCATE 0x20 + +typedef struct xl_smgr_create +{ + RelFileNode rnode; + ForkNumber forkNum; +} xl_smgr_create; + +typedef struct xl_smgr_truncate +{ + BlockNumber blkno; + RelFileNode rnode; +} xl_smgr_truncate; + +extern void log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum); + +extern void smgr_redo(XLogRecPtr lsn, XLogRecord *record); +extern void smgr_desc(StringInfo buf, uint8 xl_info, char *rec); + +#endif /* STORAGE_XLOG_H */ diff --git a/src/include/catalog/toasting.h b/src/include/catalog/toasting.h index 22211cbe3f..a4af551523 100644 --- a/src/include/catalog/toasting.h +++ b/src/include/catalog/toasting.h @@ -4,7 +4,7 @@ * This file provides some definitions to support creation of toast tables * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/toasting.h @@ -14,10 +14,16 @@ #ifndef TOASTING_H #define TOASTING_H +#include "storage/lock.h" + /* * toasting.c prototypes */ -extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions); +extern void NewRelationCreateToastTable(Oid relOid, Datum reloptions); +extern void NewHeapCreateToastTable(Oid relOid, Datum reloptions, + LOCKMODE lockmode); +extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions, + LOCKMODE lockmode); extern void BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid); diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h index 210cf4eacd..5907184902 100644 --- a/src/include/commands/alter.h +++ b/src/include/commands/alter.h @@ -4,7 +4,7 @@ * prototypes for commands/alter.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/alter.h @@ -14,16 +14,18 @@ #ifndef ALTER_H #define ALTER_H -#include "utils/acl.h" +#include "catalog/dependency.h" +#include "nodes/parsenodes.h" #include "utils/relcache.h" -extern void ExecRenameStmt(RenameStmt *stmt); -extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); -extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid); -extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId, - Oid objid, Oid nspOid, - int Anum_name, int Anum_namespace, int Anum_owner, - AclObjectKind acl_kind); -extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt); +extern Oid ExecRenameStmt(RenameStmt *stmt); + +extern Oid ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt); +extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, + ObjectAddresses *objsMoved); + +extern Oid ExecAlterOwnerStmt(AlterOwnerStmt *stmt); +extern void AlterObjectOwner_internal(Relation catalog, Oid objectId, + Oid new_ownerId); #endif /* ALTER_H */ diff --git a/src/include/commands/async.h b/src/include/commands/async.h index 3d1cf6873e..0650e654a5 100644 --- a/src/include/commands/async.h +++ b/src/include/commands/async.h @@ -3,7 +3,7 @@ * async.h * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/async.h diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h index 21b2a58020..0ada3d6516 100644 --- a/src/include/commands/cluster.h +++ b/src/include/commands/cluster.h @@ -3,7 +3,7 @@ * cluster.h * header file for postgres cluster command stuff * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/commands/cluster.h @@ -20,16 +20,19 @@ extern void cluster(ClusterStmt *stmt, bool isTopLevel); extern void cluster_rel(Oid tableOid, Oid indexOid, bool recheck, - bool verbose, int freeze_min_age, int freeze_table_age); + bool verbose); extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMODE lockmode); -extern void mark_index_clustered(Relation rel, Oid indexOid); +extern void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal); -extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace); +extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, bool forcetemp, + LOCKMODE lockmode); extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, bool is_system_catalog, bool swap_toast_by_content, bool check_constraints, - TransactionId frozenXid); + bool is_internal, + TransactionId frozenXid, + MultiXactId minMulti); #endif /* CLUSTER_H */ diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h index 0587c4f3ff..da95abcfb7 100644 --- a/src/include/commands/collationcmds.h +++ b/src/include/commands/collationcmds.h @@ -4,7 +4,7 @@ * prototypes for collationcmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/collationcmds.h @@ -17,11 +17,7 @@ #include "nodes/parsenodes.h" -extern void DefineCollation(List *names, List *parameters); -extern void RenameCollation(List *name, const char *newname); -extern void AlterCollationOwner(List *name, Oid newOwnerId); -extern void AlterCollationOwner_oid(Oid collationOid, Oid newOwnerId); -extern void AlterCollationNamespace(List *name, const char *newschema); -extern Oid AlterCollationNamespace_oid(Oid collOid, Oid newNspOid); +extern Oid DefineCollation(List *names, List *parameters); +extern void IsThereCollationInNamespace(const char *collname, Oid nspOid); #endif /* COLLATIONCMDS_H */ diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h index 441d8bd253..05fe0c6744 100644 --- a/src/include/commands/comment.h +++ b/src/include/commands/comment.h @@ -7,7 +7,7 @@ * * Prototypes for functions in commands/comment.c * - * Copyright (c) 1999-2012, PostgreSQL Global Development Group + * Copyright (c) 1999-2014, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -24,12 +24,12 @@ * related routines. CommentObject() implements the SQL "COMMENT ON" * command. DeleteComments() deletes all comments for an object. * CreateComments creates (or deletes, if comment is NULL) a comment - * for a specific key. There are versions of these two methods for + * for a specific key. There are versions of these two methods for * both normal and shared objects. *------------------------------------------------------------------ */ -extern void CommentObject(CommentStmt *stmt); +extern Oid CommentObject(CommentStmt *stmt); extern void DeleteComments(Oid oid, Oid classoid, int32 subid); diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 00f468f985..f7a445c5ad 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -4,7 +4,7 @@ * prototypes for conversioncmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/conversioncmds.h @@ -17,11 +17,6 @@ #include "nodes/parsenodes.h" -extern void CreateConversionCommand(CreateConversionStmt *parsetree); -extern void RenameConversion(List *name, const char *newname); -extern void AlterConversionOwner(List *name, Oid newOwnerId); -extern void AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId); -extern void AlterConversionNamespace(List *name, const char *newschema); -extern Oid AlterConversionNamespace_oid(Oid convOid, Oid newNspOid); +extern Oid CreateConversionCommand(CreateConversionStmt *parsetree); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index 8680ac3ddc..ba0f1b3d76 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -4,7 +4,7 @@ * Definitions for using the POSTGRES copy command. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/copy.h @@ -21,11 +21,12 @@ /* CopyStateData is private in commands/copy.c */ typedef struct CopyStateData *CopyState; -extern uint64 DoCopy(const CopyStmt *stmt, const char *queryString); +extern Oid DoCopy(const CopyStmt *stmt, const char *queryString, + uint64 *processed); extern void ProcessCopyOptions(CopyState cstate, bool is_from, List *options); extern CopyState BeginCopyFrom(Relation rel, const char *filename, - List *attnamelist, List *options); + bool is_program, List *attnamelist, List *options); extern void EndCopyFrom(CopyState cstate); extern bool NextCopyFrom(CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls, Oid *tupleOid); diff --git a/src/include/commands/createas.h b/src/include/commands/createas.h index 946c7e2cf1..c17d829a3c 100644 --- a/src/include/commands/createas.h +++ b/src/include/commands/createas.h @@ -4,7 +4,7 @@ * prototypes for createas.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/createas.h diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 3bb0450a6b..7be275371b 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -4,7 +4,7 @@ * Database management commands (create/drop database). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/dbcommands.h @@ -52,12 +52,12 @@ typedef struct xl_dbase_drop_rec Oid tablespace_id; } xl_dbase_drop_rec; -extern void createdb(const CreatedbStmt *stmt); +extern Oid createdb(const CreatedbStmt *stmt); extern void dropdb(const char *dbname, bool missing_ok); -extern void RenameDatabase(const char *oldname, const char *newname); -extern void AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel); -extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); -extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId); +extern Oid RenameDatabase(const char *oldname, const char *newname); +extern Oid AlterDatabase(AlterDatabaseStmt *stmt, bool isTopLevel); +extern Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt); +extern Oid AlterDatabaseOwner(const char *dbname, Oid newOwnerId); extern Oid get_database_oid(const char *dbname, bool missingok); extern char *get_database_name(Oid dbid); diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 8f3d2c358d..5ec9374aad 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -4,7 +4,7 @@ * POSTGRES define and remove utility definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/defrem.h @@ -15,152 +15,113 @@ #define DEFREM_H #include "nodes/parsenodes.h" +#include "utils/array.h" /* commands/dropcmds.c */ extern void RemoveObjects(DropStmt *stmt); /* commands/indexcmds.c */ -extern Oid DefineIndex(RangeVar *heapRelation, - char *indexRelationName, +extern Oid DefineIndex(Oid relationId, + IndexStmt *stmt, Oid indexRelationId, - Oid relFileNode, - char *accessMethodName, - char *tableSpaceName, - List *attributeList, - Expr *predicate, - List *options, - List *exclusionOpNames, - bool unique, - bool primary, - bool isconstraint, - bool deferrable, - bool initdeferred, bool is_alter_table, bool check_rights, bool skip_build, - bool quiet, - bool concurrent); -extern void ReindexIndex(RangeVar *indexRelation); -extern void ReindexTable(RangeVar *relation); -extern void ReindexDatabase(const char *databaseName, + bool quiet); +extern Oid ReindexIndex(RangeVar *indexRelation); +extern Oid ReindexTable(RangeVar *relation); +extern Oid ReindexDatabase(const char *databaseName, bool do_system, bool do_user); extern char *makeObjectName(const char *name1, const char *name2, const char *label); extern char *ChooseRelationName(const char *name1, const char *name2, const char *label, Oid namespaceid); -extern char *ChooseIndexName(const char *tabname, Oid namespaceId, - List *colnames, List *exclusionOpNames, - bool primary, bool isconstraint); -extern List *ChooseIndexColumnNames(List *indexElems); extern bool CheckIndexCompatible(Oid oldId, - RangeVar *heapRelation, char *accessMethodName, List *attributeList, List *exclusionOpNames); extern Oid GetDefaultOpClass(Oid type_id, Oid am_id); /* commands/functioncmds.c */ -extern void CreateFunction(CreateFunctionStmt *stmt, const char *queryString); +extern Oid CreateFunction(CreateFunctionStmt *stmt, const char *queryString); extern void RemoveFunctionById(Oid funcOid); extern void SetFunctionReturnType(Oid funcOid, Oid newRetType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); -extern void RenameFunction(List *name, List *argtypes, const char *newname); -extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId); -extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId); -extern void AlterFunction(AlterFunctionStmt *stmt); -extern void CreateCast(CreateCastStmt *stmt); +extern Oid AlterFunction(AlterFunctionStmt *stmt); +extern Oid CreateCast(CreateCastStmt *stmt); extern void DropCastById(Oid castOid); -extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg, - const char *newschema); -extern Oid AlterFunctionNamespace_oid(Oid procOid, Oid nspOid); +extern void IsThereFunctionInNamespace(const char *proname, int pronargs, + oidvector *proargtypes, Oid nspOid); extern void ExecuteDoStmt(DoStmt *stmt); extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); +extern void interpret_function_parameter_list(List *parameters, + Oid languageOid, + bool is_aggregate, + const char *queryString, + oidvector **parameterTypes, + ArrayType **allParameterTypes, + ArrayType **parameterModes, + ArrayType **parameterNames, + List **parameterDefaults, + Oid *variadicArgType, + Oid *requiredResultType); /* commands/operatorcmds.c */ -extern void DefineOperator(List *names, List *parameters); +extern Oid DefineOperator(List *names, List *parameters); extern void RemoveOperatorById(Oid operOid); -extern void AlterOperatorOwner(List *name, TypeName *typeName1, - TypeName *typename2, Oid newOwnerId); -extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId); -extern void AlterOperatorNamespace(List *names, List *argtypes, const char *newschema); -extern Oid AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid); /* commands/aggregatecmds.c */ -extern void DefineAggregate(List *name, List *args, bool oldstyle, - List *parameters); -extern void RenameAggregate(List *name, List *args, const char *newname); -extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId); +extern Oid DefineAggregate(List *name, List *args, bool oldstyle, + List *parameters, const char *queryString); /* commands/opclasscmds.c */ -extern void DefineOpClass(CreateOpClassStmt *stmt); -extern void DefineOpFamily(CreateOpFamilyStmt *stmt); -extern void AlterOpFamily(AlterOpFamilyStmt *stmt); +extern Oid DefineOpClass(CreateOpClassStmt *stmt); +extern Oid DefineOpFamily(CreateOpFamilyStmt *stmt); +extern Oid AlterOpFamily(AlterOpFamilyStmt *stmt); extern void RemoveOpClassById(Oid opclassOid); extern void RemoveOpFamilyById(Oid opfamilyOid); extern void RemoveAmOpEntryById(Oid entryOid); extern void RemoveAmProcEntryById(Oid entryOid); -extern void RenameOpClass(List *name, const char *access_method, const char *newname); -extern void RenameOpFamily(List *name, const char *access_method, const char *newname); -extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId); -extern void AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId); -extern void AlterOpClassNamespace(List *name, char *access_method, const char *newschema); -extern Oid AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid); -extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId); -extern void AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId); -extern void AlterOpFamilyNamespace(List *name, char *access_method, const char *newschema); -extern Oid AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid); +extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, + Oid opcnamespace); +extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, + Oid opfnamespace); extern Oid get_am_oid(const char *amname, bool missing_ok); extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); /* commands/tsearchcmds.c */ -extern void DefineTSParser(List *names, List *parameters); -extern void RenameTSParser(List *oldname, const char *newname); -extern void AlterTSParserNamespace(List *name, const char *newschema); -extern Oid AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid); +extern Oid DefineTSParser(List *names, List *parameters); extern void RemoveTSParserById(Oid prsId); -extern void DefineTSDictionary(List *names, List *parameters); -extern void RenameTSDictionary(List *oldname, const char *newname); +extern Oid DefineTSDictionary(List *names, List *parameters); extern void RemoveTSDictionaryById(Oid dictId); -extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt); -extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId); -extern void AlterTSDictionaryNamespace(List *name, const char *newschema); -extern Oid AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid); - -extern void DefineTSTemplate(List *names, List *parameters); -extern void RenameTSTemplate(List *oldname, const char *newname); -extern void AlterTSTemplateNamespace(List *name, const char *newschema); -extern Oid AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid); +extern Oid AlterTSDictionary(AlterTSDictionaryStmt *stmt); + +extern Oid DefineTSTemplate(List *names, List *parameters); extern void RemoveTSTemplateById(Oid tmplId); -extern void DefineTSConfiguration(List *names, List *parameters); -extern void RenameTSConfiguration(List *oldname, const char *newname); +extern Oid DefineTSConfiguration(List *names, List *parameters); extern void RemoveTSConfigurationById(Oid cfgId); -extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt); -extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId); -extern void AlterTSConfigurationNamespace(List *name, const char *newschema); -extern Oid AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid); +extern Oid AlterTSConfiguration(AlterTSConfigurationStmt *stmt); extern text *serialize_deflist(List *deflist); extern List *deserialize_deflist(Datum txt); /* commands/foreigncmds.c */ -extern void RenameForeignServer(const char *oldname, const char *newname); -extern void RenameForeignDataWrapper(const char *oldname, const char *newname); -extern void AlterForeignServerOwner(const char *name, Oid newOwnerId); +extern Oid AlterForeignServerOwner(const char *name, Oid newOwnerId); extern void AlterForeignServerOwner_oid(Oid, Oid newOwnerId); -extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId); +extern Oid AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId); extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId); -extern void CreateForeignDataWrapper(CreateFdwStmt *stmt); -extern void AlterForeignDataWrapper(AlterFdwStmt *stmt); +extern Oid CreateForeignDataWrapper(CreateFdwStmt *stmt); +extern Oid AlterForeignDataWrapper(AlterFdwStmt *stmt); extern void RemoveForeignDataWrapperById(Oid fdwId); -extern void CreateForeignServer(CreateForeignServerStmt *stmt); -extern void AlterForeignServer(AlterForeignServerStmt *stmt); +extern Oid CreateForeignServer(CreateForeignServerStmt *stmt); +extern Oid AlterForeignServer(AlterForeignServerStmt *stmt); extern void RemoveForeignServerById(Oid srvId); -extern void CreateUserMapping(CreateUserMappingStmt *stmt); -extern void AlterUserMapping(AlterUserMappingStmt *stmt); -extern void RemoveUserMapping(DropUserMappingStmt *stmt); +extern Oid CreateUserMapping(CreateUserMappingStmt *stmt); +extern Oid AlterUserMapping(AlterUserMappingStmt *stmt); +extern Oid RemoveUserMapping(DropUserMappingStmt *stmt); extern void RemoveUserMappingById(Oid umId); extern void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid); extern Datum transformGenericOptions(Oid catalogId, @@ -173,6 +134,7 @@ extern Datum transformGenericOptions(Oid catalogId, extern char *defGetString(DefElem *def); extern double defGetNumeric(DefElem *def); extern bool defGetBoolean(DefElem *def); +extern int32 defGetInt32(DefElem *def); extern int64 defGetInt64(DefElem *def); extern List *defGetQualifiedName(DefElem *def); extern TypeName *defGetTypeName(DefElem *def); diff --git a/src/include/commands/discard.h b/src/include/commands/discard.h index 450f04d4ef..1412aa2815 100644 --- a/src/include/commands/discard.h +++ b/src/include/commands/discard.h @@ -4,7 +4,7 @@ * prototypes for discard.c. * * - * Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/commands/discard.h * diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h new file mode 100644 index 0000000000..0233f4c483 --- /dev/null +++ b/src/include/commands/event_trigger.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * event_trigger.h + * Declarations for command trigger handling. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/event_trigger.h + * + *------------------------------------------------------------------------- + */ +#ifndef EVENT_TRIGGER_H +#define EVENT_TRIGGER_H + +#include "catalog/dependency.h" +#include "catalog/objectaddress.h" +#include "catalog/pg_event_trigger.h" +#include "nodes/parsenodes.h" + +typedef struct EventTriggerData +{ + NodeTag type; + const char *event; /* event name */ + Node *parsetree; /* parse tree */ + const char *tag; /* command tag */ +} EventTriggerData; + +/* + * EventTriggerData is the node type that is passed as fmgr "context" info + * when a function is called by the event trigger manager. + */ +#define CALLED_AS_EVENT_TRIGGER(fcinfo) \ + ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) + +extern Oid CreateEventTrigger(CreateEventTrigStmt *stmt); +extern void RemoveEventTriggerById(Oid ctrigOid); +extern Oid get_event_trigger_oid(const char *trigname, bool missing_ok); + +extern Oid AlterEventTrigger(AlterEventTrigStmt *stmt); +extern Oid AlterEventTriggerOwner(const char *name, Oid newOwnerId); +extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId); + +extern bool EventTriggerSupportsObjectType(ObjectType obtype); +extern bool EventTriggerSupportsObjectClass(ObjectClass objclass); +extern void EventTriggerDDLCommandStart(Node *parsetree); +extern void EventTriggerDDLCommandEnd(Node *parsetree); +extern void EventTriggerSQLDrop(Node *parsetree); + +extern bool EventTriggerBeginCompleteQuery(void); +extern void EventTriggerEndCompleteQuery(void); +extern bool trackDroppedObjectsNeeded(void); +extern void EventTriggerSQLDropAddObject(ObjectAddress *object); + +#endif /* EVENT_TRIGGER_H */ diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h index 54cdbb0205..7fa17ab568 100644 --- a/src/include/commands/explain.h +++ b/src/include/commands/explain.h @@ -3,7 +3,7 @@ * explain.h * prototypes for explain.c * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/commands/explain.h @@ -14,6 +14,7 @@ #define EXPLAIN_H #include "executor/executor.h" +#include "lib/stringinfo.h" typedef enum ExplainFormat { @@ -40,6 +41,7 @@ typedef struct ExplainState /* other states */ PlannedStmt *pstmt; /* top of plan */ List *rtable; /* range table */ + List *rtable_names; /* alias names for RTEs */ int indent; /* current indentation level */ List *grouping_stack; /* format-specific grouping state */ } ExplainState; @@ -69,10 +71,11 @@ extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into, const char *queryString, ParamListInfo params); extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, - ExplainState *es, - const char *queryString, ParamListInfo params); + ExplainState *es, const char *queryString, + ParamListInfo params, const instr_time *planduration); extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc); extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc); diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h index 7fc8a927d3..2cf784b455 100644 --- a/src/include/commands/extension.h +++ b/src/include/commands/extension.h @@ -4,7 +4,7 @@ * Extension management commands (create/drop extension). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/extension.h @@ -27,7 +27,7 @@ extern bool creating_extension; extern Oid CurrentExtensionObject; -extern void CreateExtension(CreateExtensionStmt *stmt); +extern Oid CreateExtension(CreateExtensionStmt *stmt); extern void RemoveExtensionById(Oid extId); @@ -36,13 +36,15 @@ extern Oid InsertExtensionTuple(const char *extName, Oid extOwner, Datum extConfig, Datum extCondition, List *requiredExtensions); -extern void ExecAlterExtensionStmt(AlterExtensionStmt *stmt); +extern Oid ExecAlterExtensionStmt(AlterExtensionStmt *stmt); -extern void ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt); +extern Oid ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt); extern Oid get_extension_oid(const char *extname, bool missing_ok); extern char *get_extension_name(Oid ext_oid); -extern void AlterExtensionNamespace(List *names, const char *newschema); +extern Oid AlterExtensionNamespace(List *names, const char *newschema); + +extern void AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId); #endif /* EXTENSION_H */ diff --git a/src/include/commands/lockcmds.h b/src/include/commands/lockcmds.h index 804d345a81..3c43228e81 100644 --- a/src/include/commands/lockcmds.h +++ b/src/include/commands/lockcmds.h @@ -4,7 +4,7 @@ * prototypes for lockcmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/lockcmds.h diff --git a/src/include/commands/matview.h b/src/include/commands/matview.h new file mode 100644 index 0000000000..476b285078 --- /dev/null +++ b/src/include/commands/matview.h @@ -0,0 +1,32 @@ +/*------------------------------------------------------------------------- + * + * matview.h + * prototypes for matview.c. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/matview.h + * + *------------------------------------------------------------------------- + */ +#ifndef MATVIEW_H +#define MATVIEW_H + +#include "nodes/params.h" +#include "nodes/parsenodes.h" +#include "tcop/dest.h" +#include "utils/relcache.h" + + +extern void SetMatViewPopulatedState(Relation relation, bool newstate); + +extern void ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, + ParamListInfo params, char *completionTag); + +extern DestReceiver *CreateTransientRelDestReceiver(Oid oid); + +extern bool MatViewIncrementalMaintenanceIsEnabled(void); + +#endif /* MATVIEW_H */ diff --git a/src/include/commands/portalcmds.h b/src/include/commands/portalcmds.h index 2353ffb317..6627de1262 100644 --- a/src/include/commands/portalcmds.h +++ b/src/include/commands/portalcmds.h @@ -4,7 +4,7 @@ * prototypes for portalcmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/portalcmds.h diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h index 222734b7aa..3d7b068047 100644 --- a/src/include/commands/prepare.h +++ b/src/include/commands/prepare.h @@ -4,7 +4,7 @@ * PREPARE, EXECUTE and DEALLOCATE commands, and prepared-stmt storage * * - * Copyright (c) 2002-2012, PostgreSQL Global Development Group + * Copyright (c) 2002-2014, PostgreSQL Global Development Group * * src/include/commands/prepare.h * @@ -14,6 +14,7 @@ #define PREPARE_H #include "commands/explain.h" +#include "datatype/timestamp.h" #include "utils/plancache.h" /* diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h index 17d0972419..f43c321ce2 100644 --- a/src/include/commands/proclang.h +++ b/src/include/commands/proclang.h @@ -14,11 +14,8 @@ #include "nodes/parsenodes.h" -extern void CreateProceduralLanguage(CreatePLangStmt *stmt); +extern Oid CreateProceduralLanguage(CreatePLangStmt *stmt); extern void DropProceduralLanguageById(Oid langOid); -extern void RenameLanguage(const char *oldname, const char *newname); -extern void AlterLanguageOwner(const char *name, Oid newOwnerId); -extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId); extern bool PLTemplateExists(const char *languageName); extern Oid get_language_oid(const char *langname, bool missing_ok); diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h index cb19598cb5..134e88c712 100644 --- a/src/include/commands/schemacmds.h +++ b/src/include/commands/schemacmds.h @@ -4,7 +4,7 @@ * prototypes for schemacmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/schemacmds.h @@ -18,16 +18,16 @@ #include "nodes/parsenodes.h" #ifdef PGXC -extern void CreateSchemaCommand(CreateSchemaStmt *parsetree, +extern Oid CreateSchemaCommand(CreateSchemaStmt *parsetree, const char *queryString, bool is_top_level); #else -extern void CreateSchemaCommand(CreateSchemaStmt *parsetree, +extern Oid CreateSchemaCommand(CreateSchemaStmt *parsetree, const char *queryString); #endif extern void RemoveSchemaById(Oid schemaOid); -extern void RenameSchema(const char *oldname, const char *newname); -extern void AlterSchemaOwner(const char *name, Oid newOwnerId); +extern Oid RenameSchema(const char *oldname, const char *newname); +extern Oid AlterSchemaOwner(const char *name, Oid newOwnerId); extern void AlterSchemaOwner_oid(Oid schemaOid, Oid newOwnerId); #endif /* SCHEMACMDS_H */ diff --git a/src/include/commands/seclabel.h b/src/include/commands/seclabel.h index 94b3c39cc1..ad9fce119f 100644 --- a/src/include/commands/seclabel.h +++ b/src/include/commands/seclabel.h @@ -3,7 +3,7 @@ * * Prototypes for functions in commands/seclabel.c * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ #ifndef SECLABEL_H @@ -24,7 +24,7 @@ extern void DeleteSharedSecurityLabel(Oid objectId, Oid classId); /* * Statement and ESP hook support */ -extern void ExecSecLabelStmt(SecLabelStmt *stmt); +extern Oid ExecSecLabelStmt(SecLabelStmt *stmt); typedef void (*check_object_relabel_type) (const ObjectAddress *object, const char *seclabel); diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index a917a06a87..fff8f61264 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -8,7 +8,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/sequence.h @@ -81,9 +81,10 @@ extern Datum lastval(PG_FUNCTION_ARGS); extern Datum pg_sequence_parameters(PG_FUNCTION_ARGS); -extern void DefineSequence(CreateSeqStmt *stmt); -extern void AlterSequence(AlterSeqStmt *stmt); +extern Oid DefineSequence(CreateSeqStmt *stmt); +extern Oid AlterSequence(AlterSeqStmt *stmt); extern void ResetSequence(Oid seq_relid); +extern void ResetSequenceCaches(void); extern void seq_redo(XLogRecPtr lsn, XLogRecord *rptr); extern void seq_desc(StringInfo buf, uint8 xl_info, char *rec); diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index e262a1d8d3..15f487e757 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -4,7 +4,7 @@ * prototypes for tablecmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/tablecmds.h @@ -15,6 +15,7 @@ #define TABLECMDS_H #include "access/htup.h" +#include "catalog/dependency.h" #include "nodes/parsenodes.h" #include "storage/lock.h" #include "utils/relcache.h" @@ -34,11 +35,15 @@ extern void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, L extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); -extern void AlterTableNamespace(AlterObjectSchemaStmt *stmt); +extern Oid AlterTableNamespace(AlterObjectSchemaStmt *stmt); + +extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, + Oid nspOid, ObjectAddresses *objsMoved); extern void AlterRelationNamespaceInternal(Relation classRel, Oid relOid, Oid oldNspOid, Oid newNspOid, - bool hasDependEntry); + bool hasDependEntry, + ObjectAddresses *objsMoved); extern void CheckTableNotInUse(Relation rel, const char *stmt); @@ -46,14 +51,14 @@ extern void ExecuteTruncate(TruncateStmt *stmt); extern void SetRelationHasSubclass(Oid relationId, bool relhassubclass); -extern void renameatt(RenameStmt *stmt); +extern Oid renameatt(RenameStmt *stmt); -extern void RenameConstraint(RenameStmt *stmt); +extern Oid RenameConstraint(RenameStmt *stmt); -extern void RenameRelation(RenameStmt *stmt); +extern Oid RenameRelation(RenameStmt *stmt); extern void RenameRelationInternal(Oid myrelid, - const char *newrelname); + const char *newrelname, bool is_internal); extern void find_composite_type_dependencies(Oid typeOid, Relation origRelation, @@ -61,10 +66,6 @@ extern void find_composite_type_dependencies(Oid typeOid, extern void check_of_type(HeapTuple typetuple); -extern AttrNumber *varattnos_map(TupleDesc olddesc, TupleDesc newdesc); -extern AttrNumber *varattnos_map_schema(TupleDesc old, List *schema); -extern void change_varattnos_of_a_node(Node *node, const AttrNumber *newattno); - extern void register_on_commit_action(Oid relid, OnCommitAction action); extern void remove_on_commit_action(Oid relid); @@ -85,4 +86,6 @@ extern void DropTableThrowErrorExternal(RangeVar *relation, extern void RangeVarCallbackOwnsTable(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); +extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, + Oid relId, Oid oldRelId, void *noCatalogs); #endif /* TABLECMDS_H */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index fe8b6a5dc2..1603f677a7 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -4,7 +4,7 @@ * Tablespace management commands (create/drop tablespace). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/tablespace.h @@ -39,11 +39,11 @@ typedef struct TableSpaceOpts float8 seq_page_cost; } TableSpaceOpts; -extern void CreateTableSpace(CreateTableSpaceStmt *stmt); +extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt); extern void DropTableSpace(DropTableSpaceStmt *stmt); -extern void RenameTableSpace(const char *oldname, const char *newname); -extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId); -extern void AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); +extern Oid RenameTableSpace(const char *oldname, const char *newname); +extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); +extern Oid AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 1f7ba47466..2239a32d52 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -3,7 +3,7 @@ * trigger.h * Declarations for trigger handling. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/trigger.h @@ -109,13 +109,13 @@ extern PGDLLIMPORT int SessionReplicationRole; #define TRIGGER_DISABLED 'D' extern Oid CreateTrigger(CreateTrigStmt *stmt, const char *queryString, - Oid constraintOid, Oid indexOid, + Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, bool isInternal); extern void RemoveTriggerById(Oid trigOid); extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); -extern void renametrig(RenameStmt *stmt); +extern Oid renametrig(RenameStmt *stmt); extern void EnableDisableTrigger(Relation rel, const char *tgname, char fires_when, bool skip_system); @@ -147,10 +147,12 @@ extern void ExecASDeleteTriggers(EState *estate, extern bool ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, - ItemPointer tupleid); + ItemPointer tupleid, + HeapTuple fdw_trigtuple); extern void ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, - ItemPointer tupleid); + ItemPointer tupleid, + HeapTuple fdw_trigtuple); extern bool ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, HeapTuple trigtuple); @@ -162,10 +164,12 @@ extern TupleTableSlot *ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, + HeapTuple fdw_trigtuple, TupleTableSlot *slot); extern void ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ItemPointer tupleid, + HeapTuple fdw_trigtuple, HeapTuple newtuple, List *recheckIndexes); extern TupleTableSlot *ExecIRUpdateTriggers(EState *estate, @@ -194,10 +198,10 @@ extern bool AfterTriggerPendingOnRel(Oid relid); /* * in utils/adt/ri_triggers.c */ -extern bool RI_FKey_keyequal_upd_pk(Trigger *trigger, Relation pk_rel, - HeapTuple old_row, HeapTuple new_row); -extern bool RI_FKey_keyequal_upd_fk(Trigger *trigger, Relation fk_rel, - HeapTuple old_row, HeapTuple new_row); +extern bool RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, + HeapTuple old_row, HeapTuple new_row); +extern bool RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, + HeapTuple old_row, HeapTuple new_row); extern bool RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel); diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index b72cfc4fd9..792c17838d 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -4,7 +4,7 @@ * prototypes for typecmds.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/typecmds.h @@ -15,39 +15,41 @@ #define TYPECMDS_H #include "access/htup.h" +#include "catalog/dependency.h" #include "nodes/parsenodes.h" #define DEFAULT_TYPDELIM ',' -extern void DefineType(List *names, List *parameters); +extern Oid DefineType(List *names, List *parameters); extern void RemoveTypeById(Oid typeOid); -extern void DefineDomain(CreateDomainStmt *stmt); -extern void DefineEnum(CreateEnumStmt *stmt); -extern void DefineRange(CreateRangeStmt *stmt); -extern void AlterEnum(AlterEnumStmt *stmt); +extern Oid DefineDomain(CreateDomainStmt *stmt); +extern Oid DefineEnum(CreateEnumStmt *stmt); +extern Oid DefineRange(CreateRangeStmt *stmt); +extern Oid AlterEnum(AlterEnumStmt *stmt, bool isTopLevel); extern Oid DefineCompositeType(RangeVar *typevar, List *coldeflist); extern Oid AssignTypeArrayOid(void); -extern void AlterDomainDefault(List *names, Node *defaultRaw); -extern void AlterDomainNotNull(List *names, bool notNull); -extern void AlterDomainAddConstraint(List *names, Node *constr); -extern void AlterDomainValidateConstraint(List *names, char *constrName); -extern void AlterDomainDropConstraint(List *names, const char *constrName, +extern Oid AlterDomainDefault(List *names, Node *defaultRaw); +extern Oid AlterDomainNotNull(List *names, bool notNull); +extern Oid AlterDomainAddConstraint(List *names, Node *constr); +extern Oid AlterDomainValidateConstraint(List *names, char *constrName); +extern Oid AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok); extern void checkDomainOwner(HeapTuple tup); extern List *GetDomainConstraints(Oid typeOid); -extern void RenameType(RenameStmt *stmt); -extern void AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype); +extern Oid RenameType(RenameStmt *stmt); +extern Oid AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype); extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, bool hasDependEntry); -extern void AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype); -extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid); +extern Oid AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype); +extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved); extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, bool isImplicitArray, - bool errorOnTableType); + bool errorOnTableType, + ObjectAddresses *objsMoved); #endif /* TYPECMDS_H */ diff --git a/src/include/commands/user.h b/src/include/commands/user.h index 476654abf6..d76685182f 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -22,13 +22,14 @@ typedef void (*check_password_hook_type) (const char *username, const char *pass extern PGDLLIMPORT check_password_hook_type check_password_hook; -extern void CreateRole(CreateRoleStmt *stmt); -extern void AlterRole(AlterRoleStmt *stmt); -extern void AlterRoleSet(AlterRoleSetStmt *stmt); +extern Oid CreateRole(CreateRoleStmt *stmt); +extern Oid AlterRole(AlterRoleStmt *stmt); +extern Oid AlterRoleSet(AlterRoleSetStmt *stmt); extern void DropRole(DropRoleStmt *stmt); extern void GrantRole(GrantRoleStmt *stmt); -extern void RenameRole(const char *oldname, const char *newname); +extern Oid RenameRole(const char *oldname, const char *newname); extern void DropOwnedObjects(DropOwnedStmt *stmt); extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt); +extern List *roleNamesToIds(List *memberNames); #endif /* USER_H */ diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 7d16edaac5..fd50719680 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/vacuum.h @@ -30,12 +30,12 @@ /*---------- * ANALYZE builds one of these structs for each attribute (column) that is - * to be analyzed. The struct and subsidiary data are in anl_context, + * to be analyzed. The struct and subsidiary data are in anl_context, * so they live until the end of the ANALYZE operation. * * The type-specific typanalyze function is passed a pointer to this struct * and must return TRUE to continue analysis, FALSE to skip analysis of this - * column. In the TRUE case it must set the compute_stats and minrows fields, + * column. In the TRUE case it must set the compute_stats and minrows fields, * and can optionally set extra_data to pass additional info to compute_stats. * minrows is its request for the minimum number of sample rows to be gathered * (but note this request might not be honored, eg if there are fewer rows @@ -78,7 +78,7 @@ typedef struct VacAttrStats * type-specific typanalyze function. * * Note: do not assume that the data being analyzed has the same datatype - * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is + * shown in attr, ie do not trust attr->atttypid, attlen, etc. This is * because some index opclasses store a different type than the underlying * column/expression. Instead use attrtypid, attrtypmod, and attrtype for * information about the datatype being fed to the typanalyze function. @@ -103,9 +103,9 @@ typedef struct VacAttrStats */ bool stats_valid; float4 stanullfrac; /* fraction of entries that are NULL */ - int4 stawidth; /* average width of column values */ + int32 stawidth; /* average width of column values */ float4 stadistinct; /* # distinct values */ - int2 stakind[STATISTIC_NUM_SLOTS]; + int16 stakind[STATISTIC_NUM_SLOTS]; Oid staop[STATISTIC_NUM_SLOTS]; int numnumbers[STATISTIC_NUM_SLOTS]; float4 *stanumbers[STATISTIC_NUM_SLOTS]; @@ -119,7 +119,7 @@ typedef struct VacAttrStats * elements. It should then overwrite these fields. */ Oid statypid[STATISTIC_NUM_SLOTS]; - int2 statyplen[STATISTIC_NUM_SLOTS]; + int16 statyplen[STATISTIC_NUM_SLOTS]; bool statypbyval[STATISTIC_NUM_SLOTS]; char statypalign[STATISTIC_NUM_SLOTS]; @@ -141,6 +141,8 @@ extern PGDLLIMPORT int default_statistics_target; /* PGDLLIMPORT for * PostGIS */ extern int vacuum_freeze_min_age; extern int vacuum_freeze_table_age; +extern int vacuum_multixact_freeze_min_age; +extern int vacuum_multixact_freeze_table_age; /* in commands/vacuum.c */ @@ -158,12 +160,17 @@ extern void vac_update_relstats(Relation relation, double num_tuples, BlockNumber num_all_visible_pages, bool hasindex, - TransactionId frozenxid); -extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age, - bool sharedRel, + TransactionId frozenxid, + MultiXactId minmulti); +extern void vacuum_set_xid_limits(Relation rel, + int freeze_min_age, int freeze_table_age, + int multixact_freeze_min_age, + int multixact_freeze_table_age, TransactionId *oldestXmin, TransactionId *freezeLimit, - TransactionId *freezeTableLimit); + TransactionId *xidFullScanLimit, + MultiXactId *multiXactCutoff, + MultiXactId *mxactFullScanLimit); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(void); #ifdef XCP diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h index 14540a7561..e0194e3fd9 100644 --- a/src/include/commands/variable.h +++ b/src/include/commands/variable.h @@ -7,7 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/variable.h diff --git a/src/include/commands/view.h b/src/include/commands/view.h index efebf95b7a..a77ccc56f7 100644 --- a/src/include/commands/view.h +++ b/src/include/commands/view.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/view.h @@ -16,6 +16,10 @@ #include "nodes/parsenodes.h" -extern void DefineView(ViewStmt *stmt, const char *queryString); +extern void validateWithCheckOption(char *value); + +extern Oid DefineView(ViewStmt *stmt, const char *queryString); + +extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace); #endif /* VIEW_H */ diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h new file mode 100644 index 0000000000..61c1b6fd2d --- /dev/null +++ b/src/include/common/fe_memutils.h @@ -0,0 +1,34 @@ +/* + * fe_memutils.h + * memory management support for frontend code + * + * Copyright (c) 2003-2014, PostgreSQL Global Development Group + * + * src/include/common/fe_memutils.h + */ +#ifndef FE_MEMUTILS_H +#define FE_MEMUTILS_H + +/* "Safe" memory allocation functions --- these exit(1) on failure */ +extern char *pg_strdup(const char *in); +extern void *pg_malloc(size_t size); +extern void *pg_malloc0(size_t size); +extern void *pg_realloc(void *pointer, size_t size); +extern void pg_free(void *pointer); + +/* Equivalent functions, deliberately named the same as backend functions */ +extern char *pstrdup(const char *in); +extern void *palloc(Size size); +extern void *palloc0(Size size); +extern void *repalloc(void *pointer, Size size); +extern void pfree(void *pointer); + +/* sprintf into a palloc'd buffer --- these are in psprintf.c */ +extern char * +psprintf(const char *fmt,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); +extern size_t +pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0))); + +#endif /* FE_MEMUTILS_H */ diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h new file mode 100644 index 0000000000..bd56d47660 --- /dev/null +++ b/src/include/common/relpath.h @@ -0,0 +1,79 @@ +/*------------------------------------------------------------------------- + * + * relpath.h + * Declarations for GetRelationPath() and friends + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/relpath.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELPATH_H +#define RELPATH_H + +/* + * Stuff for fork names. + * + * The physical storage of a relation consists of one or more forks. + * The main fork is always created, but in addition to that there can be + * additional forks for storing various metadata. ForkNumber is used when + * we need to refer to a specific fork in a relation. + */ +typedef enum ForkNumber +{ + InvalidForkNumber = -1, + MAIN_FORKNUM = 0, + FSM_FORKNUM, + VISIBILITYMAP_FORKNUM, + INIT_FORKNUM + + /* + * NOTE: if you add a new fork, change MAX_FORKNUM and possibly + * FORKNAMECHARS below, and update the forkNames array in + * src/common/relpath.c + */ +} ForkNumber; + +#define MAX_FORKNUM INIT_FORKNUM + +#define FORKNAMECHARS 4 /* max chars for a fork name */ + +extern const char *const forkNames[]; + +extern ForkNumber forkname_to_number(const char *forkName); +extern int forkname_chars(const char *str, ForkNumber *fork); + +/* + * Stuff for computing filesystem pathnames for relations. + */ +extern char *GetDatabasePath(Oid dbNode, Oid spcNode); + +extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode, + int backendId, ForkNumber forkNumber); + +/* + * Wrapper macros for GetRelationPath. Beware of multiple + * evaluation of the RelFileNode or RelFileNodeBackend argument! + */ + +/* First argument is a RelFileNode */ +#define relpathbackend(rnode, backend, forknum) \ + GetRelationPath((rnode).dbNode, (rnode).spcNode, (rnode).relNode, \ + backend, forknum) + +/* First argument is a RelFileNode */ +#define relpathperm(rnode, forknum) \ + relpathbackend(rnode, InvalidBackendId, forknum) + +/* First argument is a RelFileNodeBackend */ +#ifdef XCP +#define relpath(rnode, forknum) \ + relpathbackend((rnode).node, InvalidBackendId, (forknum)) +#else +#define relpath(rnode, forknum) \ + relpathbackend((rnode).node, (rnode).backend, forknum) +#endif + +#endif /* RELPATH_H */ diff --git a/src/include/common/username.h b/src/include/common/username.h new file mode 100644 index 0000000000..115d1ed450 --- /dev/null +++ b/src/include/common/username.h @@ -0,0 +1,15 @@ +/* + * username.h + * lookup effective username + * + * Copyright (c) 2003-2014, PostgreSQL Global Development Group + * + * src/include/common/username.h + */ +#ifndef USERNAME_H +#define USERNAME_H + +extern const char *get_user_name(char **errstr); +extern const char *get_user_name_or_exit(const char *progname); + +#endif /* USERNAME_H */ diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h index 706b4480b3..a33821fa61 100644 --- a/src/include/datatype/timestamp.h +++ b/src/include/datatype/timestamp.h @@ -5,7 +5,7 @@ * * Note: this file must be includable in both frontend and backend contexts. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/datatype/timestamp.h @@ -83,7 +83,7 @@ typedef struct * DAYS_PER_MONTH is very imprecise. The more accurate value is * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only * return an integral number of days, but someday perhaps we should - * also return a 'time' value to be used as well. ISO 8601 suggests + * also return a 'time' value to be used as well. ISO 8601 suggests * 30 days. */ #define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ @@ -109,7 +109,7 @@ typedef struct * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. * Currently, the record holders for wackiest offsets in actual use are zones * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 - * until 1867. If we were to reject such values we would fail to dump and + * until 1867. If we were to reject such values we would fail to dump and * restore old timestamptz values with these zone settings. */ #define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ diff --git a/src/include/executor/execdebug.h b/src/include/executor/execdebug.h index e042a6c867..fc5332c47e 100644 --- a/src/include/executor/execdebug.h +++ b/src/include/executor/execdebug.h @@ -7,7 +7,7 @@ * for debug printouts, because that's more flexible than printf(). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/execdebug.h diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h index b6c2400ffd..6937a681da 100644 --- a/src/include/executor/execdesc.h +++ b/src/include/executor/execdesc.h @@ -10,7 +10,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/execdesc.h diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 29e8edcc55..6fe5fe9941 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/executor.h @@ -41,7 +41,7 @@ * REWIND indicates that the plan node should try to efficiently support * rescans without parameter changes. (Nodes must support ExecReScan calls * in any case, but if this flag was not given, they are at liberty to do it - * through complete recalculation. Note that a parameter change forces a + * through complete recalculation. Note that a parameter change forces a * full recalculation in any case.) * * BACKWARD indicates that the plan node must respect the es_direction flag. @@ -56,7 +56,7 @@ * is responsible for there being a trigger context for them to be queued in. * * WITH/WITHOUT_OIDS tell the executor to emit tuples with or without space - * for OIDs, respectively. These are currently used only for CREATE TABLE AS. + * for OIDs, respectively. These are currently used only for CREATE TABLE AS. * If neither is set, the plan may or may not produce tuples including OIDs. */ #define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */ @@ -66,9 +66,10 @@ #define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */ #define EXEC_FLAG_WITH_OIDS 0x0020 /* force OIDs in returned tuples */ #define EXEC_FLAG_WITHOUT_OIDS 0x0040 /* force no OIDs in returned tuples */ +#define EXEC_FLAG_WITH_NO_DATA 0x0080 /* rel scannability doesn't matter */ #ifdef XCP /* distributed executor may never execute the plan on this node */ -#define EXEC_FLAG_SUBPLAN 0x0080 +#define EXEC_FLAG_SUBPLAN 0x0100 #endif @@ -203,10 +204,12 @@ extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid); extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids); extern void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate); +extern void ExecWithCheckOptions(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate); extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti); extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist); extern TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, - Relation relation, Index rti, + Relation relation, Index rti, int lockmode, ItemPointer tid, TransactionId priorXmax); extern HeapTuple EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, ItemPointer tid, TransactionId priorXmax); @@ -356,7 +359,7 @@ extern void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate); extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid); -extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid); +extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags); extern void ExecCloseScanRelation(Relation scanrel); extern void ExecOpenIndices(ResultRelInfo *resultRelInfo); diff --git a/src/include/executor/functions.h b/src/include/executor/functions.h index 6201f92622..00f309779c 100644 --- a/src/include/executor/functions.h +++ b/src/include/executor/functions.h @@ -4,7 +4,7 @@ * Declarations for execution of SQL-language functions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/functions.h diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h index 8f2dc9d547..3beae403ce 100644 --- a/src/include/executor/hashjoin.h +++ b/src/include/executor/hashjoin.h @@ -4,7 +4,7 @@ * internal structures for hash joins * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/hashjoin.h @@ -41,7 +41,7 @@ * If nbatch > 1 then tuples that don't belong in first batch get saved * into inner-batch temp files. The same statements apply for the * first scan of the outer relation, except we write tuples to outer-batch - * temp files. After finishing the first scan, we do the following for + * temp files. After finishing the first scan, we do the following for * each remaining batch: * 1. Read tuples from inner batch file, load into hash buckets. * 2. Read tuples from outer batch file, match to hash buckets and output. @@ -132,7 +132,7 @@ typedef struct HashJoinTableData /* * These arrays are allocated for the life of the hash join, but only if - * nbatch > 1. A file is opened only when we first write a tuple into it + * nbatch > 1. A file is opened only when we first write a tuple into it * (otherwise its pointer remains NULL). Note that the zero'th array * elements never get used, since we will process rather than dump out any * tuples of batch zero. diff --git a/src/include/executor/instrument.h b/src/include/executor/instrument.h index e6dd03c2d7..8ec1033ca9 100644 --- a/src/include/executor/instrument.h +++ b/src/include/executor/instrument.h @@ -4,7 +4,7 @@ * definitions for run-time statistics collection * * - * Copyright (c) 2001-2012, PostgreSQL Global Development Group + * Copyright (c) 2001-2014, PostgreSQL Global Development Group * * src/include/executor/instrument.h * diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h index edf3d6371c..d49b3ede44 100644 --- a/src/include/executor/nodeAgg.h +++ b/src/include/executor/nodeAgg.h @@ -4,7 +4,7 @@ * prototypes for nodeAgg.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeAgg.h diff --git a/src/include/executor/nodeAppend.h b/src/include/executor/nodeAppend.h index b0073759c7..2dc1ea3561 100644 --- a/src/include/executor/nodeAppend.h +++ b/src/include/executor/nodeAppend.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeAppend.h diff --git a/src/include/executor/nodeBitmapAnd.h b/src/include/executor/nodeBitmapAnd.h index 9b810b7d80..12ef85d387 100644 --- a/src/include/executor/nodeBitmapAnd.h +++ b/src/include/executor/nodeBitmapAnd.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapAnd.h diff --git a/src/include/executor/nodeBitmapHeapscan.h b/src/include/executor/nodeBitmapHeapscan.h index df057a32a7..c37e1a041f 100644 --- a/src/include/executor/nodeBitmapHeapscan.h +++ b/src/include/executor/nodeBitmapHeapscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapHeapscan.h diff --git a/src/include/executor/nodeBitmapIndexscan.h b/src/include/executor/nodeBitmapIndexscan.h index 8f0d59ff20..9572f7db41 100644 --- a/src/include/executor/nodeBitmapIndexscan.h +++ b/src/include/executor/nodeBitmapIndexscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapIndexscan.h diff --git a/src/include/executor/nodeBitmapOr.h b/src/include/executor/nodeBitmapOr.h index 97eea962f3..605103a698 100644 --- a/src/include/executor/nodeBitmapOr.h +++ b/src/include/executor/nodeBitmapOr.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapOr.h diff --git a/src/include/executor/nodeCtescan.h b/src/include/executor/nodeCtescan.h index 828e0db4a8..18c4d972e0 100644 --- a/src/include/executor/nodeCtescan.h +++ b/src/include/executor/nodeCtescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeCtescan.h diff --git a/src/include/executor/nodeForeignscan.h b/src/include/executor/nodeForeignscan.h index 11acc9f77c..52b2f8955a 100644 --- a/src/include/executor/nodeForeignscan.h +++ b/src/include/executor/nodeForeignscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeForeignscan.h diff --git a/src/include/executor/nodeFunctionscan.h b/src/include/executor/nodeFunctionscan.h index 12d3f95422..a624f4b7ee 100644 --- a/src/include/executor/nodeFunctionscan.h +++ b/src/include/executor/nodeFunctionscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeFunctionscan.h diff --git a/src/include/executor/nodeGroup.h b/src/include/executor/nodeGroup.h index 1da39854ca..515d251bbe 100644 --- a/src/include/executor/nodeGroup.h +++ b/src/include/executor/nodeGroup.h @@ -4,7 +4,7 @@ * prototypes for nodeGroup.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeGroup.h diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h index b519618f91..75be5bdc33 100644 --- a/src/include/executor/nodeHash.h +++ b/src/include/executor/nodeHash.h @@ -4,7 +4,7 @@ * prototypes for nodeHash.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeHash.h diff --git a/src/include/executor/nodeHashjoin.h b/src/include/executor/nodeHashjoin.h index c4708347df..a2115c2e26 100644 --- a/src/include/executor/nodeHashjoin.h +++ b/src/include/executor/nodeHashjoin.h @@ -4,7 +4,7 @@ * prototypes for nodeHashjoin.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeHashjoin.h diff --git a/src/include/executor/nodeIndexonlyscan.h b/src/include/executor/nodeIndexonlyscan.h index fac033e3fe..f9c902aea9 100644 --- a/src/include/executor/nodeIndexonlyscan.h +++ b/src/include/executor/nodeIndexonlyscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeIndexonlyscan.h diff --git a/src/include/executor/nodeIndexscan.h b/src/include/executor/nodeIndexscan.h index 4502705c07..7db552cf33 100644 --- a/src/include/executor/nodeIndexscan.h +++ b/src/include/executor/nodeIndexscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeIndexscan.h diff --git a/src/include/executor/nodeLimit.h b/src/include/executor/nodeLimit.h index be9adc59d4..0168fcbf56 100644 --- a/src/include/executor/nodeLimit.h +++ b/src/include/executor/nodeLimit.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeLimit.h diff --git a/src/include/executor/nodeLockRows.h b/src/include/executor/nodeLockRows.h index 0597e43180..86384774fe 100644 --- a/src/include/executor/nodeLockRows.h +++ b/src/include/executor/nodeLockRows.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeLockRows.h diff --git a/src/include/executor/nodeMaterial.h b/src/include/executor/nodeMaterial.h index a625625f02..e92c9afe08 100644 --- a/src/include/executor/nodeMaterial.h +++ b/src/include/executor/nodeMaterial.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMaterial.h diff --git a/src/include/executor/nodeMergeAppend.h b/src/include/executor/nodeMergeAppend.h index fb8d1a964e..087928c3fa 100644 --- a/src/include/executor/nodeMergeAppend.h +++ b/src/include/executor/nodeMergeAppend.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMergeAppend.h diff --git a/src/include/executor/nodeMergejoin.h b/src/include/executor/nodeMergejoin.h index 3db8e06180..cd8a650b61 100644 --- a/src/include/executor/nodeMergejoin.h +++ b/src/include/executor/nodeMergejoin.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMergejoin.h diff --git a/src/include/executor/nodeModifyTable.h b/src/include/executor/nodeModifyTable.h index 1acf80bef9..fa1c06bd64 100644 --- a/src/include/executor/nodeModifyTable.h +++ b/src/include/executor/nodeModifyTable.h @@ -3,7 +3,7 @@ * nodeModifyTable.h * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeModifyTable.h diff --git a/src/include/executor/nodeNestloop.h b/src/include/executor/nodeNestloop.h index 4d9bde60f1..b2068b0b8b 100644 --- a/src/include/executor/nodeNestloop.h +++ b/src/include/executor/nodeNestloop.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeNestloop.h diff --git a/src/include/executor/nodeRecursiveunion.h b/src/include/executor/nodeRecursiveunion.h index 20840ecc2e..5c8c7602df 100644 --- a/src/include/executor/nodeRecursiveunion.h +++ b/src/include/executor/nodeRecursiveunion.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeRecursiveunion.h diff --git a/src/include/executor/nodeResult.h b/src/include/executor/nodeResult.h index f46c2110f1..6482d168d4 100644 --- a/src/include/executor/nodeResult.h +++ b/src/include/executor/nodeResult.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeResult.h diff --git a/src/include/executor/nodeSeqscan.h b/src/include/executor/nodeSeqscan.h index 4044842ec8..86f99d8384 100644 --- a/src/include/executor/nodeSeqscan.h +++ b/src/include/executor/nodeSeqscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSeqscan.h diff --git a/src/include/executor/nodeSetOp.h b/src/include/executor/nodeSetOp.h index 1626a313ec..dfac49f786 100644 --- a/src/include/executor/nodeSetOp.h +++ b/src/include/executor/nodeSetOp.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSetOp.h diff --git a/src/include/executor/nodeSort.h b/src/include/executor/nodeSort.h index d1abf17c78..401c59fa3f 100644 --- a/src/include/executor/nodeSort.h +++ b/src/include/executor/nodeSort.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSort.h diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h index 3ef1e69d03..29ca8c0a78 100644 --- a/src/include/executor/nodeSubplan.h +++ b/src/include/executor/nodeSubplan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSubplan.h diff --git a/src/include/executor/nodeSubqueryscan.h b/src/include/executor/nodeSubqueryscan.h index b4a6d6ba65..e8cc8ed4af 100644 --- a/src/include/executor/nodeSubqueryscan.h +++ b/src/include/executor/nodeSubqueryscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSubqueryscan.h diff --git a/src/include/executor/nodeTidscan.h b/src/include/executor/nodeTidscan.h index 0f9403f453..813aab5d9f 100644 --- a/src/include/executor/nodeTidscan.h +++ b/src/include/executor/nodeTidscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeTidscan.h diff --git a/src/include/executor/nodeUnique.h b/src/include/executor/nodeUnique.h index 849c71ea80..fe3ca2b553 100644 --- a/src/include/executor/nodeUnique.h +++ b/src/include/executor/nodeUnique.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeUnique.h diff --git a/src/include/executor/nodeValuesscan.h b/src/include/executor/nodeValuesscan.h index 4edf0ea642..4864d1a9ac 100644 --- a/src/include/executor/nodeValuesscan.h +++ b/src/include/executor/nodeValuesscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeValuesscan.h diff --git a/src/include/executor/nodeWindowAgg.h b/src/include/executor/nodeWindowAgg.h index 7fe3872896..91f4bbc4eb 100644 --- a/src/include/executor/nodeWindowAgg.h +++ b/src/include/executor/nodeWindowAgg.h @@ -4,7 +4,7 @@ * prototypes for nodeWindowAgg.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeWindowAgg.h diff --git a/src/include/executor/nodeWorktablescan.h b/src/include/executor/nodeWorktablescan.h index 46e8824259..418ca0cf79 100644 --- a/src/include/executor/nodeWorktablescan.h +++ b/src/include/executor/nodeWorktablescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeWorktablescan.h diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 25676f596f..00cf8012e0 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -3,7 +3,7 @@ * spi.h * Server Programming Interface public declarations * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/spi.h @@ -13,6 +13,7 @@ #ifndef SPI_H #define SPI_H +#include "lib/ilist.h" #include "nodes/parsenodes.h" #include "utils/portal.h" @@ -24,6 +25,8 @@ typedef struct SPITupleTable uint32 free; /* # of free vals */ TupleDesc tupdesc; /* tuple descriptor */ HeapTuple *vals; /* tuples */ + slist_node next; /* link for internal bookkeeping */ + SubTransactionId subid; /* subxact in which tuptable was created */ } SPITupleTable; /* Plans are opaque structs for standard users of SPI */ @@ -103,6 +106,9 @@ extern bool SPI_is_cursor_plan(SPIPlanPtr plan); extern bool SPI_plan_is_valid(SPIPlanPtr plan); extern const char *SPI_result_code_string(int code); +extern List *SPI_plan_get_plan_sources(SPIPlanPtr plan); +extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan); + extern HeapTuple SPI_copytuple(HeapTuple tuple); extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc); extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h index 4fbb548af4..05fb73978a 100644 --- a/src/include/executor/spi_priv.h +++ b/src/include/executor/spi_priv.h @@ -3,7 +3,7 @@ * spi_priv.h * Server Programming Interface private declarations * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/spi_priv.h @@ -23,8 +23,10 @@ typedef struct /* current results */ uint32 processed; /* by Executor */ Oid lastoid; - SPITupleTable *tuptable; + SPITupleTable *tuptable; /* tuptable currently being built */ + /* resources of this execution context */ + slist_head tuptables; /* list of all live SPITupleTables */ MemoryContext procCxt; /* procedure context */ MemoryContext execCxt; /* executor context */ MemoryContext savedcxt; /* context of SPI_connect's caller */ @@ -48,7 +50,7 @@ typedef struct * adequate locks to prevent other backends from messing with the tables. * * For a saved plan, the plancxt is made a child of CacheMemoryContext - * since it should persist until explicitly destroyed. Likewise, the + * since it should persist until explicitly destroyed. Likewise, the * plancache entries will be under CacheMemoryContext since we tell * plancache.c to save them. We rely on plancache.c to keep the cache * entries up-to-date as needed in the face of invalidation events. @@ -59,6 +61,12 @@ typedef struct * while additional data such as argtypes and list cells is loose in the SPI * executor context. Such plans can be identified by having plancxt == NULL. * + * We can also have "one-shot" SPI plans (which are typically temporary, + * as described above). These are meant to be executed once and discarded, + * and various optimizations are made on the assumption of single use. + * Note in particular that the CachedPlanSources within such an SPI plan + * are not "complete" until execution. + * * Note: if the original query string contained only whitespace and comments, * the plancache_list will be NIL and so there is no place to store the * query string. We don't care about that, but we do care about the @@ -68,6 +76,7 @@ typedef struct _SPI_plan { int magic; /* should equal _SPI_PLAN_MAGIC */ bool saved; /* saved or unsaved plan? */ + bool oneshot; /* one-shot plan? */ List *plancache_list; /* one CachedPlanSource per parsetree */ MemoryContext plancxt; /* Context containing _SPI_plan and data */ int cursor_options; /* Cursor options used for planning */ diff --git a/src/include/executor/tstoreReceiver.h b/src/include/executor/tstoreReceiver.h index 6d94b09d84..06bb33a871 100644 --- a/src/include/executor/tstoreReceiver.h +++ b/src/include/executor/tstoreReceiver.h @@ -4,7 +4,7 @@ * prototypes for tstoreReceiver.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tstoreReceiver.h diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h index 693037d1e4..b98202dcbc 100644 --- a/src/include/executor/tuptable.h +++ b/src/include/executor/tuptable.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tuptable.h @@ -20,6 +20,7 @@ #define TUPTABLE_H #include "access/htup.h" +#include "access/tupdesc.h" #include "storage/buf.h" /*---------- @@ -38,7 +39,7 @@ * * A "minimal" tuple is handled similarly to a palloc'd regular tuple. * At present, minimal tuples never are stored in buffers, so there is no - * parallel to case 1. Note that a minimal tuple has no "system columns". + * parallel to case 1. Note that a minimal tuple has no "system columns". * (Actually, it could have an OID, but we have no need to access the OID.) * * A "virtual" tuple is an optimization used to minimize physical data @@ -48,7 +49,7 @@ * a lower plan node's output TupleTableSlot, or to a function result * constructed in a plan node's per-tuple econtext. It is the responsibility * of the generating plan node to be sure these resources are not released - * for as long as the virtual tuple needs to be valid. We only use virtual + * for as long as the virtual tuple needs to be valid. We only use virtual * tuples in the result slots of plan nodes --- tuples to be copied anywhere * else need to be "materialized" into physical tuples. Note also that a * virtual tuple does not have any "system columns". @@ -62,11 +63,11 @@ * payloads when this is the case. * * The Datum/isnull arrays of a TupleTableSlot serve double duty. When the - * slot contains a virtual tuple, they are the authoritative data. When the + * slot contains a virtual tuple, they are the authoritative data. When the * slot contains a physical tuple, the arrays contain data extracted from * the tuple. (In this state, any pass-by-reference Datums point into * the physical tuple.) The extracted information is built "lazily", - * ie, only as needed. This serves to avoid repeated extraction of data + * ie, only as needed. This serves to avoid repeated extraction of data * from the physical tuple. * * A TupleTableSlot can also be "empty", holding no valid data. This is @@ -93,7 +94,7 @@ * buffer page.) * * tts_nvalid indicates the number of valid columns in the tts_values/isnull - * arrays. When the slot is holding a "virtual" tuple this must be equal + * arrays. When the slot is holding a "virtual" tuple this must be equal * to the descriptor's natts. When the slot is holding a physical tuple * this is equal to the number of columns we have extracted (we always * extract columns from left to right, so there are no holes). @@ -107,7 +108,7 @@ * has only a minimal and not also a regular physical tuple, then tts_tuple * points at tts_minhdr and the fields of that struct are set correctly * for access to the minimal tuple; in particular, tts_minhdr.t_data points - * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple. This allows column + * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple. This allows column * extraction to treat the case identically to regular physical tuples. * * tts_slow/tts_off are saved state for slot_deform_tuple, and should not diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 0a25776449..267403c410 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -8,7 +8,7 @@ * or call fmgr-callable functions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fmgr.h @@ -18,8 +18,12 @@ #ifndef FMGR_H #define FMGR_H -/* We don't want to include primnodes.h here, so make a stub reference */ +/* We don't want to include primnodes.h here, so make some stub references */ typedef struct Node *fmNodePtr; +typedef struct Aggref *fmAggrefPtr; + +/* Likewise, avoid including execnodes.h here */ +typedef struct ExprContext *fmExprContextPtr; /* Likewise, avoid including stringinfo.h here */ typedef struct StringInfoData *fmStringInfo; @@ -50,8 +54,7 @@ typedef struct FmgrInfo { PGFunction fn_addr; /* pointer to function or handler to be called */ Oid fn_oid; /* OID of function (NOT of handler, if any) */ - short fn_nargs; /* 0..FUNC_MAX_ARGS, or -1 if variable arg - * count */ + short fn_nargs; /* number of input args (0..FUNC_MAX_ARGS) */ bool fn_strict; /* function is "strict" (NULL in => NULL out) */ bool fn_retset; /* function returns a set */ unsigned char fn_stats; /* collect stats if track_functions > this */ @@ -101,7 +104,7 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, /* * This macro initializes all the fields of a FunctionCallInfoData except - * for the arg[] and argnull[] arrays. Performance testing has shown that + * for the arg[] and argnull[] arrays. Performance testing has shown that * the fastest way to set up argnull[] for small numbers of arguments is to * explicitly set each required element to false, so we don't try to zero * out the argnull[] array in the macro. @@ -118,7 +121,7 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, /* * This macro invokes a function given a filled-in FunctionCallInfoData - * struct. The macro result is the returned Datum --- but note that + * struct. The macro result is the returned Datum --- but note that * caller must still check fcinfo->isnull! Also, if function is strict, * it is caller's responsibility to verify that no null arguments are present * before calling. @@ -167,11 +170,11 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, * which are varlena types). pg_detoast_datum() gives you either the input * datum (if not toasted) or a detoasted copy allocated with palloc(). * pg_detoast_datum_copy() always gives you a palloc'd copy --- use it - * if you need a modifiable copy of the input. Caller is expected to have + * if you need a modifiable copy of the input. Caller is expected to have * checked for null inputs first, if necessary. * * pg_detoast_datum_packed() will return packed (1-byte header) datums - * unmodified. It will still expand an externally toasted or compressed datum. + * unmodified. It will still expand an externally toasted or compressed datum. * The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY() * (beware of multiple evaluations in those macros!) * @@ -202,7 +205,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); pg_detoast_datum_packed((struct varlena *) DatumGetPointer(datum)) /* - * Support for cleaning up detoasted copies of inputs. This must only + * Support for cleaning up detoasted copies of inputs. This must only * be used for pass-by-ref datatypes, and normally would only be used * for toastable types. If the given pointer is different from the * original argument, assume it's a palloc'd detoasted copy, and pfree it. @@ -310,7 +313,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); #define PG_RETURN_TEXT_P(x) PG_RETURN_POINTER(x) #define PG_RETURN_BPCHAR_P(x) PG_RETURN_POINTER(x) #define PG_RETURN_VARCHAR_P(x) PG_RETURN_POINTER(x) -#define PG_RETURN_HEAPTUPLEHEADER(x) PG_RETURN_POINTER(x) +#define PG_RETURN_HEAPTUPLEHEADER(x) return HeapTupleHeaderGetDatum(x) /*------------------------------------------------------------------------- @@ -319,7 +322,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); * Dynamically loaded functions may use either the version-1 ("new style") * or version-0 ("old style") calling convention. Version 1 is the call * convention defined in this header file; version 0 is the old "plain C" - * convention. A version-1 function must be accompanied by the macro call + * convention. A version-1 function must be accompanied by the macro call * * PG_FUNCTION_INFO_V1(function_name); * @@ -344,6 +347,7 @@ typedef const Pg_finfo_record *(*PGFInfoFunction) (void); * doesn't hurt to add PGDLLIMPORT in case they don't. */ #define PG_FUNCTION_INFO_V1(funcname) \ +Datum funcname(PG_FUNCTION_ARGS); \ extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ const Pg_finfo_record * \ CppConcat(pg_finfo_,funcname) (void) \ @@ -500,8 +504,8 @@ extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, /* These are for invocation of a function identified by OID with a * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. These are essentially FunctionLookup() followed - * by FunctionCallN(). If the same function is to be invoked repeatedly, + * are allowed to be NULL. These are essentially FunctionLookup() followed + * by FunctionCallN(). If the same function is to be invoked repeatedly, * do the FunctionLookup() once and then use FunctionCallN(). */ extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation); @@ -624,6 +628,8 @@ extern Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum); extern Oid get_call_expr_argtype(fmNodePtr expr, int argnum); extern bool get_fn_expr_arg_stable(FmgrInfo *flinfo, int argnum); extern bool get_call_expr_arg_stable(fmNodePtr expr, int argnum); +extern bool get_fn_expr_variadic(FmgrInfo *flinfo); +extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid); /* * Routines in dfmgr.c @@ -639,8 +645,8 @@ extern void **find_rendezvous_variable(const char *varName); /* * Support for aggregate functions * - * This is actually in executor/nodeAgg.c, but we declare it here since the - * whole point is for callers of it to not be overly friendly with nodeAgg. + * These are actually in executor/nodeAgg.c, but we declare them here since + * the whole point is for callers to not be overly friendly with nodeAgg. */ /* AggCheckCallContext can return one of the following codes, or 0: */ @@ -649,12 +655,15 @@ extern void **find_rendezvous_variable(const char *varName); extern int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext); +extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo); +extern fmExprContextPtr AggGetPerTupleEContext(FunctionCallInfo fcinfo); +extern fmExprContextPtr AggGetPerAggEContext(FunctionCallInfo fcinfo); /* * We allow plugin modules to hook function entry/exit. This is intended * as support for loadable security policy modules, which may want to * perform additional privilege checks on function entry or exit, or to do - * other internal bookkeeping. To make this possible, such modules must be + * other internal bookkeeping. To make this possible, such modules must be * able not only to support normal function entry and exit, but also to trap * the case where we bail out due to an error; and they must also be able to * prevent inlining. diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h index 721cd25436..1b735dacc6 100644 --- a/src/include/foreign/fdwapi.h +++ b/src/include/foreign/fdwapi.h @@ -3,7 +3,7 @@ * fdwapi.h * API for foreign-data wrappers * - * Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Copyright (c) 2010-2014, PostgreSQL Global Development Group * * src/include/foreign/fdwapi.h * @@ -38,9 +38,6 @@ typedef ForeignScan *(*GetForeignPlan_function) (PlannerInfo *root, List *tlist, List *scan_clauses); -typedef void (*ExplainForeignScan_function) (ForeignScanState *node, - struct ExplainState *es); - typedef void (*BeginForeignScan_function) (ForeignScanState *node, int eflags); @@ -50,6 +47,50 @@ typedef void (*ReScanForeignScan_function) (ForeignScanState *node); typedef void (*EndForeignScan_function) (ForeignScanState *node); +typedef void (*AddForeignUpdateTargets_function) (Query *parsetree, + RangeTblEntry *target_rte, + Relation target_relation); + +typedef List *(*PlanForeignModify_function) (PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + +typedef void (*BeginForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + int eflags); + +typedef TupleTableSlot *(*ExecForeignInsert_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot *(*ExecForeignUpdate_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef TupleTableSlot *(*ExecForeignDelete_function) (EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + +typedef void (*EndForeignModify_function) (EState *estate, + ResultRelInfo *rinfo); + +typedef int (*IsForeignRelUpdatable_function) (Relation rel); + +typedef void (*ExplainForeignScan_function) (ForeignScanState *node, + struct ExplainState *es); + +typedef void (*ExplainForeignModify_function) (ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + struct ExplainState *es); + typedef int (*AcquireSampleRowsFunc) (Relation relation, int elevel, HeapTuple *rows, int targrows, double *totalrows, @@ -73,22 +114,35 @@ typedef struct FdwRoutine { NodeTag type; - /* - * These functions are required. - */ + /* Functions for scanning foreign tables */ GetForeignRelSize_function GetForeignRelSize; GetForeignPaths_function GetForeignPaths; GetForeignPlan_function GetForeignPlan; - ExplainForeignScan_function ExplainForeignScan; BeginForeignScan_function BeginForeignScan; IterateForeignScan_function IterateForeignScan; ReScanForeignScan_function ReScanForeignScan; EndForeignScan_function EndForeignScan; /* - * These functions are optional. Set the pointer to NULL for any that are - * not provided. + * Remaining functions are optional. Set the pointer to NULL for any that + * are not provided. */ + + /* Functions for updating foreign tables */ + AddForeignUpdateTargets_function AddForeignUpdateTargets; + PlanForeignModify_function PlanForeignModify; + BeginForeignModify_function BeginForeignModify; + ExecForeignInsert_function ExecForeignInsert; + ExecForeignUpdate_function ExecForeignUpdate; + ExecForeignDelete_function ExecForeignDelete; + EndForeignModify_function EndForeignModify; + IsForeignRelUpdatable_function IsForeignRelUpdatable; + + /* Support functions for EXPLAIN */ + ExplainForeignScan_function ExplainForeignScan; + ExplainForeignModify_function ExplainForeignModify; + + /* Support functions for ANALYZE */ AnalyzeForeignTable_function AnalyzeForeignTable; } FdwRoutine; @@ -96,5 +150,6 @@ typedef struct FdwRoutine /* Functions in foreign/foreign.c */ extern FdwRoutine *GetFdwRoutine(Oid fdwhandler); extern FdwRoutine *GetFdwRoutineByRelId(Oid relid); +extern FdwRoutine *GetFdwRoutineForRelation(Relation relation, bool makecopy); #endif /* FDWAPI_H */ diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h index f8aa99e2a4..ac080d71e5 100644 --- a/src/include/foreign/foreign.h +++ b/src/include/foreign/foreign.h @@ -4,7 +4,7 @@ * support for foreign-data wrappers, servers and user mappings. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/foreign/foreign.h * diff --git a/src/include/funcapi.h b/src/include/funcapi.h index 2da9fea537..6590a088c9 100644 --- a/src/include/funcapi.h +++ b/src/include/funcapi.h @@ -7,7 +7,7 @@ * or call FUNCAPI-callable functions or macros. * * - * Copyright (c) 2002-2012, PostgreSQL Global Development Group + * Copyright (c) 2002-2014, PostgreSQL Global Development Group * * src/include/funcapi.h * @@ -129,7 +129,7 @@ typedef struct FuncCallContext * Given a function's call info record, determine the kind of datatype * it is supposed to return. If resultTypeId isn't NULL, *resultTypeId * receives the actual datatype OID (this is mainly useful for scalar - * result types). If resultTupleDesc isn't NULL, *resultTupleDesc + * result types). If resultTupleDesc isn't NULL, *resultTupleDesc * receives a pointer to a TupleDesc when the result is of a composite * type, or NULL when it's a scalar result or the rowtype could not be * determined. NB: the tupledesc should be copied if it is to be @@ -200,6 +200,8 @@ extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); * HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) - * build a HeapTuple given user data in C string form. values is an array * of C strings, one for each attribute of the return tuple. + * Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple) - convert a + * HeapTupleHeader to a Datum. * * Macro declarations: * HeapTupleGetDatum(HeapTuple tuple) - convert a HeapTuple to a Datum. @@ -216,9 +218,9 @@ extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); *---------- */ -#define HeapTupleGetDatum(_tuple) PointerGetDatum((_tuple)->t_data) +#define HeapTupleGetDatum(tuple) HeapTupleHeaderGetDatum((tuple)->t_data) /* obsolete version of above */ -#define TupleGetDatum(_slot, _tuple) PointerGetDatum((_tuple)->t_data) +#define TupleGetDatum(_slot, _tuple) HeapTupleGetDatum(_tuple) extern TupleDesc RelationNameGetTupleDesc(const char *relname); extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases); @@ -227,6 +229,7 @@ extern TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases); extern TupleDesc BlessTupleDesc(TupleDesc tupdesc); extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc); extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values); +extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple); extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc); @@ -293,6 +296,15 @@ extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); PG_RETURN_DATUM(_result); \ } while (0) +#define SRF_RETURN_NEXT_NULL(_funcctx) \ + do { \ + ReturnSetInfo *rsi; \ + (_funcctx)->call_cntr++; \ + rsi = (ReturnSetInfo *) fcinfo->resultinfo; \ + rsi->isDone = ExprMultipleResult; \ + PG_RETURN_NULL(); \ + } while (0) + #define SRF_RETURN_DONE(_funcctx) \ do { \ ReturnSetInfo *rsi; \ diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h index 519a97975e..7995235d9f 100644 --- a/src/include/getaddrinfo.h +++ b/src/include/getaddrinfo.h @@ -13,7 +13,7 @@ * This code will also work on platforms where struct addrinfo is defined * in the system headers but no getaddrinfo() can be located. * - * Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/getaddrinfo.h * @@ -82,6 +82,9 @@ #ifndef NI_NUMERICSERV #define NI_NUMERICSERV 2 #endif +#ifndef NI_NAMEREQD +#define NI_NAMEREQD 4 +#endif #ifndef NI_MAXHOST #define NI_MAXHOST 1025 diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h index c07e7068fc..e23c21f333 100644 --- a/src/include/getopt_long.h +++ b/src/include/getopt_long.h @@ -2,22 +2,14 @@ * Portions Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * - * Portions Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/getopt_long.h */ #ifndef GETOPT_LONG_H #define GETOPT_LONG_H -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif - -/* These are picked up from the system's getopt() facility. */ -extern int opterr; -extern int optind; -extern int optopt; -extern char *optarg; +#include "pg_getopt.h" #ifndef HAVE_STRUCT_OPTION diff --git a/src/include/gtm/assert.h b/src/include/gtm/assert.h index 2a2f47dcab..5e6425c934 100644 --- a/src/include/gtm/assert.h +++ b/src/include/gtm/assert.h @@ -18,57 +18,5 @@ extern bool assert_enabled; -/* - * USE_ASSERT_CHECKING, if defined, turns on all the assertions. - * - plai 9/5/90 - * - * It should _NOT_ be defined in releases or in benchmark copies - */ - -/* - * Trap - * Generates an exception if the given condition is true. - */ -#define Trap(condition, errorType) \ - do { \ - if ((assert_enabled) && (condition)) \ - ExceptionalCondition(CppAsString(condition), (errorType), \ - __FILE__, __LINE__); \ - } while (0) - -/* - * TrapMacro is the same as Trap but it's intended for use in macros: - * - * #define foo(x) (AssertMacro(x != 0) && bar(x)) - * - * Isn't CPP fun? - */ -#define TrapMacro(condition, errorType) \ - ((bool) ((! assert_enabled) || ! (condition) || \ - (ExceptionalCondition(CppAsString(condition), (errorType), \ - __FILE__, __LINE__)))) - -#ifndef USE_ASSERT_CHECKING -#define Assert(condition) -#define AssertMacro(condition) ((void)true) -#define AssertArg(condition) -#define AssertState(condition) -#else -#define Assert(condition) \ - Trap(!(condition), "FailedAssertion") - -#define AssertMacro(condition) \ - ((void) TrapMacro(!(condition), "FailedAssertion")) - -#define AssertArg(condition) \ - Trap(!(condition), "BadArgument") - -#define AssertState(condition) \ - Trap(!(condition), "BadState") -#endif /* USE_ASSERT_CHECKING */ - -extern int ExceptionalCondition(const char *conditionName, - const char *errorType, - const char *fileName, int lineNumber); - #endif + diff --git a/src/include/gtm/pqsignal.h b/src/include/gtm/pqsignal.h index 9992791b23..c6d346e913 100644 --- a/src/include/gtm/pqsignal.h +++ b/src/include/gtm/pqsignal.h @@ -40,8 +40,6 @@ int pqsigsetmask(int mask); #endif #endif -typedef void (*pqsigfunc) (int); - extern void pqinitmask(void); extern pqsigfunc pqsignal(int signo, pqsigfunc func); diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h new file mode 100644 index 0000000000..8f83c234eb --- /dev/null +++ b/src/include/lib/binaryheap.h @@ -0,0 +1,54 @@ +/* + * binaryheap.h + * + * A simple binary heap implementation + * + * Portions Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + * src/include/lib/binaryheap.h + */ + +#ifndef BINARYHEAP_H +#define BINARYHEAP_H + +/* + * For a max-heap, the comparator must return <0 iff a < b, 0 iff a == b, + * and >0 iff a > b. For a min-heap, the conditions are reversed. + */ +typedef int (*binaryheap_comparator) (Datum a, Datum b, void *arg); + +/* + * binaryheap + * + * bh_size how many nodes are currently in "nodes" + * bh_space how many nodes can be stored in "nodes" + * bh_has_heap_property no unordered operations since last heap build + * bh_compare comparison function to define the heap property + * bh_arg user data for comparison function + * bh_nodes variable-length array of "space" nodes + */ +typedef struct binaryheap +{ + int bh_size; + int bh_space; + bool bh_has_heap_property; /* debugging cross-check */ + binaryheap_comparator bh_compare; + void *bh_arg; + Datum bh_nodes[FLEXIBLE_ARRAY_MEMBER]; +} binaryheap; + +extern binaryheap *binaryheap_allocate(int capacity, + binaryheap_comparator compare, + void *arg); +extern void binaryheap_reset(binaryheap *heap); +extern void binaryheap_free(binaryheap *heap); +extern void binaryheap_add_unordered(binaryheap *heap, Datum d); +extern void binaryheap_build(binaryheap *heap); +extern void binaryheap_add(binaryheap *heap, Datum d); +extern Datum binaryheap_first(binaryheap *heap); +extern Datum binaryheap_remove_first(binaryheap *heap); +extern void binaryheap_replace_first(binaryheap *heap, Datum d); + +#define binaryheap_empty(h) ((h)->bh_size == 0) + +#endif /* BINARYHEAP_H */ diff --git a/src/include/lib/dllist.h b/src/include/lib/dllist.h deleted file mode 100644 index 25ed64c7c4..0000000000 --- a/src/include/lib/dllist.h +++ /dev/null @@ -1,85 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dllist.h - * simple doubly linked list primitives - * the elements of the list are void* so the lists can contain anything - * Dlelem can only be in one list at a time - * - * - * Here's a small example of how to use Dllists: - * - * Dllist *lst; - * Dlelem *elt; - * void *in_stuff; -- stuff to stick in the list - * void *out_stuff - * - * lst = DLNewList(); -- make a new dllist - * DLAddHead(lst, DLNewElem(in_stuff)); -- add a new element to the list - * with in_stuff as the value - * ... - * elt = DLGetHead(lst); -- retrieve the head element - * out_stuff = (void*)DLE_VAL(elt); -- get the stuff out - * DLRemove(elt); -- removes the element from its list - * DLFreeElem(elt); -- free the element since we don't - * use it anymore - * - * - * It is also possible to use Dllist objects that are embedded in larger - * structures instead of being separately malloc'd. To do this, use - * DLInitElem() to initialize a Dllist field within a larger object. - * Don't forget to DLRemove() each field from its list (if any) before - * freeing the larger object! - * - * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/lib/dllist.h - * - *------------------------------------------------------------------------- - */ - -#ifndef DLLIST_H -#define DLLIST_H - -struct Dllist; -struct Dlelem; - -typedef struct Dlelem -{ - struct Dlelem *dle_next; /* next element */ - struct Dlelem *dle_prev; /* previous element */ - void *dle_val; /* value of the element */ - struct Dllist *dle_list; /* what list this element is in */ -} Dlelem; - -typedef struct Dllist -{ - Dlelem *dll_head; - Dlelem *dll_tail; -} Dllist; - -extern Dllist *DLNewList(void); /* allocate and initialize a list header */ -extern void DLInitList(Dllist *list); /* init a header alloced by caller */ -extern void DLFreeList(Dllist *list); /* free up a list and all the nodes in - * it */ -extern Dlelem *DLNewElem(void *val); -extern void DLInitElem(Dlelem *e, void *val); -extern void DLFreeElem(Dlelem *e); -extern void DLRemove(Dlelem *e); /* removes node from list */ -extern void DLAddHead(Dllist *list, Dlelem *node); -extern void DLAddTail(Dllist *list, Dlelem *node); -extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */ -extern Dlelem *DLRemTail(Dllist *list); -extern void DLMoveToFront(Dlelem *e); /* move node to front of its list */ - -/* These are macros for speed */ -#define DLGetHead(list) ((list)->dll_head) -#define DLGetTail(list) ((list)->dll_tail) -#define DLGetSucc(elem) ((elem)->dle_next) -#define DLGetPred(elem) ((elem)->dle_prev) -#define DLGetListHdr(elem) ((elem)->dle_list) - -#define DLE_VAL(elem) ((elem)->dle_val) - -#endif /* DLLIST_H */ diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h new file mode 100644 index 0000000000..f70474bd44 --- /dev/null +++ b/src/include/lib/ilist.h @@ -0,0 +1,775 @@ +/*------------------------------------------------------------------------- + * + * ilist.h + * integrated/inline doubly- and singly-linked lists + * + * These list types are useful when there are only a predetermined set of + * lists that an object could be in. List links are embedded directly into + * the objects, and thus no extra memory management overhead is required. + * (Of course, if only a small proportion of existing objects are in a list, + * the link fields in the remainder would be wasted space. But usually, + * it saves space to not have separately-allocated list nodes.) + * + * None of the functions here allocate any memory; they just manipulate + * externally managed memory. The APIs for singly and doubly linked lists + * are identical as far as capabilities of both allow. + * + * Each list has a list header, which exists even when the list is empty. + * An empty singly-linked list has a NULL pointer in its header. + * There are two kinds of empty doubly linked lists: those that have been + * initialized to NULL, and those that have been initialized to circularity. + * (If a dlist is modified and then all its elements are deleted, it will be + * in the circular state.) We prefer circular dlists because there are some + * operations that can be done without branches (and thus faster) on lists + * that use circular representation. However, it is often convenient to + * initialize list headers to zeroes rather than setting them up with an + * explicit initialization function, so we also allow the other case. + * + * EXAMPLES + * + * Here's a simple example demonstrating how this can be used. Let's assume + * we want to store information about the tables contained in a database. + * + * #include "lib/ilist.h" + * + * // Define struct for the databases including a list header that will be + * // used to access the nodes in the table list later on. + * typedef struct my_database + * { + * char *datname; + * dlist_head tables; + * // ... + * } my_database; + * + * // Define struct for the tables. Note the list_node element which stores + * // prev/next list links. The list_node element need not be first. + * typedef struct my_table + * { + * char *tablename; + * dlist_node list_node; + * perm_t permissions; + * // ... + * } my_table; + * + * // create a database + * my_database *db = create_database(); + * + * // and add a few tables to its table list + * dlist_push_head(&db->tables, &create_table(db, "a")->list_node); + * ... + * dlist_push_head(&db->tables, &create_table(db, "b")->list_node); + * + * + * To iterate over the table list, we allocate an iterator variable and use + * a specialized looping construct. Inside a dlist_foreach, the iterator's + * 'cur' field can be used to access the current element. iter.cur points to + * a 'dlist_node', but most of the time what we want is the actual table + * information; dlist_container() gives us that, like so: + * + * dlist_iter iter; + * dlist_foreach(iter, &db->tables) + * { + * my_table *tbl = dlist_container(my_table, list_node, iter.cur); + * printf("we have a table: %s in database %s\n", + * tbl->tablename, db->datname); + * } + * + * + * While a simple iteration is useful, we sometimes also want to manipulate + * the list while iterating. There is a different iterator element and looping + * construct for that. Suppose we want to delete tables that meet a certain + * criterion: + * + * dlist_mutable_iter miter; + * dlist_foreach_modify(miter, &db->tables) + * { + * my_table *tbl = dlist_container(my_table, list_node, miter.cur); + * + * if (!tbl->to_be_deleted) + * continue; // don't touch this one + * + * // unlink the current table from the linked list + * dlist_delete(miter.cur); + * // as these lists never manage memory, we can still access the table + * // after it's been unlinked + * drop_table(db, tbl); + * } + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/lib/ilist.h + *------------------------------------------------------------------------- + */ +#ifndef ILIST_H +#define ILIST_H + +/* + * Enable for extra debugging. This is rather expensive, so it's not enabled by + * default even when USE_ASSERT_CHECKING. + */ +/* #define ILIST_DEBUG */ + +/* + * Node of a doubly linked list. + * + * Embed this in structs that need to be part of a doubly linked list. + */ +typedef struct dlist_node dlist_node; +struct dlist_node +{ + dlist_node *prev; + dlist_node *next; +}; + +/* + * Head of a doubly linked list. + * + * Non-empty lists are internally circularly linked. Circular lists have the + * advantage of not needing any branches in the most common list manipulations. + * An empty list can also be represented as a pair of NULL pointers, making + * initialization easier. + */ +typedef struct dlist_head +{ + /* + * head.next either points to the first element of the list; to &head if + * it's a circular empty list; or to NULL if empty and not circular. + * + * head.prev either points to the last element of the list; to &head if + * it's a circular empty list; or to NULL if empty and not circular. + */ + dlist_node head; +} dlist_head; + + +/* + * Doubly linked list iterator. + * + * Used as state in dlist_foreach() and dlist_reverse_foreach(). To get the + * current element of the iteration use the 'cur' member. + * + * Iterations using this are *not* allowed to change the list while iterating! + * + * NB: We use an extra "end" field here to avoid multiple evaluations of + * arguments in the dlist_foreach() macro. + */ +typedef struct dlist_iter +{ + dlist_node *cur; /* current element */ + dlist_node *end; /* last node we'll iterate to */ +} dlist_iter; + +/* + * Doubly linked list iterator allowing some modifications while iterating. + * + * Used as state in dlist_foreach_modify(). To get the current element of the + * iteration use the 'cur' member. + * + * Iterations using this are only allowed to change the list at the current + * point of iteration. It is fine to delete the current node, but it is *not* + * fine to insert or delete adjacent nodes. + * + * NB: We need a separate type for mutable iterations so that we can store + * the 'next' node of the current node in case it gets deleted or modified. + */ +typedef struct dlist_mutable_iter +{ + dlist_node *cur; /* current element */ + dlist_node *next; /* next node we'll iterate to */ + dlist_node *end; /* last node we'll iterate to */ +} dlist_mutable_iter; + +/* + * Node of a singly linked list. + * + * Embed this in structs that need to be part of a singly linked list. + */ +typedef struct slist_node slist_node; +struct slist_node +{ + slist_node *next; +}; + +/* + * Head of a singly linked list. + * + * Singly linked lists are not circularly linked, in contrast to doubly linked + * lists; we just set head.next to NULL if empty. This doesn't incur any + * additional branches in the usual manipulations. + */ +typedef struct slist_head +{ + slist_node head; +} slist_head; + +/* + * Singly linked list iterator. + * + * Used as state in slist_foreach(). To get the current element of the + * iteration use the 'cur' member. + * + * It's allowed to modify the list while iterating, with the exception of + * deleting the iterator's current node; deletion of that node requires + * care if the iteration is to be continued afterward. (Doing so and also + * deleting or inserting adjacent list elements might misbehave; also, if + * the user frees the current node's storage, continuing the iteration is + * not safe.) + * + * NB: this wouldn't really need to be an extra struct, we could use an + * slist_node * directly. We prefer a separate type for consistency. + */ +typedef struct slist_iter +{ + slist_node *cur; +} slist_iter; + +/* + * Singly linked list iterator allowing some modifications while iterating. + * + * Used as state in slist_foreach_modify(). To get the current element of the + * iteration use the 'cur' member. + * + * The only list modification allowed while iterating is to remove the current + * node via slist_delete_current() (*not* slist_delete()). Insertion or + * deletion of nodes adjacent to the current node would misbehave. + */ +typedef struct slist_mutable_iter +{ + slist_node *cur; /* current element */ + slist_node *next; /* next node we'll iterate to */ + slist_node *prev; /* prev node, for deletions */ +} slist_mutable_iter; + + +/* Static initializers */ +#define DLIST_STATIC_INIT(name) {{&(name).head, &(name).head}} +#define SLIST_STATIC_INIT(name) {{NULL}} + + +/* Prototypes for functions too big to be inline */ + +/* Caution: this is O(n); consider using slist_delete_current() instead */ +extern void slist_delete(slist_head *head, slist_node *node); + +#ifdef ILIST_DEBUG +extern void dlist_check(dlist_head *head); +extern void slist_check(slist_head *head); +#else +/* + * These seemingly useless casts to void are here to keep the compiler quiet + * about the argument being unused in many functions in a non-debug compile, + * in which functions the only point of passing the list head pointer is to be + * able to run these checks. + */ +#define dlist_check(head) ((void) (head)) +#define slist_check(head) ((void) (head)) +#endif /* ILIST_DEBUG */ + + +/* + * We want the functions below to be inline; but if the compiler doesn't + * support that, fall back on providing them as regular functions. See + * STATIC_IF_INLINE in c.h. + */ +#ifndef PG_USE_INLINE +extern void dlist_init(dlist_head *head); +extern bool dlist_is_empty(dlist_head *head); +extern void dlist_push_head(dlist_head *head, dlist_node *node); +extern void dlist_push_tail(dlist_head *head, dlist_node *node); +extern void dlist_insert_after(dlist_node *after, dlist_node *node); +extern void dlist_insert_before(dlist_node *before, dlist_node *node); +extern void dlist_delete(dlist_node *node); +extern dlist_node *dlist_pop_head_node(dlist_head *head); +extern void dlist_move_head(dlist_head *head, dlist_node *node); +extern bool dlist_has_next(dlist_head *head, dlist_node *node); +extern bool dlist_has_prev(dlist_head *head, dlist_node *node); +extern dlist_node *dlist_next_node(dlist_head *head, dlist_node *node); +extern dlist_node *dlist_prev_node(dlist_head *head, dlist_node *node); +extern dlist_node *dlist_head_node(dlist_head *head); +extern dlist_node *dlist_tail_node(dlist_head *head); + +/* dlist macro support functions */ +extern void *dlist_tail_element_off(dlist_head *head, size_t off); +extern void *dlist_head_element_off(dlist_head *head, size_t off); +#endif /* !PG_USE_INLINE */ + +#if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS) +/* + * Initialize a doubly linked list. + * Previous state will be thrown away without any cleanup. + */ +STATIC_IF_INLINE void +dlist_init(dlist_head *head) +{ + head->head.next = head->head.prev = &head->head; +} + +/* + * Is the list empty? + * + * An empty list has either its first 'next' pointer set to NULL, or to itself. + */ +STATIC_IF_INLINE bool +dlist_is_empty(dlist_head *head) +{ + dlist_check(head); + + return head->head.next == NULL || head->head.next == &(head->head); +} + +/* + * Insert a node at the beginning of the list. + */ +STATIC_IF_INLINE void +dlist_push_head(dlist_head *head, dlist_node *node) +{ + if (head->head.next == NULL) /* convert NULL header to circular */ + dlist_init(head); + + node->next = head->head.next; + node->prev = &head->head; + node->next->prev = node; + head->head.next = node; + + dlist_check(head); +} + +/* + * Insert a node at the end of the list. + */ +STATIC_IF_INLINE void +dlist_push_tail(dlist_head *head, dlist_node *node) +{ + if (head->head.next == NULL) /* convert NULL header to circular */ + dlist_init(head); + + node->next = &head->head; + node->prev = head->head.prev; + node->prev->next = node; + head->head.prev = node; + + dlist_check(head); +} + +/* + * Insert a node after another *in the same list* + */ +STATIC_IF_INLINE void +dlist_insert_after(dlist_node *after, dlist_node *node) +{ + node->prev = after; + node->next = after->next; + after->next = node; + node->next->prev = node; +} + +/* + * Insert a node before another *in the same list* + */ +STATIC_IF_INLINE void +dlist_insert_before(dlist_node *before, dlist_node *node) +{ + node->prev = before->prev; + node->next = before; + before->prev = node; + node->prev->next = node; +} + +/* + * Delete 'node' from its list (it must be in one). + */ +STATIC_IF_INLINE void +dlist_delete(dlist_node *node) +{ + node->prev->next = node->next; + node->next->prev = node->prev; +} + +/* + * Remove and return the first node from a list (there must be one). + */ +STATIC_IF_INLINE dlist_node * +dlist_pop_head_node(dlist_head *head) +{ + dlist_node *node; + + Assert(!dlist_is_empty(head)); + node = head->head.next; + dlist_delete(node); + return node; +} + +/* + * Move element from its current position in the list to the head position in + * the same list. + * + * Undefined behaviour if 'node' is not already part of the list. + */ +STATIC_IF_INLINE void +dlist_move_head(dlist_head *head, dlist_node *node) +{ + /* fast path if it's already at the head */ + if (head->head.next == node) + return; + + dlist_delete(node); + dlist_push_head(head, node); + + dlist_check(head); +} + +/* + * Check whether 'node' has a following node. + * Caution: unreliable if 'node' is not in the list. + */ +STATIC_IF_INLINE bool +dlist_has_next(dlist_head *head, dlist_node *node) +{ + return node->next != &head->head; +} + +/* + * Check whether 'node' has a preceding node. + * Caution: unreliable if 'node' is not in the list. + */ +STATIC_IF_INLINE bool +dlist_has_prev(dlist_head *head, dlist_node *node) +{ + return node->prev != &head->head; +} + +/* + * Return the next node in the list (there must be one). + */ +STATIC_IF_INLINE dlist_node * +dlist_next_node(dlist_head *head, dlist_node *node) +{ + Assert(dlist_has_next(head, node)); + return node->next; +} + +/* + * Return previous node in the list (there must be one). + */ +STATIC_IF_INLINE dlist_node * +dlist_prev_node(dlist_head *head, dlist_node *node) +{ + Assert(dlist_has_prev(head, node)); + return node->prev; +} + +/* internal support function to get address of head element's struct */ +STATIC_IF_INLINE void * +dlist_head_element_off(dlist_head *head, size_t off) +{ + Assert(!dlist_is_empty(head)); + return (char *) head->head.next - off; +} + +/* + * Return the first node in the list (there must be one). + */ +STATIC_IF_INLINE dlist_node * +dlist_head_node(dlist_head *head) +{ + return (dlist_node *) dlist_head_element_off(head, 0); +} + +/* internal support function to get address of tail element's struct */ +STATIC_IF_INLINE void * +dlist_tail_element_off(dlist_head *head, size_t off) +{ + Assert(!dlist_is_empty(head)); + return (char *) head->head.prev - off; +} + +/* + * Return the last node in the list (there must be one). + */ +STATIC_IF_INLINE dlist_node * +dlist_tail_node(dlist_head *head) +{ + return (dlist_node *) dlist_tail_element_off(head, 0); +} +#endif /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */ + +/* + * Return the containing struct of 'type' where 'membername' is the dlist_node + * pointed at by 'ptr'. + * + * This is used to convert a dlist_node * back to its containing struct. + */ +#define dlist_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, dlist_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Return the address of the first element in the list. + * + * The list must not be empty. + */ +#define dlist_head_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + (type *) dlist_head_element_off(lhead, offsetof(type, membername))) + +/* + * Return the address of the last element in the list. + * + * The list must not be empty. + */ +#define dlist_tail_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, dlist_node), \ + ((type *) dlist_tail_element_off(lhead, offsetof(type, membername)))) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * It is *not* allowed to manipulate the list during iteration. + */ +#define dlist_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->next ? (iter).end->next : (iter).end; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).cur->next) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * Iterations using this are only allowed to change the list at the current + * point of iteration. It is fine to delete the current node, but it is *not* + * fine to insert or delete adjacent nodes. + */ +#define dlist_foreach_modify(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_mutable_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->next ? (iter).end->next : (iter).end, \ + (iter).next = (iter).cur->next; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).next, (iter).next = (iter).cur->next) + +/* + * Iterate through the list in reverse order. + * + * It is *not* allowed to manipulate the list during iteration. + */ +#define dlist_reverse_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \ + AssertVariableIsOfTypeMacro(lhead, dlist_head *), \ + (iter).end = &(lhead)->head, \ + (iter).cur = (iter).end->prev ? (iter).end->prev : (iter).end; \ + (iter).cur != (iter).end; \ + (iter).cur = (iter).cur->prev) + + +/* + * We want the functions below to be inline; but if the compiler doesn't + * support that, fall back on providing them as regular functions. See + * STATIC_IF_INLINE in c.h. + */ +#ifndef PG_USE_INLINE +extern void slist_init(slist_head *head); +extern bool slist_is_empty(slist_head *head); +extern void slist_push_head(slist_head *head, slist_node *node); +extern void slist_insert_after(slist_node *after, slist_node *node); +extern slist_node *slist_pop_head_node(slist_head *head); +extern bool slist_has_next(slist_head *head, slist_node *node); +extern slist_node *slist_next_node(slist_head *head, slist_node *node); +extern slist_node *slist_head_node(slist_head *head); +extern void slist_delete_current(slist_mutable_iter *iter); + +/* slist macro support function */ +extern void *slist_head_element_off(slist_head *head, size_t off); +#endif + +#if defined(PG_USE_INLINE) || defined(ILIST_INCLUDE_DEFINITIONS) +/* + * Initialize a singly linked list. + * Previous state will be thrown away without any cleanup. + */ +STATIC_IF_INLINE void +slist_init(slist_head *head) +{ + head->head.next = NULL; +} + +/* + * Is the list empty? + */ +STATIC_IF_INLINE bool +slist_is_empty(slist_head *head) +{ + slist_check(head); + + return head->head.next == NULL; +} + +/* + * Insert a node at the beginning of the list. + */ +STATIC_IF_INLINE void +slist_push_head(slist_head *head, slist_node *node) +{ + node->next = head->head.next; + head->head.next = node; + + slist_check(head); +} + +/* + * Insert a node after another *in the same list* + */ +STATIC_IF_INLINE void +slist_insert_after(slist_node *after, slist_node *node) +{ + node->next = after->next; + after->next = node; +} + +/* + * Remove and return the first node from a list (there must be one). + */ +STATIC_IF_INLINE slist_node * +slist_pop_head_node(slist_head *head) +{ + slist_node *node; + + Assert(!slist_is_empty(head)); + node = head->head.next; + head->head.next = node->next; + slist_check(head); + return node; +} + +/* + * Check whether 'node' has a following node. + */ +STATIC_IF_INLINE bool +slist_has_next(slist_head *head, slist_node *node) +{ + slist_check(head); + + return node->next != NULL; +} + +/* + * Return the next node in the list (there must be one). + */ +STATIC_IF_INLINE slist_node * +slist_next_node(slist_head *head, slist_node *node) +{ + Assert(slist_has_next(head, node)); + return node->next; +} + +/* internal support function to get address of head element's struct */ +STATIC_IF_INLINE void * +slist_head_element_off(slist_head *head, size_t off) +{ + Assert(!slist_is_empty(head)); + return (char *) head->head.next - off; +} + +/* + * Return the first node in the list (there must be one). + */ +STATIC_IF_INLINE slist_node * +slist_head_node(slist_head *head) +{ + return (slist_node *) slist_head_element_off(head, 0); +} + +/* + * Delete the list element the iterator currently points to. + * + * Caution: this modifies iter->cur, so don't use that again in the current + * loop iteration. + */ +STATIC_IF_INLINE void +slist_delete_current(slist_mutable_iter *iter) +{ + /* + * Update previous element's forward link. If the iteration is at the + * first list element, iter->prev will point to the list header's "head" + * field, so we don't need a special case for that. + */ + iter->prev->next = iter->next; + + /* + * Reset cur to prev, so that prev will continue to point to the prior + * valid list element after slist_foreach_modify() advances to the next. + */ + iter->cur = iter->prev; +} +#endif /* PG_USE_INLINE || ILIST_INCLUDE_DEFINITIONS */ + +/* + * Return the containing struct of 'type' where 'membername' is the slist_node + * pointed at by 'ptr'. + * + * This is used to convert a slist_node * back to its containing struct. + */ +#define slist_container(type, membername, ptr) \ + (AssertVariableIsOfTypeMacro(ptr, slist_node *), \ + AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \ + ((type *) ((char *) (ptr) - offsetof(type, membername)))) + +/* + * Return the address of the first element in the list. + * + * The list must not be empty. + */ +#define slist_head_element(type, membername, lhead) \ + (AssertVariableIsOfTypeMacro(((type *) NULL)->membername, slist_node), \ + (type *) slist_head_element_off(lhead, offsetof(type, membername))) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * It's allowed to modify the list while iterating, with the exception of + * deleting the iterator's current node; deletion of that node requires + * care if the iteration is to be continued afterward. (Doing so and also + * deleting or inserting adjacent list elements might misbehave; also, if + * the user frees the current node's storage, continuing the iteration is + * not safe.) + */ +#define slist_foreach(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, slist_iter), \ + AssertVariableIsOfTypeMacro(lhead, slist_head *), \ + (iter).cur = (lhead)->head.next; \ + (iter).cur != NULL; \ + (iter).cur = (iter).cur->next) + +/* + * Iterate through the list pointed at by 'lhead' storing the state in 'iter'. + * + * Access the current element with iter.cur. + * + * The only list modification allowed while iterating is to remove the current + * node via slist_delete_current() (*not* slist_delete()). Insertion or + * deletion of nodes adjacent to the current node would misbehave. + */ +#define slist_foreach_modify(iter, lhead) \ + for (AssertVariableIsOfTypeMacro(iter, slist_mutable_iter), \ + AssertVariableIsOfTypeMacro(lhead, slist_head *), \ + (iter).prev = &(lhead)->head, \ + (iter).cur = (iter).prev->next, \ + (iter).next = (iter).cur ? (iter).cur->next : NULL; \ + (iter).cur != NULL; \ + (iter).prev = (iter).cur, \ + (iter).cur = (iter).next, \ + (iter).next = (iter).next ? (iter).next->next : NULL) + +#endif /* ILIST_H */ diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h index dbf9277abe..4fff10a70c 100644 --- a/src/include/lib/stringinfo.h +++ b/src/include/lib/stringinfo.h @@ -7,7 +7,7 @@ * It can be used to buffer either ordinary C strings (null-terminated text) * or arbitrary binary data. All storage is allocated with palloc(). * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/lib/stringinfo.h @@ -60,7 +60,7 @@ typedef StringInfoData *StringInfo; * * NOTE: some routines build up a string using StringInfo, and then * release the StringInfoData but return the data string itself to their - * caller. At that point the data string looks like a plain palloc'd + * caller. At that point the data string looks like a plain palloc'd * string. *------------------------- */ @@ -100,12 +100,13 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); /*------------------------ * appendStringInfoVA * Attempt to format text data under the control of fmt (an sprintf-style - * format string) and append it to whatever is already in str. If successful - * return true; if not (because there's not enough space), return false - * without modifying str. Typically the caller would enlarge str and retry - * on false return --- see appendStringInfo for standard usage pattern. + * format string) and append it to whatever is already in str. If successful + * return zero; if not (because there's not enough space), return an estimate + * of the space needed, without modifying str. Typically the caller should + * pass the return value to enlargeStringInfo() before trying again; see + * appendStringInfo for standard usage pattern. */ -extern bool +extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0))); diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h index 84f4440268..ace647a7ff 100644 --- a/src/include/libpq/auth.h +++ b/src/include/libpq/auth.h @@ -4,7 +4,7 @@ * Definitions for network authentication routines * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/auth.h @@ -17,9 +17,7 @@ #include "libpq/libpq-be.h" extern char *pg_krb_server_keyfile; -extern char *pg_krb_srvnam; extern bool pg_krb_caseins_users; -extern char *pg_krb_server_hostname; extern char *pg_krb_realm; extern void ClientAuthentication(Port *port); diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h index 0c832da6e4..84ee49690c 100644 --- a/src/include/libpq/be-fsstubs.h +++ b/src/include/libpq/be-fsstubs.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/be-fsstubs.h @@ -25,6 +25,7 @@ extern Datum lo_export(PG_FUNCTION_ARGS); extern Datum lo_creat(PG_FUNCTION_ARGS); extern Datum lo_create(PG_FUNCTION_ARGS); +extern Datum lo_create_bytea(PG_FUNCTION_ARGS); extern Datum lo_open(PG_FUNCTION_ARGS); extern Datum lo_close(PG_FUNCTION_ARGS); @@ -32,10 +33,17 @@ extern Datum lo_close(PG_FUNCTION_ARGS); extern Datum loread(PG_FUNCTION_ARGS); extern Datum lowrite(PG_FUNCTION_ARGS); +extern Datum lo_get(PG_FUNCTION_ARGS); +extern Datum lo_get_fragment(PG_FUNCTION_ARGS); +extern Datum lo_put(PG_FUNCTION_ARGS); + extern Datum lo_lseek(PG_FUNCTION_ARGS); extern Datum lo_tell(PG_FUNCTION_ARGS); +extern Datum lo_lseek64(PG_FUNCTION_ARGS); +extern Datum lo_tell64(PG_FUNCTION_ARGS); extern Datum lo_unlink(PG_FUNCTION_ARGS); extern Datum lo_truncate(PG_FUNCTION_ARGS); +extern Datum lo_truncate64(PG_FUNCTION_ARGS); /* * compatibility option for access control diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h index da4459062b..b91024f86c 100644 --- a/src/include/libpq/crypt.h +++ b/src/include/libpq/crypt.h @@ -3,7 +3,7 @@ * crypt.h * Interface to libpq/crypt.c * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/crypt.h @@ -15,7 +15,7 @@ #include "libpq/libpq-be.h" -extern int md5_crypt_verify(const Port *port, const char *user, - char *client_pass); +extern int md5_crypt_verify(const Port *port, const char *role, + char *client_pass, char **logdetail); #endif diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 12a526e691..938668680d 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -13,13 +13,13 @@ #include "libpq/pqcomm.h" /* pgrminclude ignore */ /* needed for NetBSD */ #include "nodes/pg_list.h" +#include "regex/regex.h" typedef enum UserAuth { uaReject, uaImplicitReject, - uaKrb5, uaTrust, uaIdent, uaPassword, @@ -52,6 +52,7 @@ typedef enum ConnType typedef struct HbaLine { int linenumber; + char *rawline; ConnType conntype; List *databases; List *roles; @@ -70,10 +71,10 @@ typedef struct HbaLine char *ldapbindpasswd; char *ldapsearchattribute; char *ldapbasedn; + int ldapscope; char *ldapprefix; char *ldapsuffix; bool clientcert; - char *krb_server_hostname; char *krb_realm; bool include_realm; char *radiusserver; @@ -82,11 +83,21 @@ typedef struct HbaLine int radiusport; } HbaLine; +typedef struct IdentLine +{ + int linenumber; + + char *usermap; + char *ident_user; + char *pg_role; + regex_t re; +} IdentLine; + /* kluge to avoid including libpq/libpq-be.h here */ typedef struct Port hbaPort; extern bool load_hba(void); -extern void load_ident(void); +extern bool load_ident(void); extern void hba_getauthmethod(hbaPort *port); extern int check_usermap(const char *usermap_name, const char *pg_role, const char *auth_user, diff --git a/src/include/libpq/ip.h b/src/include/libpq/ip.h index 0ea57461fc..95d033392b 100644 --- a/src/include/libpq/ip.h +++ b/src/include/libpq/ip.h @@ -6,7 +6,7 @@ * These definitions are used by both frontend and backend code. Be careful * what you include here! * - * Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/libpq/ip.h * diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index 55a88d6613..5abaa25e32 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -8,7 +8,7 @@ * Structs that need to be client-visible are in pqcomm.h. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq-be.h @@ -92,12 +92,31 @@ typedef struct #endif /* - * This is used by the postmaster in its communication with frontends. It + * SSL renegotiations + */ +extern int ssl_renegotiation_limit; + +/* + * This is used by the postmaster in its communication with frontends. It * contains all state information needed during this communication before the - * backend is run. The Port structure is kept in malloc'd memory and is - * still available when a backend is running (see MyProcPort). The data + * backend is run. The Port structure is kept in malloc'd memory and is + * still available when a backend is running (see MyProcPort). The data * it points to must also be malloc'd, or else palloc'd in TopMemoryContext, * so that it survives into PostgresMain execution! + * + * remote_hostname is set if we did a successful reverse lookup of the + * client's IP address during connection setup. + * remote_hostname_resolv tracks the state of hostname verification: + * +1 = remote_hostname is known to resolve to client's IP address + * -1 = remote_hostname is known NOT to resolve to client's IP address + * 0 = we have not done the forward DNS lookup yet + * -2 = there was an error in name resolution + * If reverse lookup of the client IP address fails, remote_hostname will be + * left NULL while remote_hostname_resolv is set to -2. If reverse lookup + * succeeds but forward lookup fails, remote_hostname_resolv is also set to -2 + * (the case is distinguishable because remote_hostname isn't NULL). In + * either of the -2 cases, remote_hostname_errcode saves the lookup return + * code for possible later use with gai_strerror. */ typedef struct Port @@ -110,18 +129,14 @@ typedef struct Port char *remote_host; /* name (or ip addr) of remote host */ char *remote_hostname;/* name (not ip addr) of remote host, if * available */ - int remote_hostname_resolv; /* +1 = remote_hostname is known to - * resolve to client's IP address; -1 - * = remote_hostname is known NOT to - * resolve to client's IP address; 0 = - * we have not done the forward DNS - * lookup yet */ + int remote_hostname_resolv; /* see above */ + int remote_hostname_errcode; /* see above */ char *remote_port; /* text rep of remote port */ CAC_state canAcceptConnections; /* postmaster connection status */ /* * Information that needs to be saved from the startup packet and passed - * into backend execution. "char *" fields are NULL if not set. + * into backend execution. "char *" fields are NULL if not set. * guc_options points to a List of alternating option names and values. */ char *database_name; diff --git a/src/include/libpq/libpq-fs.h b/src/include/libpq/libpq-fs.h index 70295ce24d..8710a3eed4 100644 --- a/src/include/libpq/libpq-fs.h +++ b/src/include/libpq/libpq-fs.h @@ -4,7 +4,7 @@ * definitions for using Inversion file system routines (ie, large objects) * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq-fs.h diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 7083cd866b..e4e354dafa 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -4,7 +4,7 @@ * POSTGRES LIBPQ buffer structure definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq.h @@ -45,11 +45,11 @@ typedef struct * prototypes for functions in pqcomm.c */ extern int StreamServerPort(int family, char *hostName, - unsigned short portNumber, char *unixSocketName, pgsocket ListenSocket[], - int MaxListen); + unsigned short portNumber, char *unixSocketDir, + pgsocket ListenSocket[], int MaxListen); extern int StreamConnection(pgsocket server_fd, Port *port); extern void StreamClose(pgsocket sock); -extern void TouchSocketFile(void); +extern void TouchSocketFiles(void); extern void pq_init(void); extern void pq_comm_reset(void); extern int pq_getbytes(char *s, size_t len); diff --git a/src/include/libpq/md5.h b/src/include/libpq/md5.h index e05857285f..13faa19147 100644 --- a/src/include/libpq/md5.h +++ b/src/include/libpq/md5.h @@ -6,7 +6,7 @@ * These definitions are needed by both frontend and backend code to work * with MD5-encrypted passwords. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/md5.h diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index 604b5535df..d68a197c29 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -6,7 +6,7 @@ * NOTE: for historical reasons, this does not correspond to pqcomm.c. * pqcomm.c's routines are declared in libpq.h. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqcomm.h @@ -74,6 +74,19 @@ typedef struct (port)) /* + * The maximum workable length of a socket path is what will fit into + * struct sockaddr_un. This is usually only 100 or so bytes :-(. + * + * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), + * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. + * (Because the standard API for getaddrinfo doesn't allow it to complain in + * a useful way when the socket pathname is too long, we have to test for + * this explicitly, instead of just letting the subroutine return an error.) + */ +#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) + + +/* * These manipulate the frontend/backend protocol version number. * * The major number should be incremented for incompatible changes. The minor @@ -140,7 +153,7 @@ extern bool Db_user_namespace; /* * In protocol 3.0 and later, the startup packet length is not fixed, but - * we set an arbitrary limit on it anyway. This is just to prevent simple + * we set an arbitrary limit on it anyway. This is just to prevent simple * denial-of-service attacks via sending enough data to run the server * out of memory. */ @@ -151,7 +164,7 @@ extern bool Db_user_namespace; #define AUTH_REQ_OK 0 /* User is authenticated */ #define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ -#define AUTH_REQ_KRB5 2 /* Kerberos V5 */ +#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ #define AUTH_REQ_PASSWORD 3 /* Password */ #define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ #define AUTH_REQ_MD5 5 /* md5 password */ diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h index 7080076eb7..6c0362138a 100644 --- a/src/include/libpq/pqformat.h +++ b/src/include/libpq/pqformat.h @@ -3,7 +3,7 @@ * pqformat.h * Definitions for formatting and parsing frontend/backend messages * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqformat.h diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h index 399be9dac9..4d29489d5b 100644 --- a/src/include/libpq/pqsignal.h +++ b/src/include/libpq/pqsignal.h @@ -1,18 +1,13 @@ /*------------------------------------------------------------------------- * * pqsignal.h - * prototypes for the reliable BSD-style signal(2) routine. + * Backend signal(2) support (see also src/port/pqsignal.c) * - * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqsignal.h * - * NOTES - * This shouldn't be in libpq, but the monitor and some other - * things need it... - * *------------------------------------------------------------------------- */ #ifndef PQSIGNAL_H @@ -42,10 +37,6 @@ int pqsigsetmask(int mask); #define sigdelset(set, signum) (*(set) &= ~(sigmask(signum))) #endif /* not HAVE_SIGPROCMASK */ -typedef void (*pqsigfunc) (int); - extern void pqinitmask(void); -extern pqsigfunc pqsignal(int signo, pqsigfunc func); - #endif /* PQSIGNAL_H */ diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h index d456309486..09085f23ae 100644 --- a/src/include/mb/pg_wchar.h +++ b/src/include/mb/pg_wchar.h @@ -3,14 +3,14 @@ * pg_wchar.h * multibyte-character support * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/mb/pg_wchar.h * * NOTES * This is used both by the backend and by libpq, but should not be - * included by libpq client programs. In particular, a libpq client + * included by libpq client programs. In particular, a libpq client * should not assume that the encoding IDs used by the version of libpq * it's linked to match up with the IDs declared here. * @@ -25,6 +25,11 @@ typedef unsigned int pg_wchar; /* + * Maximum byte length of multibyte characters in any backend encoding + */ +#define MAX_MULTIBYTE_CHAR_LEN 4 + +/* * various definitions for EUC */ #define SS2 0x8e /* single shift 2 (JIS0201) */ @@ -36,36 +41,63 @@ typedef unsigned int pg_wchar; #define ISSJISHEAD(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) #define ISSJISTAIL(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc)) -/* - * Leading byte types or leading prefix byte for MULE internal code. - * See http://www.xemacs.org for more details. (there is a doc titled - * "XEmacs Internals Manual", "MULE Character Sets and Encodings" - * section.) - */ -/* - * Is a leading byte for "official" single byte encodings? - */ -#define IS_LC1(c) ((unsigned char)(c) >= 0x81 && (unsigned char)(c) <= 0x8d) -/* - * Is a prefix byte for "private" single byte encodings? - */ -#define IS_LCPRV1(c) ((unsigned char)(c) == 0x9a || (unsigned char)(c) == 0x9b) -/* - * Is a leading byte for "official" multibyte encodings? - */ -#define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) -/* - * Is a prefix byte for "private" multibyte encodings? - */ -#define IS_LCPRV2(c) ((unsigned char)(c) == 0x9c || (unsigned char)(c) == 0x9d) - /*---------------------------------------------------- - * leading characters + * MULE Internal Encoding (MIC) + * + * This encoding follows the design used within XEmacs; it is meant to + * subsume many externally-defined character sets. Each character includes + * identification of the character set it belongs to, so the encoding is + * general but somewhat bulky. + * + * Currently PostgreSQL supports 5 types of MULE character sets: + * + * 1) 1-byte ASCII characters. Each byte is below 0x80. + * + * 2) "Official" single byte charsets such as ISO-8859-1 (Latin1). + * Each MULE character consists of 2 bytes: LC1 + C1, where LC1 is + * an identifier for the charset (in the range 0x81 to 0x8d) and C1 + * is the character code (in the range 0xa0 to 0xff). + * + * 3) "Private" single byte charsets such as SISHENG. Each MULE + * character consists of 3 bytes: LCPRV1 + LC12 + C1, where LCPRV1 + * is a private-charset flag, LC12 is an identifier for the charset, + * and C1 is the character code (in the range 0xa0 to 0xff). + * LCPRV1 is either 0x9a (if LC12 is in the range 0xa0 to 0xdf) + * or 0x9b (if LC12 is in the range 0xe0 to 0xef). + * + * 4) "Official" multibyte charsets such as JIS X0208. Each MULE + * character consists of 3 bytes: LC2 + C1 + C2, where LC2 is + * an identifier for the charset (in the range 0x90 to 0x99) and C1 + * and C2 form the character code (each in the range 0xa0 to 0xff). + * + * 5) "Private" multibyte charsets such as CNS 11643-1992 Plane 3. + * Each MULE character consists of 4 bytes: LCPRV2 + LC22 + C1 + C2, + * where LCPRV2 is a private-charset flag, LC22 is an identifier for + * the charset, and C1 and C2 form the character code (each in the range + * 0xa0 to 0xff). LCPRV2 is either 0x9c (if LC22 is in the range 0xf0 + * to 0xf4) or 0x9d (if LC22 is in the range 0xf5 to 0xfe). + * + * "Official" encodings are those that have been assigned code numbers by + * the XEmacs project; "private" encodings have Postgres-specific charset + * identifiers. + * + * See the "XEmacs Internals Manual", available at http://www.xemacs.org, + * for more details. Note that for historical reasons, Postgres' + * private-charset flag values do not match what XEmacs says they should be, + * so this isn't really exactly MULE (not that private charsets would be + * interoperable anyway). + * + * Note that XEmacs's implementation is different from what emacs does. + * We follow emacs's implementaion, rathter than XEmacs's. *---------------------------------------------------- */ /* - * Official single byte encodings (0x81-0x8e) + * Charset identifiers (also called "leading bytes" in the MULE documentation) + */ + +/* + * Charset IDs for official single byte encodings (0x81-0x8e) */ #define LC_ISO8859_1 0x81 /* ISO8859 Latin 1 */ #define LC_ISO8859_2 0x82 /* ISO8859 Latin 2 */ @@ -79,37 +111,62 @@ typedef unsigned int pg_wchar; #define LC_JISX0201R 0x8a /* Japanese 1 byte Roman */ /* Note that 0x8b seems to be unused as of Emacs 20.7. * However, there might be a chance that 0x8b could be used - * in later version of Emacs. + * in later versions of Emacs. */ #define LC_KOI8_R 0x8b /* Cyrillic KOI8-R */ -#define LC_KOI8_U 0x8b /* Cyrillic KOI8-U */ #define LC_ISO8859_5 0x8c /* ISO8859 Cyrillic */ #define LC_ISO8859_9 0x8d /* ISO8859 Latin 5 (not supported yet) */ -/* #define FREE 0x8e free (unused) */ +#define LC_ISO8859_15 0x8e /* ISO8859 Latin 15 (not supported yet) */ +/* #define CONTROL_1 0x8f control characters (unused) */ -/* - * Unused - */ -#define CONTROL_1 0x8f /* control characters (unused) */ +/* Is a leading byte for "official" single byte encodings? */ +#define IS_LC1(c) ((unsigned char)(c) >= 0x81 && (unsigned char)(c) <= 0x8d) /* - * Official multibyte byte encodings (0x90-0x99) + * Charset IDs for official multibyte encodings (0x90-0x99) * 0x9a-0x9d are free. 0x9e and 0x9f are reserved. */ #define LC_JISX0208_1978 0x90 /* Japanese Kanji, old JIS (not supported) */ -/* #define FREE 0x90 free (unused) */ #define LC_GB2312_80 0x91 /* Chinese */ #define LC_JISX0208 0x92 /* Japanese Kanji (JIS X 0208) */ #define LC_KS5601 0x93 /* Korean */ #define LC_JISX0212 0x94 /* Japanese Kanji (JIS X 0212) */ #define LC_CNS11643_1 0x95 /* CNS 11643-1992 Plane 1 */ #define LC_CNS11643_2 0x96 /* CNS 11643-1992 Plane 2 */ -/* #define FREE 0x97 free (unused) */ +#define LC_JISX0213_1 0x97/* Japanese Kanji (JIS X 0213 Plane 1) (not + * supported) */ #define LC_BIG5_1 0x98 /* Plane 1 Chinese traditional (not supported) */ #define LC_BIG5_2 0x99 /* Plane 1 Chinese traditional (not supported) */ +/* Is a leading byte for "official" multibyte encodings? */ +#define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) + /* - * Private single byte encodings (0xa0-0xef) + * Postgres-specific prefix bytes for "private" single byte encodings + * (According to the MULE docs, we should be using 0x9e for this) + */ +#define LCPRV1_A 0x9a +#define LCPRV1_B 0x9b +#define IS_LCPRV1(c) ((unsigned char)(c) == LCPRV1_A || (unsigned char)(c) == LCPRV1_B) +#define IS_LCPRV1_A_RANGE(c) \ + ((unsigned char)(c) >= 0xa0 && (unsigned char)(c) <= 0xdf) +#define IS_LCPRV1_B_RANGE(c) \ + ((unsigned char)(c) >= 0xe0 && (unsigned char)(c) <= 0xef) + +/* + * Postgres-specific prefix bytes for "private" multibyte encodings + * (According to the MULE docs, we should be using 0x9f for this) + */ +#define LCPRV2_A 0x9c +#define LCPRV2_B 0x9d +#define IS_LCPRV2(c) ((unsigned char)(c) == LCPRV2_A || (unsigned char)(c) == LCPRV2_B) +#define IS_LCPRV2_A_RANGE(c) \ + ((unsigned char)(c) >= 0xf0 && (unsigned char)(c) <= 0xf4) +#define IS_LCPRV2_B_RANGE(c) \ + ((unsigned char)(c) >= 0xf5 && (unsigned char)(c) <= 0xfe) + +/* + * Charset IDs for private single byte encodings (0xa0-0xef) */ #define LC_SISHENG 0xa0/* Chinese SiSheng characters for * PinYin/ZhuYin (not supported) */ @@ -129,24 +186,36 @@ typedef unsigned int pg_wchar; #define LC_ARABIC_2_COLUMN 0xa8 /* Arabic 1-column (not supported) */ /* - * Private multibyte encodings (0xf0-0xff) + * Charset IDs for private multibyte encodings (0xf0-0xff) */ -#define LC_INDIAN_1_COLUMN 0xf0/* Indian charset for 1-column width glypps +#define LC_INDIAN_1_COLUMN 0xf0/* Indian charset for 1-column width glyphs * (not supported) */ -#define LC_TIBETAN_1_COLUMN 0xf1 /* Tibetan 1 column glyph (not supported) */ +#define LC_TIBETAN_1_COLUMN 0xf1/* Tibetan 1-column width glyphs (not + * supported) */ +#define LC_UNICODE_SUBSET_2 0xf2/* Unicode characters of the range + * U+2500..U+33FF. (not supported) */ +#define LC_UNICODE_SUBSET_3 0xf3/* Unicode characters of the range + * U+E000..U+FFFF. (not supported) */ +#define LC_UNICODE_SUBSET 0xf4/* Unicode characters of the range + * U+0100..U+24FF. (not supported) */ #define LC_ETHIOPIC 0xf5 /* Ethiopic characters (not supported) */ #define LC_CNS11643_3 0xf6 /* CNS 11643-1992 Plane 3 */ #define LC_CNS11643_4 0xf7 /* CNS 11643-1992 Plane 4 */ #define LC_CNS11643_5 0xf8 /* CNS 11643-1992 Plane 5 */ #define LC_CNS11643_6 0xf9 /* CNS 11643-1992 Plane 6 */ #define LC_CNS11643_7 0xfa /* CNS 11643-1992 Plane 7 */ -#define LC_INDIAN_2_COLUMN 0xfb/* Indian charset for 2-column width glypps +#define LC_INDIAN_2_COLUMN 0xfb/* Indian charset for 2-column width glyphs * (not supported) */ #define LC_TIBETAN 0xfc /* Tibetan (not supported) */ /* #define FREE 0xfd free (unused) */ /* #define FREE 0xfe free (unused) */ /* #define FREE 0xff free (unused) */ +/*---------------------------------------------------- + * end of MULE stuff + *---------------------------------------------------- + */ + /* * PostgreSQL encoding identifiers * @@ -204,7 +273,7 @@ typedef enum pg_enc /* PG_ENCODING_BE_LAST points to the above entry */ /* followings are for client encoding only */ - PG_SJIS, /* Shift JIS (Winindows-932) */ + PG_SJIS, /* Shift JIS (Windows-932) */ PG_BIG5, /* Big5 (Windows-950) */ PG_GBK, /* GBK (Windows-936) */ PG_UHC, /* UHC (Windows-949) */ @@ -234,33 +303,23 @@ typedef enum pg_enc #define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc) /* - * Encoding names with all aliases - */ -typedef struct pg_encname -{ - char *name; - pg_enc encoding; -} pg_encname; - -extern pg_encname pg_encname_tbl[]; -extern unsigned int pg_encname_tbl_sz; - -/* - * Careful: + * Table for mapping an encoding number to official encoding name and + * possibly other subsidiary data. Be careful to check encoding number + * before accessing a table entry! * * if (PG_VALID_ENCODING(encoding)) * pg_enc2name_tbl[ encoding ]; */ typedef struct pg_enc2name { - char *name; + const char *name; pg_enc encoding; #ifdef WIN32 unsigned codepage; /* codepage for WIN32 */ #endif } pg_enc2name; -extern pg_enc2name pg_enc2name_tbl[]; +extern const pg_enc2name pg_enc2name_tbl[]; /* * Encoding names for gettext @@ -271,7 +330,7 @@ typedef struct pg_enc2gettext const char *name; } pg_enc2gettext; -extern pg_enc2gettext pg_enc2gettext_tbl[]; +extern const pg_enc2gettext pg_enc2gettext_tbl[]; /* * pg_wchar stuff @@ -280,6 +339,10 @@ typedef int (*mb2wchar_with_len_converter) (const unsigned char *from, pg_wchar *to, int len); +typedef int (*wchar2mb_with_len_converter) (const pg_wchar *from, + unsigned char *to, + int len); + typedef int (*mblen_converter) (const unsigned char *mbstr); typedef int (*mbdisplaylen_converter) (const unsigned char *mbstr); @@ -292,13 +355,15 @@ typedef struct { mb2wchar_with_len_converter mb2wchar_with_len; /* convert a multibyte * string to a wchar */ + wchar2mb_with_len_converter wchar2mb_with_len; /* convert a wchar + * string to a multibyte */ mblen_converter mblen; /* get byte length of a char */ mbdisplaylen_converter dsplen; /* get display width of a char */ mbverifier mbverify; /* verify multibyte sequence */ int maxmblen; /* max bytes for a char in this encoding */ } pg_wchar_tbl; -extern pg_wchar_tbl pg_wchar_table[]; +extern const pg_wchar_tbl pg_wchar_table[]; /* * UTF-8 to local code conversion map @@ -366,12 +431,14 @@ extern int pg_valid_server_encoding_id(int encoding); * Remaining functions are not considered part of libpq's API, though many * of them do exist inside libpq. */ -extern pg_encname *pg_char_to_encname_struct(const char *name); - extern int pg_mb2wchar(const char *from, pg_wchar *to); extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len); extern int pg_encoding_mb2wchar_with_len(int encoding, const char *from, pg_wchar *to, int len); +extern int pg_wchar2mb(const pg_wchar *from, char *to); +extern int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len); +extern int pg_encoding_wchar2mb_with_len(int encoding, + const pg_wchar *from, char *to, int len); extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2); extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n); extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n); @@ -402,8 +469,12 @@ extern const char *pg_get_client_encoding_name(void); extern void SetDatabaseEncoding(int encoding); extern int GetDatabaseEncoding(void); extern const char *GetDatabaseEncodingName(void); -extern int GetPlatformEncoding(void); -extern void pg_bind_textdomain_codeset(const char *domainname); +extern void SetMessageEncoding(int encoding); +extern int GetMessageEncoding(void); + +#ifdef ENABLE_NLS +extern int pg_bind_textdomain_codeset(const char *domainname); +#endif extern int pg_valid_client_encoding(const char *name); extern int pg_valid_server_encoding(const char *name); @@ -443,9 +514,9 @@ extern void check_encoding_conversion_args(int src_encoding, int expected_src_encoding, int expected_dest_encoding); -extern void report_invalid_encoding(int encoding, const char *mbstr, int len); +extern void report_invalid_encoding(int encoding, const char *mbstr, int len) __attribute__((noreturn)); extern void report_untranslatable_char(int src_encoding, int dest_encoding, - const char *mbstr, int len); + const char *mbstr, int len) __attribute__((noreturn)); extern void pg_ascii2mic(const unsigned char *l, unsigned char *p, int len); extern void pg_mic2ascii(const unsigned char *mic, unsigned char *p, int len); @@ -463,7 +534,7 @@ extern void mic2latin_with_table(const unsigned char *mic, unsigned char *p, extern bool pg_utf8_islegal(const unsigned char *source, int length); #ifdef WIN32 -extern WCHAR *pgwin32_toUTF16(const char *str, int len, int *utf16len); +extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); #endif #endif /* PG_WCHAR_H */ diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f54522308c..a75a27cd67 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -15,7 +15,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/miscadmin.h @@ -33,6 +33,8 @@ #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" +#define InvalidPid (-1) + /***************************************************************************** * System interrupt and critical section handling @@ -42,7 +44,7 @@ * In both cases, we need to be able to clean up the current transaction * gracefully, so we can't respond to the interrupt instantaneously --- * there's no guarantee that internal data structures would be self-consistent - * if the code is interrupted at an arbitrary instant. Instead, the signal + * if the code is interrupted at an arbitrary instant. Instead, the signal * handlers set flags that are checked periodically during execution. * * The CHECK_FOR_INTERRUPTS() macro is called at strategically located spots @@ -51,13 +53,13 @@ * might sometimes be called in contexts that do *not* want to allow a cancel * or die interrupt. The HOLD_INTERRUPTS() and RESUME_INTERRUPTS() macros * allow code to ensure that no cancel or die interrupt will be accepted, - * even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt + * even if CHECK_FOR_INTERRUPTS() gets called in a subroutine. The interrupt * will be held off until CHECK_FOR_INTERRUPTS() is done outside any * HOLD_INTERRUPTS() ... RESUME_INTERRUPTS() section. * * Special mechanisms are used to let an interrupt be accepted when we are * waiting for a lock or when we are waiting for command input (but, of - * course, only if the interrupt holdoff counter is zero). See the + * course, only if the interrupt holdoff counter is zero). See the * related code for details. * * A lost connection is handled similarly, although the loss of connection @@ -68,7 +70,7 @@ * A related, but conceptually distinct, mechanism is the "critical section" * mechanism. A critical section not only holds off cancel/die interrupts, * but causes any ereport(ERROR) or ereport(FATAL) to become ereport(PANIC) - * --- that is, a system-wide reset is forced. Needless to say, only really + * --- that is, a system-wide reset is forced. Needless to say, only really * *critical* code should be marked as a critical section! Currently, this * mechanism is only used for XLOG-related code. * @@ -77,13 +79,13 @@ /* in globals.c */ /* these are marked volatile because they are set by signal handlers: */ extern PGDLLIMPORT volatile bool InterruptPending; -extern volatile bool QueryCancelPending; -extern volatile bool ProcDiePending; +extern PGDLLIMPORT volatile bool QueryCancelPending; +extern PGDLLIMPORT volatile bool ProcDiePending; extern volatile bool ClientConnectionLost; /* these are marked volatile because they are examined by signal handlers: */ -extern volatile bool ImmediateInterruptOK; +extern PGDLLIMPORT volatile bool ImmediateInterruptOK; extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount; extern PGDLLIMPORT volatile uint32 CritSectionCount; @@ -136,6 +138,7 @@ do { \ extern pid_t PostmasterPid; extern bool IsPostmasterEnvironment; extern PGDLLIMPORT bool IsUnderPostmaster; +extern bool IsBackgroundWorker; extern bool IsBinaryUpgrade; extern bool ExitOnAnyError; @@ -145,6 +148,7 @@ extern PGDLLIMPORT char *DataDir; extern PGDLLIMPORT int NBuffers; extern int MaxBackends; extern int MaxConnections; +extern int max_worker_processes; extern PGDLLIMPORT int MyProcPid; extern PGDLLIMPORT pg_time_t MyStartTime; @@ -203,8 +207,8 @@ extern PGDLLIMPORT Oid MyDatabaseTableSpace; #define DATEORDER_DMY 1 #define DATEORDER_MDY 2 -extern int DateStyle; -extern int DateOrder; +extern PGDLLIMPORT int DateStyle; +extern PGDLLIMPORT int DateOrder; /* * IntervalStyles @@ -218,16 +222,7 @@ extern int DateOrder; #define INTSTYLE_SQL_STANDARD 2 #define INTSTYLE_ISO_8601 3 -extern int IntervalStyle; - -/* - * HasCTZSet is true if user has set timezone as a numeric offset from UTC. - * If so, CTimeZone is the timezone offset in seconds (using the Unix-ish - * sign convention, ie, positive offset is west of UTC, rather than the - * SQL-ish convention that positive is east of UTC). - */ -extern bool HasCTZSet; -extern int CTimeZone; +extern PGDLLIMPORT int IntervalStyle; #define MAXTZLEN 10 /* max TZ name len, not counting tr. null */ @@ -280,7 +275,7 @@ extern int trace_recovery(int trace_level); /***************************************************************************** * pdir.h -- * - * POSTGRES directory path definitions. * + * POSTGRES directory path definitions. * *****************************************************************************/ /* flags to be OR'd to form sec_context */ @@ -314,7 +309,6 @@ extern void SetCurrentRoleId(Oid roleid, bool is_superuser); extern void SetDataDir(const char *dir); extern void ChangeToDataDir(void); -extern char *make_absolute_path(const char *path); /* in utils/misc/superuser.c */ extern bool superuser(void); /* current user is superuser */ @@ -323,7 +317,7 @@ extern bool superuser_arg(Oid roleid); /* given user is superuser */ /***************************************************************************** * pmod.h -- * - * POSTGRES processing mode definitions. * + * POSTGRES processing mode definitions. * *****************************************************************************/ /* @@ -338,11 +332,11 @@ extern bool superuser_arg(Oid roleid); /* given user is superuser */ * is used during the initial generation of template databases. * * Initialization mode: used while starting a backend, until all normal - * initialization is complete. Some code behaves differently when executed + * initialization is complete. Some code behaves differently when executed * in this mode to enable system bootstrapping. * - * If a POSTGRES binary is in normal mode, then all code may be executed - * normally. + * If a POSTGRES backend process is in normal mode, then all code may be + * executed normally. */ typedef enum ProcessingMode @@ -354,9 +348,11 @@ typedef enum ProcessingMode extern ProcessingMode Mode; -#define IsBootstrapProcessingMode() ((bool)(Mode == BootstrapProcessing)) -#define IsInitProcessingMode() ((bool)(Mode == InitProcessing)) -#define IsNormalProcessingMode() ((bool)(Mode == NormalProcessing)) +#define IsBootstrapProcessingMode() (Mode == BootstrapProcessing) +#define IsInitProcessingMode() (Mode == InitProcessing) +#define IsNormalProcessingMode() (Mode == NormalProcessing) + +#define GetProcessingMode() Mode #define SetProcessingMode(mode) \ do { \ @@ -366,16 +362,48 @@ extern ProcessingMode Mode; Mode = (mode); \ } while(0) -#define GetProcessingMode() Mode + +/* + * Auxiliary-process type identifiers. These used to be in bootstrap.h + * but it seems saner to have them here, with the ProcessingMode stuff. + * The MyAuxProcType global is defined and set in bootstrap.c. + */ + +typedef enum +{ + NotAnAuxProcess = -1, + CheckerProcess = 0, + BootstrapProcess, + StartupProcess, + BgWriterProcess, + CheckpointerProcess, + WalWriterProcess, + WalReceiverProcess, +#ifdef PGXC + PoolerProcess, +#endif + + NUM_AUXPROCTYPES /* Must be last! */ +} AuxProcType; + +extern AuxProcType MyAuxProcType; + +#define AmBootstrapProcess() (MyAuxProcType == BootstrapProcess) +#define AmStartupProcess() (MyAuxProcType == StartupProcess) +#define AmBackgroundWriterProcess() (MyAuxProcType == BgWriterProcess) +#define AmCheckpointerProcess() (MyAuxProcType == CheckpointerProcess) +#define AmWalWriterProcess() (MyAuxProcType == WalWriterProcess) +#define AmWalReceiverProcess() (MyAuxProcType == WalReceiverProcess) /***************************************************************************** * pinit.h -- * - * POSTGRES initialization and cleanup definitions. * + * POSTGRES initialization and cleanup definitions. * *****************************************************************************/ /* in utils/init/postinit.c */ extern void pg_split_opts(char **argv, int *argcp, char *optstr); +extern void InitializeMaxBackends(void); extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, char *out_dbname); extern void BaseInit(void); @@ -383,6 +411,7 @@ extern void BaseInit(void); /* in utils/init/miscinit.c */ extern bool IgnoreSystemIndexes; extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress; +extern char *session_preload_libraries_string; extern char *shared_preload_libraries_string; extern char *local_preload_libraries_string; @@ -394,12 +423,12 @@ extern char *local_preload_libraries_string; * 2 data directory path * 3 postmaster start timestamp (time_t representation) * 4 port number - * 5 socket directory path (empty on Windows) + * 5 first Unix socket directory path (empty if none) * 6 first listen_address (IP address or "*"; empty if no TCP port) * 7 shared memory key (not present on Windows) * * Lines 6 and up are added via AddToDataDirLockFile() after initial file - * creation; they have to be ordered according to time of addition. + * creation. * * The socket lock file, if used, has the same contents as lines 1-5. */ @@ -412,14 +441,15 @@ extern char *local_preload_libraries_string; #define LOCK_FILE_LINE_SHMEM_KEY 7 extern void CreateDataDirLockFile(bool amPostmaster); -extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster); -extern void TouchSocketLockFile(void); +extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster, + const char *socketDir); +extern void TouchSocketLockFiles(void); extern void AddToDataDirLockFile(int target_line, const char *str); extern void ValidatePgVersion(const char *path); extern void process_shared_preload_libraries(void); -extern void process_local_preload_libraries(void); +extern void process_session_preload_libraries(void); extern void pg_bindtextdomain(const char *domain); -extern bool is_authenticated_user_replication_role(void); +extern bool has_rolreplication(Oid roleid); /* in access/transam/xlog.c */ extern bool BackupInProgress(void); diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h index bcca70d2b9..f77060844f 100644 --- a/src/include/nodes/bitmapset.h +++ b/src/include/nodes/bitmapset.h @@ -11,7 +11,7 @@ * bms_is_empty() in preference to testing for NULL.) * * - * Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/nodes/bitmapset.h * diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 93b5380051..6ead821e1a 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/execnodes.h @@ -96,14 +96,14 @@ typedef struct ExprContext_CB * * This class holds the "current context" information * needed to evaluate expressions for doing tuple qualifications - * and tuple projections. For example, if an expression refers + * and tuple projections. For example, if an expression refers * to an attribute in the current inner tuple then we need to know * what the current inner tuple is and so we look at the expression * context. * * There are two memory contexts associated with an ExprContext: * * ecxt_per_query_memory is a query-lifespan context, typically the same - * context the ExprContext node itself is allocated in. This context + * context the ExprContext node itself is allocated in. This context * can be used for purposes such as storing function call cache info. * * ecxt_per_tuple_memory is a short-term context for expression results. * As the name suggests, it will typically be reset once per tuple, @@ -149,7 +149,7 @@ typedef struct ExprContext /* Link to containing EState (NULL if a standalone ExprContext) */ struct EState *ecxt_estate; - /* Functions to call back when ExprContext is shut down */ + /* Functions to call back when ExprContext is shut down or rescanned */ ExprContext_CB *ecxt_callbacks; } ExprContext; @@ -206,9 +206,9 @@ typedef struct ReturnSetInfo * Nodes which need to do projections create one of these. * * ExecProject() evaluates the tlist, forms a tuple, and stores it - * in the given slot. Note that the result will be a "virtual" tuple + * in the given slot. Note that the result will be a "virtual" tuple * unless ExecMaterializeSlot() is then called to force it to be - * converted to a physical tuple. The slot must have a tupledesc + * converted to a physical tuple. The slot must have a tupledesc * that matches the output of the tlist! * * The planner very often produces tlists that consist entirely of @@ -263,7 +263,7 @@ typedef struct ProjectionInfo * in emitted tuples. For example, when we do an UPDATE query, * the planner adds a "junk" entry to the targetlist so that the tuples * returned to ExecutePlan() contain an extra attribute: the ctid of - * the tuple to be updated. This is needed to do the update, but we + * the tuple to be updated. This is needed to do the update, but we * don't want the ctid to be part of the stored new tuple! So, we * apply a "junk filter" to remove the junk attributes and form the * real output tuple. The junkfilter code also provides routines to @@ -278,7 +278,8 @@ typedef struct ProjectionInfo * resultSlot: tuple slot used to hold cleaned tuple. * junkAttNo: not used by junkfilter code. Can be used by caller * to remember the attno of a specific junk attribute - * (execMain.c stores the "ctid" attno here). + * (nodeModifyTable.c keeps the "ctid" or "wholerow" + * attno here). * ---------------- */ typedef struct JunkFilter @@ -308,6 +309,10 @@ typedef struct JunkFilter * TrigFunctions cached lookup info for trigger functions * TrigWhenExprs array of trigger WHEN expr states * TrigInstrument optional runtime measurements for triggers + * FdwRoutine FDW callback functions, if foreign table + * FdwState available to save private state of FDW + * WithCheckOptions list of WithCheckOption's for views + * WithCheckOptionExprs list of WithCheckOption expr states * ConstraintExprs array of constraint-checking expr states * junkFilter for removing junk attributes from tuples * projectReturning for computing a RETURNING list @@ -325,6 +330,10 @@ typedef struct ResultRelInfo FmgrInfo *ri_TrigFunctions; List **ri_TrigWhenExprs; Instrumentation *ri_TrigInstrument; + struct FdwRoutine *ri_FdwRoutine; + void *ri_FdwState; + List *ri_WithCheckOptions; + List *ri_WithCheckOptionExprs; List **ri_ConstraintExprs; JunkFilter *ri_junkFilter; ProjectionInfo *ri_projectReturning; @@ -401,7 +410,7 @@ typedef struct EState /* * These fields are for re-evaluating plan quals when an updated tuple is - * substituted in READ COMMITTED mode. es_epqTuple[] contains tuples that + * substituted in READ COMMITTED mode. es_epqTuple[] contains tuples that * scan plan nodes should return instead of whatever they'd normally * return, or NULL if nothing to return; es_epqTupleSet[] is true if a * particular array entry is valid; and es_epqScanDone[] is state to @@ -416,9 +425,9 @@ typedef struct EState /* * ExecRowMark - - * runtime representation of FOR UPDATE/SHARE clauses + * runtime representation of FOR [KEY] UPDATE/SHARE clauses * - * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we should have an + * When doing UPDATE, DELETE, or SELECT FOR [KEY] UPDATE/SHARE, we should have an * ExecRowMark for each non-target relation in the query (except inheritance * parent RTEs, which can be ignored at runtime). See PlanRowMark for details * about most of the fields. In addition to fields directly derived from @@ -439,7 +448,7 @@ typedef struct ExecRowMark /* * ExecAuxRowMark - - * additional runtime representation of FOR UPDATE/SHARE clauses + * additional runtime representation of FOR [KEY] UPDATE/SHARE clauses * * Each LockRows and ModifyTable node keeps a list of the rowmarks it needs to * deal with. In addition to a pointer to the related entry in es_rowMarks, @@ -574,13 +583,26 @@ typedef struct GenericExprState } GenericExprState; /* ---------------- + * WholeRowVarExprState node + * ---------------- + */ +typedef struct WholeRowVarExprState +{ + ExprState xprstate; + struct PlanState *parent; /* parent PlanState, or NULL if none */ + JunkFilter *wrv_junkFilter; /* JunkFilter to remove resjunk cols */ +} WholeRowVarExprState; + +/* ---------------- * AggrefExprState node * ---------------- */ typedef struct AggrefExprState { ExprState xprstate; - List *args; /* states of argument expressions */ + List *aggdirectargs; /* states of direct-argument expressions */ + List *args; /* states of aggregated-argument expressions */ + ExprState *aggfilter; /* state of FILTER expression, if any */ int aggno; /* ID number for agg within its plan node */ } AggrefExprState; @@ -592,6 +614,7 @@ typedef struct WindowFuncExprState { ExprState xprstate; List *args; /* states of argument expressions */ + ExprState *aggfilter; /* FILTER expression */ int wfuncno; /* ID number for wfunc within its plan node */ } WindowFuncExprState; @@ -646,7 +669,7 @@ typedef struct FuncExprState /* * In some cases we need to compute a tuple descriptor for the function's - * output. If so, it's stored here. + * output. If so, it's stored here. */ TupleDesc funcResultDesc; bool funcReturnsTuple; /* valid when funcResultDesc isn't @@ -670,7 +693,7 @@ typedef struct FuncExprState /* * Flag to remember whether we have registered a shutdown callback for - * this FuncExprState. We do so only if funcResultStore or setArgsValid + * this FuncExprState. We do so only if funcResultStore or setArgsValid * has been set at least once (since all the callback is for is to release * the tuplestore or clear setArgsValid). */ @@ -721,6 +744,7 @@ typedef struct SubPlanState ExprState *testexpr; /* state of combining expression */ List *args; /* states of argument expression(s) */ HeapTuple curTuple; /* copy of most recent tuple from subplan */ + Datum curArray; /* most recent array from ARRAY() subplan */ /* these are used when hashing the subselect's output: */ ProjectionInfo *projLeft; /* for projecting lefthand exprs */ ProjectionInfo *projRight; /* for projecting subselect output */ @@ -1104,10 +1128,8 @@ typedef struct AppendState * nkeys number of sort key columns * sortkeys sort keys in SortSupport representation * slots current output tuple of each subplan - * heap heap of active tuples (represented as array indexes) - * heap_size number of active heap entries + * heap heap of active tuples * initialized true if we have fetched first tuple from each subplan - * last_slot last subplan fetched from (which must be re-called) * ---------------- */ typedef struct MergeAppendState @@ -1118,10 +1140,8 @@ typedef struct MergeAppendState int ms_nkeys; SortSupport ms_sortkeys; /* array of length ms_nkeys */ TupleTableSlot **ms_slots; /* array of length ms_nplans */ - int *ms_heap; /* array of length ms_nplans */ - int ms_heap_size; /* current active length of ms_heap[] */ + struct binaryheap *ms_heap; /* binary heap of slot indices */ bool ms_initialized; /* are subplans started? */ - int ms_last_slot; /* last subplan slot we returned from */ } MergeAppendState; /* ---------------- @@ -1334,6 +1354,8 @@ typedef struct BitmapIndexScanState * tbm bitmap obtained from child index scan(s) * tbmiterator iterator for scanning current pages * tbmres current-page data + * exact_pages total number of exact pages retrieved + * lossy_pages total number of lossy pages retrieved * prefetch_iterator iterator for prefetching ahead of current page * prefetch_pages # pages prefetch iterator is ahead of current * prefetch_target target prefetch distance @@ -1346,6 +1368,8 @@ typedef struct BitmapHeapScanState TIDBitmap *tbm; TBMIterator *tbmiterator; TBMIterateResult *tbmres; + long exact_pages; + long lossy_pages; TBMIterator *prefetch_iterator; int prefetch_pages; int prefetch_target; @@ -1392,18 +1416,26 @@ typedef struct SubqueryScanState * function appearing in FROM (typically a function returning set). * * eflags node's capability flags - * tupdesc expected return tuple description - * tuplestorestate private state of tuplestore.c - * funcexpr state for function expression being evaluated + * ordinality is this scan WITH ORDINALITY? + * simple true if we have 1 function and no ordinality + * ordinal current ordinal column value + * nfuncs number of functions being executed + * funcstates per-function execution states (private in + * nodeFunctionscan.c) * ---------------- */ +struct FunctionScanPerFuncState; + typedef struct FunctionScanState { ScanState ss; /* its first field is NodeTag */ int eflags; - TupleDesc tupdesc; - Tuplestorestate *tuplestorestate; - ExprState *funcexpr; + bool ordinality; + bool simple; + int64 ordinal; + int nfuncs; + struct FunctionScanPerFuncState *funcstates; /* array of length + * nfuncs */ } FunctionScanState; /* ---------------- @@ -1461,7 +1493,7 @@ typedef struct CteScanState * WorkTableScanState information * * WorkTableScan nodes are used to scan the work table created by - * a RecursiveUnion node. We locate the RecursiveUnion node + * a RecursiveUnion node. We locate the RecursiveUnion node * during executor startup. * ---------------- */ @@ -1693,6 +1725,7 @@ typedef struct AggState AggStatePerAgg peragg; /* per-Aggref information */ MemoryContext aggcontext; /* memory context for long-lived data */ ExprContext *tmpcontext; /* econtext for input expressions */ + AggStatePerAgg curperagg; /* identifies currently active aggregate */ bool agg_done; /* indicates completion of Agg scan */ /* these fields are used in AGG_PLAIN and AGG_SORTED modes: */ AggStatePerGroup pergroup; /* per-Aggref-per-group working state */ @@ -1750,7 +1783,8 @@ typedef struct WindowAggState Datum endOffsetValue; /* result of endOffset evaluation */ MemoryContext partcontext; /* context for partition-lifespan data */ - MemoryContext aggcontext; /* context for each aggregate data */ + MemoryContext aggcontext; /* shared context for aggregate working data */ + MemoryContext curaggcontext; /* current aggregate's working data */ ExprContext *tmpcontext; /* short-term evaluation context */ bool all_first; /* true if the scan is starting */ @@ -1778,7 +1812,7 @@ typedef struct WindowAggState * UniqueState information * * Unique nodes are used "on top of" sort nodes to discard - * duplicate tuples returned from the sort phase. Basically + * duplicate tuples returned from the sort phase. Basically * all it does is compare the current tuple from the subplan * with the previously fetched tuple (stored in its result slot). * If the two are identical in all interesting fields, then @@ -1837,7 +1871,7 @@ typedef struct SetOpState /* ---------------- * LockRowsState information * - * LockRows nodes are used to enforce FOR UPDATE/FOR SHARE locking. + * LockRows nodes are used to enforce FOR [KEY] UPDATE/SHARE locking. * ---------------- */ typedef struct LockRowsState diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index a6dffe6110..e108b852a0 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -4,7 +4,7 @@ * prototypes for the creator functions (for primitive nodes) * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/makefuncs.h @@ -75,6 +75,8 @@ extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod); extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat); +extern FuncCall *makeFuncCall(List *name, List *args, int location); + extern DefElem *makeDefElem(char *name, Node *arg); extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg, DefElemAction defaction); diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h index 503d59f3ba..f79ebd423f 100644 --- a/src/include/nodes/memnodes.h +++ b/src/include/nodes/memnodes.h @@ -4,7 +4,7 @@ * POSTGRES memory context node definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/memnodes.h diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h index e609e4bae2..f9afdb6916 100644 --- a/src/include/nodes/nodeFuncs.h +++ b/src/include/nodes/nodeFuncs.h @@ -3,7 +3,7 @@ * nodeFuncs.h * Various general-purpose manipulations of Node trees * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/nodeFuncs.h @@ -30,6 +30,7 @@ extern Oid exprType(const Node *expr); extern int32 exprTypmod(const Node *expr); extern bool exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod); extern Node *relabel_to_typmod(Node *expr, int32 typmod); +extern Node *strip_implicit_coercions(Node *node); extern bool expression_returns_set(Node *clause); extern Oid exprCollation(const Node *expr); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 2c9cf5ee15..601ea16229 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -217,6 +217,7 @@ typedef enum NodeTag */ T_ExprState = 400, T_GenericExprState, + T_WholeRowVarExprState, T_AggrefExprState, T_WindowFuncExprState, T_ArrayRefExprState, @@ -271,6 +272,7 @@ typedef enum NodeTag T_RestrictInfo, T_PlaceHolderVar, T_SpecialJoinInfo, + T_LateralJoinInfo, T_AppendRelInfo, T_PlaceHolderInfo, T_MinMaxAggInfo, @@ -400,11 +402,17 @@ typedef enum NodeTag T_RemoteStmt, #endif T_AlterTableSpaceOptionsStmt, + T_AlterTableSpaceMoveStmt, T_SecLabelStmt, T_CreateForeignTableStmt, T_CreateExtensionStmt, T_AlterExtensionStmt, T_AlterExtensionContentsStmt, + T_CreateEventTrigStmt, + T_AlterEventTrigStmt, + T_RefreshMatViewStmt, + T_ReplicaIdentityStmt, + T_AlterSystemStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) @@ -431,6 +439,8 @@ typedef enum NodeTag T_Constraint, T_DefElem, T_RangeTblEntry, + T_RangeTblFunction, + T_WithCheckOption, T_SortGroupClause, T_WindowClause, T_PrivGrantee, @@ -450,7 +460,10 @@ typedef enum NodeTag */ T_IdentifySystemCmd, T_BaseBackupCmd, + T_CreateReplicationSlotCmd, + T_DropReplicationSlotCmd, T_StartReplicationCmd, + T_TimeLineHistoryCmd, /* * TAGS FOR RANDOM OTHER STUFF @@ -461,6 +474,7 @@ typedef enum NodeTag * pass multiple object types through the same pointer). */ T_TriggerData = 950, /* in commands/trigger.h */ + T_EventTriggerData, /* in commands/event_trigger.h */ T_ReturnSetInfo, /* in nodes/execnodes.h */ T_WindowObjectData, /* private in nodeWindowAgg.c */ T_TIDBitmap, /* in nodes/tidbitmap.h */ @@ -615,7 +629,7 @@ typedef enum JoinType /* * Semijoins and anti-semijoins (as defined in relational theory) do not * appear in the SQL JOIN syntax, but there are standard idioms for - * representing them (e.g., using EXISTS). The planner recognizes these + * representing them (e.g., using EXISTS). The planner recognizes these * cases and converts them to joins. So the planner and executor must * support these codes. NOTE: in JOIN_SEMI output, it is unspecified * which matching RHS row is joined to. In JOIN_ANTI output, the row is @@ -639,7 +653,7 @@ typedef enum JoinType /* * OUTER joins are those for which pushed-down quals must behave differently * from the join's own quals. This is in fact everything except INNER and - * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols + * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols * since those are temporary proxies for what will eventually be an INNER * join. * diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h index a7cdd0d888..07c2738252 100644 --- a/src/include/nodes/params.h +++ b/src/include/nodes/params.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/params.h @@ -27,20 +27,20 @@ struct ParseState; * ParamListInfo * * ParamListInfo arrays are used to pass parameters into the executor - * for parameterized plans. Each entry in the array defines the value + * for parameterized plans. Each entry in the array defines the value * to be substituted for a PARAM_EXTERN parameter. The "paramid" * of a PARAM_EXTERN Param can range from 1 to numParams. * * Although parameter numbers are normally consecutive, we allow * ptype == InvalidOid to signal an unused array entry. * - * pflags is a flags field. Currently the only used bit is: + * pflags is a flags field. Currently the only used bit is: * PARAM_FLAG_CONST signals the planner that it may treat this parameter * as a constant (i.e., generate a plan that works only for this value * of the parameter). * * There are two hook functions that can be associated with a ParamListInfo - * array to support dynamic parameter handling. First, if paramFetch + * array to support dynamic parameter handling. First, if paramFetch * isn't null and the executor requires a value for an invalid parameter * (one with ptype == InvalidOid), the paramFetch hook is called to give * it a chance to fill in the parameter value. Second, a parserSetup @@ -90,7 +90,7 @@ typedef struct ParamListInfoData * es_param_exec_vals or ecxt_param_exec_vals. * * If execPlan is not NULL, it points to a SubPlanState node that needs - * to be executed to produce the value. (This is done so that we can have + * to be executed to produce the value. (This is done so that we can have * lazy evaluation of InitPlans: they aren't executed until/unless a * result value is needed.) Otherwise the value is assumed to be valid * when needed. diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 4b1b00bd28..3aa13d8518 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -15,7 +15,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -84,7 +84,7 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */ #define ACL_CONNECT (1<<11) /* for databases */ #define N_ACL_RIGHTS 12 /* 1 plus the last 1<<x */ #define ACL_NO_RIGHTS 0 -/* Currently, SELECT ... FOR UPDATE/FOR SHARE requires UPDATE privileges */ +/* Currently, SELECT ... FOR [KEY] UPDATE/SHARE requires UPDATE privileges */ #define ACL_SELECT_FOR_UPDATE ACL_UPDATE @@ -129,7 +129,7 @@ typedef struct Query bool hasDistinctOn; /* distinctClause is from DISTINCT ON */ bool hasRecursive; /* WITH RECURSIVE was specified */ bool hasModifyingCTE; /* has INSERT/UPDATE/DELETE in WITH */ - bool hasForUpdate; /* FOR UPDATE or FOR SHARE was specified */ + bool hasForUpdate; /* FOR [KEY] UPDATE/SHARE was specified */ List *cteList; /* WITH list (of CommonTableExpr's) */ @@ -138,6 +138,8 @@ typedef struct Query List *targetList; /* target list (of TargetEntry) */ + List *withCheckOptions; /* a list of WithCheckOption's */ + List *returningList; /* return-values list (of TargetEntry) */ List *groupClause; /* a list of SortGroupClause's */ @@ -180,7 +182,7 @@ typedef struct Query * Supporting data structures for Parse Trees * * Most of these node types appear in raw parsetrees output by the grammar, - * and get transformed to something else by the analyzer. A few of them + * and get transformed to something else by the analyzer. A few of them * are used as-is in transformed querytrees. ****************************************************************************/ @@ -194,7 +196,7 @@ typedef struct Query * be prespecified in typemod, otherwise typemod is unused. * * If pct_type is TRUE, then names is actually a field name and we look up - * the type of that field. Otherwise (the normal case), names is a type + * the type of that field. Otherwise (the normal case), names is a type * name possibly qualified with schema and database name. */ typedef struct TypeName @@ -213,7 +215,7 @@ typedef struct TypeName /* * ColumnRef - specifies a reference to a column, or possibly a whole tuple * - * The "fields" list must be nonempty. It can contain string Value nodes + * The "fields" list must be nonempty. It can contain string Value nodes * (representing names) and A_Star nodes (representing occurrence of a '*'). * Currently, A_Star must appear only as the last list element --- the grammar * is responsible for enforcing this! @@ -302,12 +304,16 @@ typedef struct CollateClause /* * FuncCall - a function or aggregate invocation * - * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)'. + * agg_order (if not NIL) indicates we saw 'foo(... ORDER BY ...)', or if + * agg_within_group is true, it was 'foo(...) WITHIN GROUP (ORDER BY ...)'. * agg_star indicates we saw a 'foo(*)' construct, while agg_distinct * indicates we saw 'foo(DISTINCT ...)'. In any of these cases, the * construct *must* be an aggregate call. Otherwise, it might be either an - * aggregate or some other kind of function. However, if OVER is present - * it had better be an aggregate or window function. + * aggregate or some other kind of function. However, if FILTER or OVER is + * present it had better be an aggregate or window function. + * + * Normally, you'd initialize this via makeFuncCall() and then only change the + * parts of the struct its defaults don't match afterwards, as needed. */ typedef struct FuncCall { @@ -315,6 +321,8 @@ typedef struct FuncCall List *funcname; /* qualified name of function */ List *args; /* the arguments (list of exprs) */ List *agg_order; /* ORDER BY (list of SortBy) */ + Node *agg_filter; /* FILTER clause, if any */ + bool agg_within_group; /* ORDER BY appeared in WITHIN GROUP */ bool agg_star; /* argument was really '*' */ bool agg_distinct; /* arguments were labeled DISTINCT */ bool func_variadic; /* last argument was labeled VARIADIC */ @@ -474,17 +482,32 @@ typedef struct WindowDef typedef struct RangeSubselect { NodeTag type; + bool lateral; /* does it have LATERAL prefix? */ Node *subquery; /* the untransformed sub-select clause */ Alias *alias; /* table alias & optional column aliases */ } RangeSubselect; /* * RangeFunction - function call appearing in a FROM clause + * + * functions is a List because we use this to represent the construct + * ROWS FROM(func1(...), func2(...), ...). Each element of this list is a + * two-element sublist, the first element being the untransformed function + * call tree, and the second element being a possibly-empty list of ColumnDef + * nodes representing any columndef list attached to that function within the + * ROWS FROM() syntax. + * + * alias and coldeflist represent any alias and/or columndef list attached + * at the top level. (We disallow coldeflist appearing both here and + * per-function, but that's checked in parse analysis, not by the grammar.) */ typedef struct RangeFunction { NodeTag type; - Node *funccallnode; /* untransformed function call tree */ + bool lateral; /* does it have LATERAL prefix? */ + bool ordinality; /* does it have WITH ORDINALITY suffix? */ + bool is_rowsfrom; /* is result of ROWS FROM() syntax? */ + List *functions; /* per-function information, see above */ Alias *alias; /* table alias & optional column aliases */ List *coldeflist; /* list of ColumnDef nodes to describe result * of function returning RECORD */ @@ -497,7 +520,7 @@ typedef struct RangeFunction * in either "raw" form (an untransformed parse tree) or "cooked" form * (a post-parse-analysis, executable expression tree), depending on * how this ColumnDef node was created (by parsing, or by inheritance - * from an existing relation). We should never have both in the same node! + * from an existing relation). We should never have both in the same node! * * Similarly, we may have a COLLATE specification in either raw form * (represented as a CollateClause with arg==NULL) or cooked form @@ -524,6 +547,7 @@ typedef struct ColumnDef Oid collOid; /* collation OID (InvalidOid if not set) */ List *constraints; /* other constraints on column */ List *fdwoptions; /* per-column FDW options */ + int location; /* parse location, or -1 if none/unknown */ } ColumnDef; /* @@ -568,7 +592,7 @@ typedef struct IndexElem /* * DefElem - a generic "name = value" option definition * - * In some contexts the name can be qualified. Also, certain SQL commands + * In some contexts the name can be qualified. Also, certain SQL commands * allow a SET/ADD/DROP action to be attached to option settings, so it's * convenient to carry a field for that too. (Note: currently, it is our * practice that the grammar allows namespace and action only in statements @@ -593,18 +617,28 @@ typedef struct DefElem } DefElem; /* - * LockingClause - raw representation of FOR UPDATE/SHARE options + * LockingClause - raw representation of FOR [NO KEY] UPDATE/[KEY] SHARE + * options * - * Note: lockedRels == NIL means "all relations in query". Otherwise it + * Note: lockedRels == NIL means "all relations in query". Otherwise it * is a list of RangeVar nodes. (We use RangeVar mainly because it carries * a location field --- currently, parse analysis insists on unqualified * names in LockingClause.) */ +typedef enum LockClauseStrength +{ + /* order is important -- see applyLockingClause */ + LCS_FORKEYSHARE, + LCS_FORSHARE, + LCS_FORNOKEYUPDATE, + LCS_FORUPDATE +} LockClauseStrength; + typedef struct LockingClause { NodeTag type; - List *lockedRels; /* FOR UPDATE or FOR SHARE relations */ - bool forUpdate; /* true = FOR UPDATE, false = FOR SHARE */ + List *lockedRels; /* FOR [KEY] UPDATE/SHARE relations */ + LockClauseStrength strength; bool noWait; /* NOWAIT option */ } LockingClause; @@ -650,20 +684,20 @@ typedef struct XmlSerialize * * In RELATION RTEs, the colnames in both alias and eref are indexed by * physical attribute number; this means there must be colname entries for - * dropped columns. When building an RTE we insert empty strings ("") for - * dropped columns. Note however that a stored rule may have nonempty + * dropped columns. When building an RTE we insert empty strings ("") for + * dropped columns. Note however that a stored rule may have nonempty * colnames for columns dropped since the rule was created (and for that * matter the colnames might be out of date due to column renamings). - * The same comments apply to FUNCTION RTEs when the function's return type + * The same comments apply to FUNCTION RTEs when a function's return type * is a named composite type. * * In JOIN RTEs, the colnames in both alias and eref are one-to-one with * joinaliasvars entries. A JOIN RTE will omit columns of its inputs when - * those columns are known to be dropped at parse time. Again, however, + * those columns are known to be dropped at parse time. Again, however, * a stored rule might contain entries for columns dropped since the rule - * was created. (This is only possible for columns not actually referenced + * was created. (This is only possible for columns not actually referenced * in the rule.) When loading a stored rule, we replace the joinaliasvars - * items for any such columns with NULL Consts. (We can't simply delete + * items for any such columns with null pointers. (We can't simply delete * them from the joinaliasvars list, because that would affect the attnums * of Vars referencing the rest of the list.) * @@ -680,7 +714,7 @@ typedef struct XmlSerialize * decompiled queries. * * requiredPerms and checkAsUser specify run-time access permissions - * checks to be performed at query startup. The user must have *all* + * checks to be performed at query startup. The user must have *all* * of the permissions that are OR'd together in requiredPerms (zero * indicates no permissions checking). If checkAsUser is not zero, * then do the permissions checks using the access rights of that user, @@ -738,34 +772,38 @@ typedef struct RangeTblEntry * Fields valid for a subquery RTE (else NULL): */ Query *subquery; /* the sub-query */ - bool security_barrier; /* subquery from security_barrier view */ + bool security_barrier; /* is from security_barrier view? */ /* * Fields valid for a join RTE (else NULL/zero): * - * joinaliasvars is a list of Vars or COALESCE expressions corresponding - * to the columns of the join result. An alias Var referencing column K - * of the join result can be replaced by the K'th element of joinaliasvars - * --- but to simplify the task of reverse-listing aliases correctly, we - * do not do that until planning time. In a Query loaded from a stored - * rule, it is also possible for joinaliasvars items to be NULL Consts, - * denoting columns dropped since the rule was made. + * joinaliasvars is a list of (usually) Vars corresponding to the columns + * of the join result. An alias Var referencing column K of the join + * result can be replaced by the K'th element of joinaliasvars --- but to + * simplify the task of reverse-listing aliases correctly, we do not do + * that until planning time. In detail: an element of joinaliasvars can + * be a Var of one of the join's input relations, or such a Var with an + * implicit coercion to the join's output column type, or a COALESCE + * expression containing the two input column Vars (possibly coerced). + * Within a Query loaded from a stored rule, it is also possible for + * joinaliasvars items to be null pointers, which are placeholders for + * (necessarily unreferenced) columns dropped since the rule was made. + * Also, once planning begins, joinaliasvars items can be almost anything, + * as a result of subquery-flattening substitutions. */ JoinType jointype; /* type of join */ List *joinaliasvars; /* list of alias-var expansions */ /* - * Fields valid for a function RTE (else NULL): + * Fields valid for a function RTE (else NIL/zero): * - * If the function returns RECORD, funccoltypes lists the column types - * declared in the RTE's column type specification, funccoltypmods lists - * their declared typmods, funccolcollations their collations. Otherwise, - * those fields are NIL. + * When funcordinality is true, the eref->colnames list includes an alias + * for the ordinality column. The ordinality column is otherwise + * implicit, and must be accounted for "by hand" in places such as + * expandRTE(). */ - Node *funcexpr; /* expression tree for func call */ - List *funccoltypes; /* OID list of column type OIDs */ - List *funccoltypmods; /* integer list of column typmods */ - List *funccolcollations; /* OID list of column collation OIDs */ + List *functions; /* list of RangeTblFunction nodes */ + bool funcordinality; /* is this called WITH ORDINALITY? */ /* * Fields valid for a values RTE (else NIL): @@ -788,15 +826,61 @@ typedef struct RangeTblEntry */ Alias *alias; /* user-written alias clause, if any */ Alias *eref; /* expanded reference names */ + bool lateral; /* subquery, function, or values is LATERAL? */ bool inh; /* inheritance requested? */ bool inFromCl; /* present in FROM clause? */ AclMode requiredPerms; /* bitmask of required access permissions */ Oid checkAsUser; /* if valid, check access as this role */ Bitmapset *selectedCols; /* columns needing SELECT permission */ Bitmapset *modifiedCols; /* columns needing INSERT/UPDATE permission */ + List *securityQuals; /* any security barrier quals to apply */ } RangeTblEntry; /* + * RangeTblFunction - + * RangeTblEntry subsidiary data for one function in a FUNCTION RTE. + * + * If the function had a column definition list (required for an + * otherwise-unspecified RECORD result), funccolnames lists the names given + * in the definition list, funccoltypes lists their declared column types, + * funccoltypmods lists their typmods, funccolcollations their collations. + * Otherwise, those fields are NIL. + * + * Notice we don't attempt to store info about the results of functions + * returning named composite types, because those can change from time to + * time. We do however remember how many columns we thought the type had + * (including dropped columns!), so that we can successfully ignore any + * columns added after the query was parsed. + */ +typedef struct RangeTblFunction +{ + NodeTag type; + + Node *funcexpr; /* expression tree for func call */ + int funccolcount; /* number of columns it contributes to RTE */ + /* These fields record the contents of a column definition list, if any: */ + List *funccolnames; /* column names (list of String) */ + List *funccoltypes; /* OID list of column type OIDs */ + List *funccoltypmods; /* integer list of column typmods */ + List *funccolcollations; /* OID list of column collation OIDs */ + /* This is set during planning for use by the executor: */ + Bitmapset *funcparams; /* PARAM_EXEC Param IDs affecting this func */ +} RangeTblFunction; + +/* + * WithCheckOption - + * representation of WITH CHECK OPTION checks to be applied to new tuples + * when inserting/updating an auto-updatable view. + */ +typedef struct WithCheckOption +{ + NodeTag type; + char *viewname; /* name of view that specified the WCO */ + Node *qual; /* constraint qual to check */ + bool cascaded; /* true = WITH CASCADED CHECK OPTION */ +} WithCheckOption; + +/* * SortGroupClause - * representation of ORDER BY, GROUP BY, PARTITION BY, * DISTINCT, DISTINCT ON items @@ -804,7 +888,7 @@ typedef struct RangeTblEntry * You might think that ORDER BY is only interested in defining ordering, * and GROUP/DISTINCT are only interested in defining equality. However, * one way to implement grouping is to sort and then apply a "uniq"-like - * filter. So it's also interesting to keep track of possible sort operators + * filter. So it's also interesting to keep track of possible sort operators * for GROUP/DISTINCT, and in particular to try to sort for the grouping * in a way that will also yield a requested ORDER BY ordering. So we need * to be able to compare ORDER BY and GROUP/DISTINCT lists, which motivates @@ -824,15 +908,15 @@ typedef struct RangeTblEntry * here, but it's cheap to get it along with the sortop, and requiring it * to be valid eases comparisons to grouping items.) Note that this isn't * actually enough information to determine an ordering: if the sortop is - * collation-sensitive, a collation OID is needed too. We don't store the + * collation-sensitive, a collation OID is needed too. We don't store the * collation in SortGroupClause because it's not available at the time the * parser builds the SortGroupClause; instead, consult the exposed collation * of the referenced targetlist expression to find out what it is. * - * In a grouping item, eqop must be valid. If the eqop is a btree equality + * In a grouping item, eqop must be valid. If the eqop is a btree equality * operator, then sortop should be set to a compatible ordering operator. * We prefer to set eqop/sortop/nulls_first to match any ORDER BY item that - * the query presents for the same tlist item. If there is none, we just + * the query presents for the same tlist item. If there is none, we just * use the default ordering op for the datatype. * * If the tlist item's type has a hash opclass but no btree opclass, then @@ -894,21 +978,21 @@ typedef struct WindowClause /* * RowMarkClause - - * parser output representation of FOR UPDATE/SHARE clauses + * parser output representation of FOR [KEY] UPDATE/SHARE clauses * * Query.rowMarks contains a separate RowMarkClause node for each relation - * identified as a FOR UPDATE/SHARE target. If FOR UPDATE/SHARE is applied - * to a subquery, we generate RowMarkClauses for all normal and subquery rels - * in the subquery, but they are marked pushedDown = true to distinguish them - * from clauses that were explicitly written at this query level. Also, - * Query.hasForUpdate tells whether there were explicit FOR UPDATE/SHARE - * clauses in the current query level. + * identified as a FOR [KEY] UPDATE/SHARE target. If one of these clauses + * is applied to a subquery, we generate RowMarkClauses for all normal and + * subquery rels in the subquery, but they are marked pushedDown = true to + * distinguish them from clauses that were explicitly written at this query + * level. Also, Query.hasForUpdate tells whether there were explicit FOR + * UPDATE/SHARE/KEY SHARE clauses in the current query level. */ typedef struct RowMarkClause { NodeTag type; Index rti; /* range table index of target relation */ - bool forUpdate; /* true = FOR UPDATE, false = FOR SHARE */ + LockClauseStrength strength; bool noWait; /* NOWAIT option */ bool pushedDown; /* pushed down from higher query level? */ } RowMarkClause; @@ -1048,7 +1132,6 @@ typedef struct SelectStmt List *groupClause; /* GROUP BY clauses */ Node *havingClause; /* HAVING conditional-expression */ List *windowClause; /* WINDOW window_name AS (...), ... */ - WithClause *withClause; /* WITH clause */ /* * In a "leaf" node representing a VALUES list, the above fields are all @@ -1068,6 +1151,7 @@ typedef struct SelectStmt Node *limitOffset; /* # of result tuples to skip */ Node *limitCount; /* # of result tuples to return */ List *lockingClause; /* FOR UPDATE (list of LockingClause's) */ + WithClause *withClause; /* WITH clause */ /* * These fields are used only in upper-level SelectStmts. @@ -1088,7 +1172,7 @@ typedef struct SelectStmt * range table. Its setOperations field shows the tree of set operations, * with leaf SelectStmt nodes replaced by RangeTblRef nodes, and internal * nodes replaced by SetOperationStmt nodes. Information about the output - * column types is added, too. (Note that the child nodes do not necessarily + * column types is added, too. (Note that the child nodes do not necessarily * produce these types directly, but we've checked that their output types * can be coerced to the output column type.) Also, if it's not UNION ALL, * information about the types' sort/group semantics is provided in the form @@ -1145,6 +1229,7 @@ typedef enum ObjectType OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DOMAIN, + OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, @@ -1153,6 +1238,7 @@ typedef enum ObjectType OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, + OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, @@ -1185,6 +1271,7 @@ typedef struct CreateSchemaStmt char *schemaname; /* the name of the schema to create */ char *authid; /* the owner of the created schema */ List *schemaElts; /* schema components (list of parsenodes) */ + bool if_not_exists; /* just do nothing if schema already exists? */ } CreateSchemaStmt; typedef enum DropBehavior @@ -1224,6 +1311,8 @@ typedef enum AlterTableType AT_ReAddIndex, /* internal to commands/tablecmds.c */ AT_AddConstraint, /* add constraint */ AT_AddConstraintRecurse, /* internal to commands/tablecmds.c */ + AT_ReAddConstraint, /* internal to commands/tablecmds.c */ + AT_AlterConstraint, /* alter constraint */ AT_ValidateConstraint, /* validate constraint */ AT_ValidateConstraintRecurse, /* internal to commands/tablecmds.c */ AT_ProcessedConstraint, /* pre-processed add constraint (local in @@ -1265,9 +1354,17 @@ typedef enum AlterTableType AT_AddNodeList, /* ADD NODE nodelist */ AT_DeleteNodeList, /* DELETE NODE nodelist */ #endif - AT_GenericOptions, /* OPTIONS (...) */ + AT_ReplicaIdentity, /* REPLICA IDENTITY */ + AT_GenericOptions /* OPTIONS (...) */ } AlterTableType; +typedef struct ReplicaIdentityStmt +{ + NodeTag type; + char identity_type; + char *name; +} ReplicaIdentityStmt; + typedef struct AlterTableCmd /* one subcommand of an ALTER TABLE */ { NodeTag type; @@ -1387,7 +1484,7 @@ typedef struct AccessPriv * * Note: because of the parsing ambiguity with the GRANT <privileges> * statement, granted_roles is a list of AccessPriv; the execution code - * should complain if any column lists appear. grantee_roles is a list + * should complain if any column lists appear. grantee_roles is a list * of role names, as Value strings. * ---------------------- */ @@ -1417,7 +1514,7 @@ typedef struct AlterDefaultPrivilegesStmt * Copy Statement * * We support "COPY relation FROM file", "COPY relation TO file", and - * "COPY (query) TO file". In any given CopyStmt, exactly one of "relation" + * "COPY (query) TO file". In any given CopyStmt, exactly one of "relation" * and "query" must be non-NULL. * ---------------------- */ @@ -1429,6 +1526,7 @@ typedef struct CopyStmt List *attlist; /* List of column names (as Strings), or NIL * for all columns */ bool is_from; /* TO or FROM */ + bool is_program; /* is 'filename' a program to popen? */ char *filename; /* filename, or NULL for STDIN/STDOUT */ List *options; /* List of DefElem nodes */ } CopyStmt; @@ -1519,7 +1617,7 @@ typedef struct CreateStmt * * If skip_validation is true then we skip checking that the existing rows * in the table satisfy the constraint, and just install the catalog entries - * for the constraint. A new FK constraint is marked as valid iff + * for the constraint. A new FK constraint is marked as valid iff * initially_valid is true. (Usually skip_validation and initially_valid * are inverses, but we can set both true if the table is known empty.) * @@ -1532,7 +1630,8 @@ typedef struct CreateStmt typedef enum ConstrType /* types of constraints */ { - CONSTR_NULL, /* not SQL92, but a lot of people expect it */ + CONSTR_NULL, /* not standard SQL, but a lot of people + * expect it */ CONSTR_NOTNULL, CONSTR_DEFAULT, CONSTR_CHECK, @@ -1556,7 +1655,7 @@ typedef enum ConstrType /* types of constraints */ /* Foreign key matchtype codes */ #define FKCONSTR_MATCH_FULL 'f' #define FKCONSTR_MATCH_PARTIAL 'p' -#define FKCONSTR_MATCH_UNSPECIFIED 'u' +#define FKCONSTR_MATCH_SIMPLE 's' typedef struct Constraint { @@ -1592,10 +1691,11 @@ typedef struct Constraint RangeVar *pktable; /* Primary key table */ List *fk_attrs; /* Attributes of foreign key */ List *pk_attrs; /* Corresponding attrs in PK table */ - char fk_matchtype; /* FULL, PARTIAL, UNSPECIFIED */ + char fk_matchtype; /* FULL, PARTIAL, SIMPLE */ char fk_upd_action; /* ON UPDATE action */ char fk_del_action; /* ON DELETE action */ List *old_conpfeqop; /* pg_constraint.conpfeqop of my former self */ + Oid old_pktable_oid; /* pg_constraint.confrelid of my former self */ /* Fields used for constraints that allow a NOT VALID specification */ bool skip_validation; /* skip validation of existing rows? */ @@ -1613,6 +1713,7 @@ typedef struct CreateTableSpaceStmt char *tablespacename; char *owner; char *location; + List *options; } CreateTableSpaceStmt; typedef struct DropTableSpaceStmt @@ -1630,6 +1731,17 @@ typedef struct AlterTableSpaceOptionsStmt bool isReset; } AlterTableSpaceOptionsStmt; +typedef struct AlterTableSpaceMoveStmt +{ + NodeTag type; + char *orig_tablespacename; + ObjectType objtype; /* set to -1 if move_all is true */ + bool move_all; /* move all, or just objtype objects? */ + List *roles; /* List of roles to move objects of */ + char *new_tablespacename; + bool nowait; +} AlterTableSpaceMoveStmt; + /* ---------------------- * Create/Alter Extension Statements * ---------------------- @@ -1773,6 +1885,32 @@ typedef struct CreateTrigStmt } CreateTrigStmt; /* ---------------------- + * Create EVENT TRIGGER Statement + * ---------------------- + */ +typedef struct CreateEventTrigStmt +{ + NodeTag type; + char *trigname; /* TRIGGER's name */ + char *eventname; /* event's identifier */ + List *whenclause; /* list of DefElems indicating filtering */ + List *funcname; /* qual. name of function to call */ +} CreateEventTrigStmt; + +/* ---------------------- + * Alter EVENT TRIGGER Statement + * ---------------------- + */ +typedef struct AlterEventTrigStmt +{ + NodeTag type; + char *trigname; /* TRIGGER's name */ + char tgenabled; /* trigger's firing configuration WRT + * session_replication_role */ +} AlterEventTrigStmt; + +/* ---------------------- + * Create/Drop PROCEDURAL LANGUAGE Statements * Create PROCEDURAL LANGUAGE Statements * ---------------------- */ @@ -2004,7 +2142,7 @@ typedef struct SecLabelStmt * Declare Cursor Statement * * Note: the "query" field of DeclareCursorStmt is only used in the raw grammar - * output. After parse analysis it's set to null, and the Query points to the + * output. After parse analysis it's set to null, and the Query points to the * DeclareCursorStmt, not vice versa. * ---------------------- */ @@ -2066,10 +2204,11 @@ typedef struct FetchStmt * Create Index Statement * * This represents creation of an index and/or an associated constraint. - * If indexOid isn't InvalidOid, we are not creating an index, just a - * UNIQUE/PKEY constraint using an existing index. isconstraint must always - * be true in this case, and the fields describing the index properties are - * empty. + * If isconstraint is true, we should create a pg_constraint entry along + * with the index. But if indexOid isn't InvalidOid, we are not creating an + * index, just a UNIQUE/PKEY constraint using an existing index. isconstraint + * must always be true in this case, and the fields describing the index + * properties are empty. * ---------------------- */ typedef struct IndexStmt @@ -2079,15 +2218,16 @@ typedef struct IndexStmt RangeVar *relation; /* relation to build index on */ char *accessMethod; /* name of access method (eg. btree) */ char *tableSpace; /* tablespace, or NULL for default */ - List *indexParams; /* a list of IndexElem */ - List *options; /* options from WITH clause */ + List *indexParams; /* columns to index: a list of IndexElem */ + List *options; /* WITH clause options: a list of DefElem */ Node *whereClause; /* qualification (partial-index predicate) */ List *excludeOpNames; /* exclusion operator names, or NIL if none */ + char *idxcomment; /* comment to apply to index, or NULL */ Oid indexOid; /* OID of an existing index, if any */ - Oid oldNode; /* relfilenode of my former self */ + Oid oldNode; /* relfilenode of existing storage, if any */ bool unique; /* is index unique? */ - bool primary; /* is index on primary key? */ - bool isconstraint; /* is it from a CONSTRAINT clause? */ + bool primary; /* is index a primary key? */ + bool isconstraint; /* is it for a pkey/unique constraint? */ bool deferrable; /* is the constraint DEFERRABLE? */ bool initdeferred; /* is the constraint INITIALLY DEFERRED? */ bool concurrent; /* should this be a concurrent index build? */ @@ -2184,7 +2324,6 @@ typedef struct AlterObjectSchemaStmt RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ - char *addname; /* additional name if needed */ char *newschema; /* the new schema */ bool missing_ok; /* skip error if missing? */ } AlterObjectSchemaStmt; @@ -2200,7 +2339,6 @@ typedef struct AlterOwnerStmt RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ - char *addname; /* additional name if needed */ char *newowner; /* the new owner */ } AlterOwnerStmt; @@ -2322,12 +2460,20 @@ typedef struct AlterEnumStmt char *newVal; /* new enum value's name */ char *newValNeighbor; /* neighboring enum value, if specified */ bool newValIsAfter; /* place new enum value after neighbor? */ + bool skipIfExists; /* no error if label already exists */ } AlterEnumStmt; /* ---------------------- * Create View Statement * ---------------------- */ +typedef enum ViewCheckOption +{ + NO_CHECK_OPTION, + LOCAL_CHECK_OPTION, + CASCADED_CHECK_OPTION +} ViewCheckOption; + typedef struct ViewStmt { NodeTag type; @@ -2336,6 +2482,7 @@ typedef struct ViewStmt Node *query; /* the SELECT query */ bool replace; /* replace an existing view? */ List *options; /* options from WITH clause */ + ViewCheckOption withCheckOption; /* WITH CHECK OPTION */ } ViewStmt; /* ---------------------- @@ -2389,6 +2536,16 @@ typedef struct DropdbStmt } DropdbStmt; /* ---------------------- + * Alter System Statement + * ---------------------- + */ +typedef struct AlterSystemStmt +{ + NodeTag type; + VariableSetStmt *setstmt; /* SET subcommand */ +} AlterSystemStmt; + +/* ---------------------- * Cluster Statement (support pbrown's cluster index implementation) * ---------------------- */ @@ -2426,6 +2583,10 @@ typedef struct VacuumStmt int options; /* OR of VacuumOption flags */ int freeze_min_age; /* min freeze age, or -1 to use default */ int freeze_table_age; /* age at which to scan whole table */ + int multixact_freeze_min_age; /* min multixact freeze age, + * or -1 to use default */ + int multixact_freeze_table_age; /* multixact age at which to + * scan whole table */ RangeVar *relation; /* single table to process, or NULL */ List *va_cols; /* list of column names, or NIL for all */ } VacuumStmt; @@ -2527,6 +2688,8 @@ typedef struct ExplainStmt * A query written as CREATE TABLE AS will produce this node type natively. * A query written as SELECT ... INTO will be transformed to this form during * parse analysis. + * A query written as CREATE MATERIALIZED view will produce this node type, + * during parse analysis, since it needs all the same data. * * The "query" field is handled similarly to EXPLAIN, though note that it * can be a SELECT or an EXECUTE, but not other DML statements. @@ -2537,10 +2700,23 @@ typedef struct CreateTableAsStmt NodeTag type; Node *query; /* the query (see comments above) */ IntoClause *into; /* destination table */ + ObjectType relkind; /* OBJECT_TABLE or OBJECT_MATVIEW */ bool is_select_into; /* it was written as SELECT INTO */ } CreateTableAsStmt; /* ---------------------- + * REFRESH MATERIALIZED VIEW Statement + * ---------------------- + */ +typedef struct RefreshMatViewStmt +{ + NodeTag type; + bool concurrent; /* allow concurrent access? */ + bool skipData; /* true for WITH NO DATA */ + RangeVar *relation; /* relation to insert into */ +} RefreshMatViewStmt; + +/* ---------------------- * Checkpoint Statement * ---------------------- */ @@ -2558,6 +2734,7 @@ typedef enum DiscardMode { DISCARD_ALL, DISCARD_PLANS, + DISCARD_SEQUENCES, DISCARD_TEMP } DiscardMode; @@ -2597,7 +2774,7 @@ typedef struct ConstraintsSetStmt typedef struct ReindexStmt { NodeTag type; - ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, OBJECT_DATABASE */ + ObjectType kind; /* OBJECT_INDEX, OBJECT_TABLE, etc. */ RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ bool do_system; /* include system tables in database case */ diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index 22363ac2f0..e9b6ff73a1 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -27,7 +27,7 @@ * always be so; try to be careful to maintain the distinction.) * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/pg_list.h @@ -73,32 +73,32 @@ struct ListCell * them as macros, since we want to avoid double-evaluation of macro * arguments. Therefore, we implement them using static inline functions * if supported by the compiler, or as regular functions otherwise. + * See STATIC_IF_INLINE in c.h. */ -#ifdef USE_INLINE - -static inline ListCell * +#ifndef PG_USE_INLINE +extern ListCell *list_head(const List *l); +extern ListCell *list_tail(List *l); +extern int list_length(const List *l); +#endif /* PG_USE_INLINE */ +#if defined(PG_USE_INLINE) || defined(PG_LIST_INCLUDE_DEFINITIONS) +STATIC_IF_INLINE ListCell * list_head(const List *l) { return l ? l->head : NULL; } -static inline ListCell * +STATIC_IF_INLINE ListCell * list_tail(List *l) { return l ? l->tail : NULL; } -static inline int +STATIC_IF_INLINE int list_length(const List *l) { return l ? l->length : 0; } -#else - -extern ListCell *list_head(const List *l); -extern ListCell *list_tail(List *l); -extern int list_length(const List *l); -#endif /* USE_INLINE */ +#endif /*-- PG_USE_INLINE || PG_LIST_INCLUDE_DEFINITIONS */ /* * NB: There is an unfortunate legacy from a previous incarnation of diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 644dd18a38..04287aca9a 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/plannodes.h @@ -190,7 +190,9 @@ typedef struct ModifyTable List *resultRelations; /* integer list of RT indexes */ int resultRelIndex; /* index of first resultRel in plan's list */ List *plans; /* plan(s) producing source data */ + List *withCheckOptionLists; /* per-target-table WCO lists */ List *returningLists; /* per-target-table RETURNING tlists */ + List *fdwPrivLists; /* per-target-table FDW private data lists */ List *rowMarks; /* PlanRowMarks (non-locking only) */ int epqParam; /* ID of Param for EvalPlanQual re-eval */ #ifdef PGXC @@ -252,7 +254,7 @@ typedef struct RecursiveUnion * BitmapAnd node - * Generate the intersection of the results of sub-plans. * - * The subplans must be of types that yield tuple bitmaps. The targetlist + * The subplans must be of types that yield tuple bitmaps. The targetlist * and qual fields of the plan are unused and are always NIL. * ---------------- */ @@ -266,7 +268,7 @@ typedef struct BitmapAnd * BitmapOr node - * Generate the union of the results of sub-plans. * - * The subplans must be of types that yield tuple bitmaps. The targetlist + * The subplans must be of types that yield tuple bitmaps. The targetlist * and qual fields of the plan are unused and are always NIL. * ---------------- */ @@ -300,7 +302,7 @@ typedef Scan SeqScan; * in the same form it appeared in the query WHERE condition. Each should * be of the form (indexkey OP comparisonval) or (comparisonval OP indexkey). * The indexkey is a Var or expression referencing column(s) of the index's - * base table. The comparisonval might be any expression, but it won't use + * base table. The comparisonval might be any expression, but it won't use * any columns of the base table. The expressions are ordered by index * column position (but items referencing the same index column can appear * in any order). indexqualorig is used at runtime only if we have to recheck @@ -315,7 +317,7 @@ typedef Scan SeqScan; * that are being implemented by the index, while indexorderby is modified to * have index column Vars on the left-hand side. Here, multiple expressions * must appear in exactly the ORDER BY order, and this is not necessarily the - * index column order. Only the expressions are provided, not the auxiliary + * index column order. Only the expressions are provided, not the auxiliary * sort-order information from the ORDER BY SortGroupClauses; it's assumed * that the sort ordering is fully determinable from the top-level operators. * indexorderbyorig is unused at run time, but is needed for EXPLAIN. @@ -367,7 +369,7 @@ typedef struct IndexOnlyScan * bitmap index scan node * * BitmapIndexScan delivers a bitmap of potential tuple locations; - * it does not access the heap itself. The bitmap is used by an + * it does not access the heap itself. The bitmap is used by an * ancestor BitmapHeapScan node, possibly after passing through * intermediate BitmapAnd and/or BitmapOr nodes to combine it with * the results of other BitmapIndexScans. @@ -427,7 +429,7 @@ typedef struct TidScan * purposes. * * Note: we store the sub-plan in the type-specific subplan field, not in - * the generic lefttree field as you might expect. This is because we do + * the generic lefttree field as you might expect. This is because we do * not want plan-tree-traversal routines to recurse into the subplan without * knowing that they are changing Query contexts. * ---------------- @@ -445,11 +447,8 @@ typedef struct SubqueryScan typedef struct FunctionScan { Scan scan; - Node *funcexpr; /* expression tree for func call */ - List *funccolnames; /* output column names (string Value nodes) */ - List *funccoltypes; /* OID list of column type OIDs */ - List *funccoltypmods; /* integer list of column typmods */ - List *funccolcollations; /* OID list of column collation OIDs */ + List *functions; /* list of RangeTblFunction nodes */ + bool funcordinality; /* WITH ORDINALITY */ } FunctionScan; /* ---------------- @@ -795,32 +794,53 @@ typedef struct Limit * RowMarkType - * enums for types of row-marking operations * + * The first four of these values represent different lock strengths that + * we can take on tuples according to SELECT FOR [KEY] UPDATE/SHARE requests. + * We only support these on regular tables. For foreign tables, any locking + * that might be done for these requests must happen during the initial row + * fetch; there is no mechanism for going back to lock a row later (and thus + * no need for EvalPlanQual machinery during updates of foreign tables). + * This means that the semantics will be a bit different than for a local + * table; in particular we are likely to lock more rows than would be locked + * locally, since remote rows will be locked even if they then fail + * locally-checked restriction or join quals. However, the alternative of + * doing a separate remote query to lock each selected row is extremely + * unappealing, so let's do it like this for now. + * * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we have to uniquely * identify all the source rows, not only those from the target relations, so * that we can perform EvalPlanQual rechecking at need. For plain tables we - * can just fetch the TID, the same as for a target relation. Otherwise (for - * example for VALUES or FUNCTION scans) we have to copy the whole row value. - * The latter is pretty inefficient but fortunately the case is not - * performance-critical in practice. + * can just fetch the TID, much as for a target relation; this case is + * represented by ROW_MARK_REFERENCE. Otherwise (for example for VALUES or + * FUNCTION scans) we have to copy the whole row value. ROW_MARK_COPY is + * pretty inefficient, since most of the time we'll never need the data; but + * fortunately the case is not performance-critical in practice. Note that + * we use ROW_MARK_COPY for non-target foreign tables, even if the FDW has a + * concept of rowid and so could theoretically support some form of + * ROW_MARK_REFERENCE. Although copying the whole row value is inefficient, + * it's probably still faster than doing a second remote fetch, so it doesn't + * seem worth the extra complexity to permit ROW_MARK_REFERENCE. */ typedef enum RowMarkType { ROW_MARK_EXCLUSIVE, /* obtain exclusive tuple lock */ + ROW_MARK_NOKEYEXCLUSIVE, /* obtain no-key exclusive tuple lock */ ROW_MARK_SHARE, /* obtain shared tuple lock */ + ROW_MARK_KEYSHARE, /* obtain keyshare tuple lock */ ROW_MARK_REFERENCE, /* just fetch the TID */ ROW_MARK_COPY /* physically copy the row value */ } RowMarkType; -#define RowMarkRequiresRowShareLock(marktype) ((marktype) <= ROW_MARK_SHARE) +#define RowMarkRequiresRowShareLock(marktype) ((marktype) <= ROW_MARK_KEYSHARE) /* * PlanRowMark - - * plan-time representation of FOR UPDATE/SHARE clauses + * plan-time representation of FOR [KEY] UPDATE/SHARE clauses * * When doing UPDATE, DELETE, or SELECT FOR UPDATE/SHARE, we create a separate - * PlanRowMark node for each non-target relation in the query. Relations that + * PlanRowMark node for each non-target relation in the query. Relations that * are not specified as FOR UPDATE/SHARE are marked ROW_MARK_REFERENCE (if - * real tables) or ROW_MARK_COPY (if not). + * regular tables) or ROW_MARK_COPY (if not). * * Initially all PlanRowMarks have rti == prti and isParent == false. * When the planner discovers that a relation is the root of an inheritance @@ -832,7 +852,7 @@ typedef enum RowMarkType * * The planner also adds resjunk output columns to the plan that carry * information sufficient to identify the locked or fetched rows. For - * tables (markType != ROW_MARK_COPY), these columns are named + * regular tables (markType != ROW_MARK_COPY), these columns are named * tableoid%u OID of table * ctid%u TID of row * The tableoid column is only present for an inheritance hierarchy. @@ -864,7 +884,7 @@ typedef struct PlanRowMark * * We track the objects on which a PlannedStmt depends in two ways: * relations are recorded as a simple list of OIDs, and everything else - * is represented as a list of PlanInvalItems. A PlanInvalItem is designed + * is represented as a list of PlanInvalItems. A PlanInvalItem is designed * to be used with the syscache invalidation mechanism, so it identifies a * system catalog entry by cache ID and hash value. */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 3ec44c2b8b..62c151acaf 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -12,7 +12,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -39,7 +39,7 @@ * * Note: colnames is a list of Value nodes (always strings). In Alias structs * associated with RTEs, there may be entries corresponding to dropped - * columns; these are normally empty strings (""). See parsenodes.h for info. + * columns; these are normally empty strings (""). See parsenodes.h for info. */ typedef struct Alias { @@ -86,7 +86,12 @@ typedef struct RangeVar } RangeVar; /* - * IntoClause - target information for SELECT INTO and CREATE TABLE AS + * IntoClause - target information for SELECT INTO, CREATE TABLE AS, and + * CREATE MATERIALIZED VIEW + * + * For CREATE MATERIALIZED VIEW, viewQuery is the parsed-but-not-rewritten + * SELECT Query for the view; otherwise it's NULL. (Although it's actually + * Query*, we declare it as Node* to avoid a forward reference.) */ typedef struct IntoClause { @@ -97,6 +102,7 @@ typedef struct IntoClause List *options; /* options from WITH clause */ OnCommitAction onCommit; /* what do we do at COMMIT? */ char *tableSpaceName; /* table space to use, or NULL */ + Node *viewQuery; /* materialized view's SELECT query */ bool skipData; /* true for WITH NO DATA */ #ifdef PGXC struct DistributeBy *distributeby; /* distribution to use, or NULL */ @@ -229,17 +235,24 @@ typedef struct Param /* * Aggref * - * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes - * (before Postgres 9.0 it was just bare expressions). The non-resjunk TLEs + * The aggregate's args list is a targetlist, ie, a list of TargetEntry nodes. + * + * For a normal (non-ordered-set) aggregate, the non-resjunk TargetEntries * represent the aggregate's regular arguments (if any) and resjunk TLEs can * be added at the end to represent ORDER BY expressions that are not also * arguments. As in a top-level Query, the TLEs can be marked with * ressortgroupref indexes to let them be referenced by SortGroupClause * entries in the aggorder and/or aggdistinct lists. This represents ORDER BY * and DISTINCT operations to be applied to the aggregate input rows before - * they are passed to the transition function. The grammar only allows a + * they are passed to the transition function. The grammar only allows a * simple "DISTINCT" specifier for the arguments, but we use the full * query-level representation to allow more code sharing. + * + * For an ordered-set aggregate, the args list represents the WITHIN GROUP + * (aggregated) arguments, all of which will be listed in the aggorder list. + * DISTINCT is not supported in this case, so aggdistinct will be NIL. + * The direct arguments appear in aggdirectargs (as a list of plain + * expressions, not TargetEntry nodes). */ typedef struct Aggref { @@ -254,10 +267,15 @@ typedef struct Aggref bool agghas_collectfn; /* is collection function available */ #endif /* XCP */ #endif /* PGXC */ - List *args; /* arguments and sort expressions */ + List *aggdirectargs; /* direct arguments, if an ordered-set agg */ + List *args; /* aggregated arguments and sort expressions */ List *aggorder; /* ORDER BY (list of SortGroupClause) */ List *aggdistinct; /* DISTINCT (list of SortGroupClause) */ + Expr *aggfilter; /* FILTER expression, if any */ bool aggstar; /* TRUE if argument list was really '*' */ + bool aggvariadic; /* true if variadic arguments have been + * combined into an array last argument */ + char aggkind; /* aggregate kind (see pg_aggregate.h) */ Index agglevelsup; /* > 0 if agg belongs to outer query */ int location; /* token location, or -1 if unknown */ } Aggref; @@ -273,6 +291,7 @@ typedef struct WindowFunc Oid wincollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ List *args; /* arguments to the window function */ + Expr *aggfilter; /* FILTER expression, if any */ Index winref; /* index of associated WindowClause */ bool winstar; /* TRUE if argument list was really '*' */ bool winagg; /* is function a simple aggregate? */ @@ -290,7 +309,7 @@ typedef struct WindowFunc * entire new modified array value. * * If reflowerindexpr = NIL, then we are fetching or storing a single array - * element at the subscripts given by refupperindexpr. Otherwise we are + * element at the subscripts given by refupperindexpr. Otherwise we are * fetching or storing an array slice, that is a rectangular subarray * with lower and upper bounds given by the index expressions. * reflowerindexpr must be the same length as refupperindexpr when it @@ -332,14 +351,19 @@ typedef enum CoercionContext } CoercionContext; /* - * CoercionForm - information showing how to display a function-call node + * CoercionForm - how to display a node that could have come from a cast + * + * NB: equal() ignores CoercionForm fields, therefore this *must* not carry + * any semantically significant information. We need that behavior so that + * the planner will consider equivalent implicit and explicit casts to be + * equivalent. In cases where those actually behave differently, the coercion + * function's arguments will be different. */ typedef enum CoercionForm { COERCE_EXPLICIT_CALL, /* display as a function call */ COERCE_EXPLICIT_CAST, /* display as an explicit cast */ - COERCE_IMPLICIT_CAST, /* implicit cast, so hide it */ - COERCE_DONTCARE /* special case for planner */ + COERCE_IMPLICIT_CAST /* implicit cast, so hide it */ } CoercionForm; /* @@ -351,6 +375,8 @@ typedef struct FuncExpr Oid funcid; /* PG_PROC OID of the function */ Oid funcresulttype; /* PG_TYPE OID of result value */ bool funcretset; /* true if function returns set */ + bool funcvariadic; /* true if variadic arguments have been + * combined into an array last argument */ CoercionForm funcformat; /* how to display this function call */ Oid funccollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ @@ -449,7 +475,7 @@ typedef struct ScalarArrayOpExpr * * Notice the arguments are given as a List. For NOT, of course the list * must always have exactly one element. For AND and OR, the executor can - * handle any number of arguments. The parser generally treats AND and OR + * handle any number of arguments. The parser generally treats AND and OR * as binary and so it typically only produces two-element lists, but the * optimizer will flatten trees of AND and OR nodes to produce longer lists * when possible. There are also a few special cases where more arguments @@ -472,7 +498,7 @@ typedef struct BoolExpr * SubLink * * A SubLink represents a subselect appearing in an expression, and in some - * cases also the combining operator(s) just above it. The subLinkType + * cases also the combining operator(s) just above it. The subLinkType * indicates the form of the expression represented: * EXISTS_SUBLINK EXISTS(SELECT ...) * ALL_SUBLINK (lefthand) op ALL (SELECT ...) @@ -499,7 +525,7 @@ typedef struct BoolExpr * * NOTE: in the raw output of gram.y, testexpr contains just the raw form * of the lefthand expression (if any), and operName is the String name of - * the combining operator. Also, subselect is a raw parsetree. During parse + * the combining operator. Also, subselect is a raw parsetree. During parse * analysis, the parser transforms testexpr into a complete boolean expression * that compares the lefthand value(s) to PARAM_SUBLINK nodes representing the * output columns of the subselect. And subselect is transformed to a Query. @@ -557,7 +583,7 @@ typedef struct SubLink * list). In this case testexpr is NULL to avoid duplication. * * The planner also derives lists of the values that need to be passed into - * and out of the subplan. Input values are represented as a list "args" of + * and out of the subplan. Input values are represented as a list "args" of * expressions to be evaluated in the outer-query context (currently these * args are always just Vars, but in principle they could be any expression). * The values are assigned to the global PARAM_EXEC params indexed by parParam @@ -648,7 +674,7 @@ typedef struct FieldSelect * portion of a column. * * A single FieldStore can actually represent updates of several different - * fields. The parser only generates FieldStores with single-element lists, + * fields. The parser only generates FieldStores with single-element lists, * but the planner will collapse multiple updates of the same base column * into one FieldStore. * ---------------- @@ -780,7 +806,7 @@ typedef struct CollateExpr * and the testexpr in the second case. * * In the raw grammar output for the second form, the condition expressions - * of the WHEN clauses are just the comparison values. Parse analysis + * of the WHEN clauses are just the comparison values. Parse analysis * converts these to valid boolean expressions of the form * CaseTestExpr '=' compexpr * where the CaseTestExpr node is a placeholder that emits the correct @@ -854,22 +880,22 @@ typedef struct ArrayExpr * * Note: the list of fields must have a one-for-one correspondence with * physical fields of the associated rowtype, although it is okay for it - * to be shorter than the rowtype. That is, the N'th list element must + * to be shorter than the rowtype. That is, the N'th list element must * match up with the N'th physical field. When the N'th physical field * is a dropped column (attisdropped) then the N'th list element can just - * be a NULL constant. (This case can only occur for named composite types, + * be a NULL constant. (This case can only occur for named composite types, * not RECORD types, since those are built from the RowExpr itself rather * than vice versa.) It is important not to assume that length(args) is * the same as the number of columns logically present in the rowtype. * * colnames provides field names in cases where the names can't easily be - * obtained otherwise. Names *must* be provided if row_typeid is RECORDOID. + * obtained otherwise. Names *must* be provided if row_typeid is RECORDOID. * If row_typeid identifies a known composite type, colnames can be NIL to * indicate the type's cataloged field names apply. Note that colnames can * be non-NIL even for a composite type, and typically is when the RowExpr * was created by expanding a whole-row Var. This is so that we can retain * the column alias names of the RTE that the Var referenced (which would - * otherwise be very difficult to extract from the parsetree). Like the + * otherwise be very difficult to extract from the parsetree). Like the * args list, colnames is one-for-one with physical fields of the rowtype. */ typedef struct RowExpr @@ -882,7 +908,7 @@ typedef struct RowExpr * Note: we deliberately do NOT store a typmod. Although a typmod will be * associated with specific RECORD types at runtime, it will differ for * different backends, and so cannot safely be stored in stored - * parsetrees. We must assume typmod -1 for a RowExpr node. + * parsetrees. We must assume typmod -1 for a RowExpr node. * * We don't need to store a collation either. The result type is * necessarily composite, and composite types never have a collation. @@ -968,8 +994,9 @@ typedef struct MinMaxExpr * 'args' carries all other arguments. * * Note: result type/typmod/collation are not stored, but can be deduced - * from the XmlExprOp. The type/typmod fields are just used for display - * purposes, and are NOT the true result type of the node. + * from the XmlExprOp. The type/typmod fields are just used for display + * purposes, and are NOT necessarily the true result type of the node. + * (We also use type == InvalidOid to mark a not-yet-parse-analyzed XmlExpr.) */ typedef enum XmlExprOp { @@ -1053,8 +1080,8 @@ typedef struct BooleanTest * * CoerceToDomain represents the operation of coercing a value to a domain * type. At runtime (and not before) the precise set of constraints to be - * checked will be determined. If the value passes, it is returned as the - * result; if not, an error is raised. Note that this is equivalent to + * checked will be determined. If the value passes, it is returned as the + * result; if not, an error is raised. Note that this is equivalent to * RelabelType in the scenario where no constraints are applied. */ typedef struct CoerceToDomain @@ -1070,7 +1097,7 @@ typedef struct CoerceToDomain /* * Placeholder node for the value to be processed by a domain's check - * constraint. This is effectively like a Param, but can be implemented more + * constraint. This is effectively like a Param, but can be implemented more * simply since we need only one replacement value at a time. * * Note: the typeId/typeMod/collation will be set from the domain's base type, @@ -1090,7 +1117,7 @@ typedef struct CoerceToDomainValue * Placeholder node for a DEFAULT marker in an INSERT or UPDATE command. * * This is not an executable expression: it must be replaced by the actual - * column default expression during rewriting. But it is convenient to + * column default expression during rewriting. But it is convenient to * treat it as an expression node during parsing and rewriting. */ typedef struct SetToDefault @@ -1132,14 +1159,14 @@ typedef struct CurrentOfExpr * single expression tree. * * In a SELECT's targetlist, resno should always be equal to the item's - * ordinal position (counting from 1). However, in an INSERT or UPDATE + * ordinal position (counting from 1). However, in an INSERT or UPDATE * targetlist, resno represents the attribute number of the destination * column for the item; so there may be missing or out-of-order resnos. * It is even legal to have duplicated resnos; consider * UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ... * The two meanings come together in the executor, because the planner * transforms INSERT/UPDATE tlists into a normalized form with exactly - * one entry for each column of the destination table. Before that's + * one entry for each column of the destination table. Before that's * happened, however, it is risky to assume that resno == position. * Generally get_tle_by_resno() should be used rather than list_nth() * to fetch tlist entries by resno, and only in SELECT should you assume @@ -1148,25 +1175,25 @@ typedef struct CurrentOfExpr * resname is required to represent the correct column name in non-resjunk * entries of top-level SELECT targetlists, since it will be used as the * column title sent to the frontend. In most other contexts it is only - * a debugging aid, and may be wrong or even NULL. (In particular, it may + * a debugging aid, and may be wrong or even NULL. (In particular, it may * be wrong in a tlist from a stored rule, if the referenced column has been - * renamed by ALTER TABLE since the rule was made. Also, the planner tends + * renamed by ALTER TABLE since the rule was made. Also, the planner tends * to store NULL rather than look up a valid name for tlist entries in * non-toplevel plan nodes.) In resjunk entries, resname should be either * a specific system-generated name (such as "ctid") or NULL; anything else * risks confusing ExecGetJunkAttribute! * * ressortgroupref is used in the representation of ORDER BY, GROUP BY, and - * DISTINCT items. Targetlist entries with ressortgroupref=0 are not + * DISTINCT items. Targetlist entries with ressortgroupref=0 are not * sort/group items. If ressortgroupref>0, then this item is an ORDER BY, - * GROUP BY, and/or DISTINCT target value. No two entries in a targetlist + * GROUP BY, and/or DISTINCT target value. No two entries in a targetlist * may have the same nonzero ressortgroupref --- but there is no particular * meaning to the nonzero values, except as tags. (For example, one must * not assume that lower ressortgroupref means a more significant sort key.) * The order of the associated SortGroupClause lists determine the semantics. * * resorigtbl/resorigcol identify the source of the column, if it is a - * simple reference to a column of a base table (or view). If it is not + * simple reference to a column of a base table (or view). If it is not * a simple reference, these fields are zeroes. * * If resjunk is true then the column is a working column (such as a sort key) @@ -1206,7 +1233,7 @@ typedef struct TargetEntry * * NOTE: the qualification expressions present in JoinExpr nodes are * *in addition to* the query's main WHERE clause, which appears as the - * qual of the top-level FromExpr. The reason for associating quals with + * qual of the top-level FromExpr. The reason for associating quals with * specific nodes in the jointree is that the position of a qual is critical * when outer joins are present. (If we enforce a qual too soon or too late, * that may cause the outer join to produce the wrong set of NULL-extended @@ -1242,7 +1269,7 @@ typedef struct RangeTblRef * If he writes NATURAL then parse analysis generates the equivalent USING() * list, and from that fills in "quals" with the right equality comparisons. * If he writes USING() then "quals" is filled with equality comparisons. - * If he writes ON() then only "quals" is set. Note that NATURAL/USING + * If he writes ON() then only "quals" is set. Note that NATURAL/USING * are not equivalent to ON() since they also affect the output column list. * * alias is an Alias node representing the AS alias-clause attached to the @@ -1251,7 +1278,7 @@ typedef struct RangeTblRef * restricts visibility of the tables/columns inside it. * * During parse analysis, an RTE is created for the Join, and its index - * is filled into rtindex. This RTE is present mainly so that Vars can + * is filled into rtindex. This RTE is present mainly so that Vars can * be created that refer to the outputs of the join. The planner sometimes * generates JoinExprs internally; these can have rtindex = 0 if there are * no join alias variables referencing such joins. diff --git a/src/include/nodes/print.h b/src/include/nodes/print.h index 13fa8793fd..43ef948943 100644 --- a/src/include/nodes/print.h +++ b/src/include/nodes/print.h @@ -4,7 +4,7 @@ * definitions for nodes/print.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/print.h diff --git a/src/include/nodes/readfuncs.h b/src/include/nodes/readfuncs.h index 2c96fbbaf2..9ca70ddf7c 100644 --- a/src/include/nodes/readfuncs.h +++ b/src/include/nodes/readfuncs.h @@ -4,7 +4,7 @@ * header file for read.c and readfuncs.c. These functions are internal * to the stringToNode interface and should not be used by anyone else. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/readfuncs.h diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 97361105db..b2f1b4a1ad 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/relation.h @@ -71,15 +71,16 @@ typedef struct QualCost /* * Costing aggregate function execution requires these statistics about - * the aggregates to be executed by a given Agg node. Note that transCost - * includes the execution costs of the aggregates' input expressions. + * the aggregates to be executed by a given Agg node. Note that the costs + * include the execution costs of the aggregates' argument expressions as + * well as the aggregate functions themselves. */ typedef struct AggClauseCosts { int numAggs; /* total number of aggregate functions */ - int numOrderedAggs; /* number that use DISTINCT or ORDER BY */ + int numOrderedAggs; /* number w/ DISTINCT/ORDER BY/WITHIN GROUP */ QualCost transCost; /* total per-input-row execution costs */ - Cost finalCost; /* total costs of agg final functions */ + Cost finalCost; /* total per-aggregated-row costs */ Size transitionSpace; /* space for pass-by-ref transition data */ } AggClauseCosts; @@ -99,8 +100,6 @@ typedef struct PlannerGlobal ParamListInfo boundParams; /* Param values provided to planner() */ - List *paramlist; /* to keep track of cross-level Params */ - List *subplans; /* Plans for SubPlan nodes */ List *subroots; /* PlannerInfos for SubPlan nodes */ @@ -117,6 +116,8 @@ typedef struct PlannerGlobal List *invalItems; /* other dependencies, as PlanInvalItems */ + int nParamExec; /* number of PARAM_EXEC Params used */ + Index lastPHId; /* highest PlaceHolderVar ID assigned */ Index lastRowMarkId; /* highest PlanRowMark ID assigned */ @@ -135,7 +136,7 @@ typedef struct PlannerGlobal * * This struct is conventionally called "root" in all the planner routines. * It holds links to all of the planner's working state, in addition to the - * original Query. Note that at present the planner extensively modifies + * original Query. Note that at present the planner extensively modifies * the passed-in Query data structure; someday that should stop. *---------- */ @@ -151,9 +152,11 @@ typedef struct PlannerInfo struct PlannerInfo *parent_root; /* NULL at outermost Query */ + List *plan_params; /* list of PlannerParamItems, see below */ + /* * simple_rel_array holds pointers to "base rels" and "other rels" (see - * comments for RelOptInfo for more info). It is indexed by rangetable + * comments for RelOptInfo for more info). It is indexed by rangetable * index (so entry 0 is always wasted). Entries can be NULL when an RTE * does not correspond to a base relation, such as a join RTE or an * unreferenced view RTE; or if the RelOptInfo hasn't been made yet. @@ -172,16 +175,25 @@ typedef struct PlannerInfo /* * all_baserels is a Relids set of all base relids (but not "other" * relids) in the query; that is, the Relids identifier of the final join - * we need to form. + * we need to form. This is computed in make_one_rel, just before we + * start making Paths. */ Relids all_baserels; /* + * nullable_baserels is a Relids set of base relids that are nullable by + * some outer join in the jointree; these are rels that are potentially + * nullable below the WHERE clause, SELECT targetlist, etc. This is + * computed in deconstruct_jointree. + */ + Relids nullable_baserels; + + /* * join_rel_list is a list of all join-relation RelOptInfos we have * considered in this planning run. For small problems we just scan the * list to do lookups, but when there are many join relations we build a * hash table for faster lookups. The hash table is present and valid - * when join_rel_hash is not NULL. Note that we still maintain the list + * when join_rel_hash is not NULL. Note that we still maintain the list * even when using the hash table for lookups; this simplifies life for * GEQO. */ @@ -219,6 +231,8 @@ typedef struct PlannerInfo List *join_info_list; /* list of SpecialJoinInfos */ + List *lateral_info_list; /* list of LateralJoinInfos */ + List *append_rel_list; /* list of AppendRelInfos */ List *rowMarks; /* list of PlanRowMarks */ @@ -226,7 +240,7 @@ typedef struct PlannerInfo List *placeholder_list; /* list of PlaceHolderInfos */ List *query_pathkeys; /* desired pathkeys for query_planner(), and - * actual pathkeys afterwards */ + * actual pathkeys after planning */ List *group_pathkeys; /* groupClause pathkeys, if any */ List *window_pathkeys; /* pathkeys of bottom window, if any */ @@ -247,6 +261,7 @@ typedef struct PlannerInfo bool hasInheritedTarget; /* true if parse->resultRelation is an * inheritance child rel */ bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */ + bool hasLateralRTEs; /* true if any RTEs are marked LATERAL */ bool hasHavingQual; /* true if havingQual was non-null */ bool hasPseudoConstantQuals; /* true if any RestrictInfo has * pseudoconstant = true */ @@ -329,7 +344,7 @@ typedef struct PlannerInfo * Currently the only kind of otherrels are those made for member relations * of an "append relation", that is an inheritance set or UNION ALL subquery. * An append relation has a parent RTE that is a base rel, which represents - * the entire append relation. The member RTEs are otherrels. The parent + * the entire append relation. The member RTEs are otherrels. The parent * is present in the query join tree but the members are not. The member * RTEs and otherrels are used to plan the scans of the individual tables or * subqueries of the append set; then the parent baserel is given Append @@ -341,7 +356,7 @@ typedef struct PlannerInfo * alias Vars are expanded to non-aliased form during preprocess_expression. * * Parts of this data structure are specific to various scan and join - * mechanisms. It didn't seem worth creating new node types for them. + * mechanisms. It didn't seem worth creating new node types for them. * * relids - Set of base-relation identifiers; it is a base relation * if there is just one, a join relation if more than one @@ -349,26 +364,28 @@ typedef struct PlannerInfo * clauses have been applied (ie, output rows of a plan for it) * width - avg. number of bytes per tuple in the relation after the * appropriate projections have been done (ie, output width) + * consider_startup - true if there is any value in keeping paths for + * this rel on the basis of having cheap startup cost * reltargetlist - List of Var and PlaceHolderVar nodes for the values * we need to output from this relation. * List is in no particular order, but all rels of an * appendrel set must use corresponding orders. - * NOTE: in a child relation, may contain RowExpr or - * ConvertRowtypeExpr representing a whole-row Var. + * NOTE: in an appendrel child relation, may contain + * arbitrary expressions pulled up from a subquery! * pathlist - List of Path nodes, one for each potentially useful * method of generating the relation * ppilist - ParamPathInfo nodes for parameterized Paths, if any * cheapest_startup_path - the pathlist member with lowest startup cost - * (regardless of its ordering; but must be - * unparameterized) + * (regardless of ordering) among the unparameterized paths; + * or NULL if there is no unparameterized path * cheapest_total_path - the pathlist member with lowest total cost - * (regardless of its ordering; but must be - * unparameterized) + * (regardless of ordering) among the unparameterized paths; + * or if there is no unparameterized path, the path with lowest + * total cost among the paths with minimum parameterization * cheapest_unique_path - for caching cheapest path to produce unique - * (no duplicates) output from relation - * cheapest_parameterized_paths - paths with cheapest total costs for - * their parameterizations; always includes - * cheapest_total_path + * (no duplicates) output from relation; NULL if not yet requested + * cheapest_parameterized_paths - best paths for their parameterizations; + * always includes cheapest_total_path, even if that's unparameterized * * If the relation is a base relation it will have these fields set: * @@ -381,6 +398,11 @@ typedef struct PlannerInfo * the attribute is needed as part of final targetlist * attr_widths - cache space for per-attribute width estimates; * zero means not computed yet + * lateral_vars - lateral cross-references of rel, if any (list of + * Vars and PlaceHolderVars) + * lateral_relids - required outer rels for LATERAL, as a Relids set + * (for child rels this can be more than lateral_vars) + * lateral_referencers - relids of rels that reference this one laterally * indexlist - list of IndexOptInfo nodes for relation's indexes * (always NIL if it's not a table) * pages - number of disk pages in relation (zero if not a table) @@ -388,6 +410,7 @@ typedef struct PlannerInfo * allvisfrac - fraction of disk pages that are marked all-visible * subplan - plan for subquery (NULL if it's not a subquery) * subroot - PlannerInfo for subquery (NULL if it's not a subquery) + * subplan_params - list of PlannerParamItems to be passed to subquery * fdwroutine - function hooks for FDW, if foreign table (else NULL) * fdw_private - private state for FDW, if foreign table (else NULL) * @@ -451,6 +474,9 @@ typedef struct RelOptInfo double rows; /* estimated number of result tuples */ int width; /* estimated avg width of result tuples */ + /* per-relation planner control flags */ + bool consider_startup; /* keep cheap-startup-cost paths? */ + /* materialization information */ List *reltargetlist; /* Vars to be output by scan of relation */ List *pathlist; /* Path structures */ @@ -468,6 +494,9 @@ typedef struct RelOptInfo AttrNumber max_attr; /* largest attrno of rel */ Relids *attr_needed; /* array indexed [min_attr .. max_attr] */ int32 *attr_widths; /* array indexed [min_attr .. max_attr] */ + List *lateral_vars; /* LATERAL Vars and PHVs referenced by rel */ + Relids lateral_relids; /* minimum parameterization of rel */ + Relids lateral_referencers; /* rels that reference me laterally */ List *indexlist; /* list of IndexOptInfo */ BlockNumber pages; /* size estimates derived from pg_class */ double tuples; @@ -475,6 +504,7 @@ typedef struct RelOptInfo /* use "struct Plan" to avoid including plannodes.h here */ struct Plan *subplan; /* if subquery */ PlannerInfo *subroot; /* if subquery */ + List *subplan_params; /* if subquery */ /* use "struct FdwRoutine" to avoid including fdwapi.h here */ struct FdwRoutine *fdwroutine; /* if foreign table */ void *fdw_private; /* if foreign table */ @@ -522,9 +552,10 @@ typedef struct IndexOptInfo Oid reltablespace; /* tablespace of index (not table) */ RelOptInfo *rel; /* back-link to index's table */ - /* statistics from pg_class */ + /* index-size statistics (from pg_class and elsewhere) */ BlockNumber pages; /* number of disk pages in index */ double tuples; /* number of index tuples in index */ + int tree_height; /* index tree height, or -1 if unknown */ /* index descriptor information */ int ncolumns; /* number of columns in index */ @@ -570,7 +601,7 @@ typedef struct IndexOptInfo * equal to each other, where "equal" is according to the rules of the btree * operator family(s) shown in ec_opfamilies, as well as the collation shown * by ec_collation. (We restrict an EC to contain only equalities whose - * operators belong to the same set of opfamilies. This could probably be + * operators belong to the same set of opfamilies. This could probably be * relaxed, but for now it's not worth the trouble, since nearly all equality * operators belong to only one btree opclass anyway. Similarly, we suppose * that all or none of the input datatypes are collatable, so that a single @@ -580,7 +611,7 @@ typedef struct IndexOptInfo * us represent knowledge about different sort orderings being equivalent. * Since every PathKey must reference an EquivalenceClass, we will end up * with single-member EquivalenceClasses whenever a sort key expression has - * not been equivalenced to anything else. It is also possible that such an + * not been equivalenced to anything else. It is also possible that such an * EquivalenceClass will contain a volatile expression ("ORDER BY random()"), * which is a case that can't arise otherwise since clauses containing * volatile functions are never considered mergejoinable. We mark such @@ -593,7 +624,7 @@ typedef struct IndexOptInfo * We allow equality clauses appearing below the nullable side of an outer join * to form EquivalenceClasses, but these have a slightly different meaning: * the included values might be all NULL rather than all the same non-null - * values. See src/backend/optimizer/README for more on that point. + * values. See src/backend/optimizer/README for more on that point. * * NB: if ec_merged isn't NULL, this class has been merged into another, and * should be ignored in favor of using the pointed-to class. @@ -607,7 +638,8 @@ typedef struct EquivalenceClass List *ec_members; /* list of EquivalenceMembers */ List *ec_sources; /* list of generating RestrictInfos */ List *ec_derives; /* list of derived RestrictInfos */ - Relids ec_relids; /* all relids appearing in ec_members */ + Relids ec_relids; /* all relids appearing in ec_members, except + * for child members (see below) */ bool ec_has_const; /* any pseudoconstants in ec_members? */ bool ec_has_volatile; /* the (sole) member is a volatile expr */ bool ec_below_outer_join; /* equivalence applies below an OJ */ @@ -628,7 +660,7 @@ typedef struct EquivalenceClass * * em_is_child signifies that this element was built by transposing a member * for an appendrel parent relation to represent the corresponding expression - * for an appendrel child. These members are used for determining the + * for an appendrel child. These members are used for determining the * pathkeys of scans on the child relation and for explicitly sorting the * child when necessary to build a MergeAppend path for the whole appendrel * tree. An em_is_child member has no impact on the properties of the EC as a @@ -642,7 +674,7 @@ typedef struct EquivalenceClass * * em_datatype is usually the same as exprType(em_expr), but can be * different when dealing with a binary-compatible opfamily; in particular - * anyarray_ops would never work without this. Use em_datatype when + * anyarray_ops would never work without this. Use em_datatype when * looking up a specific btree operator to work with this expression. */ typedef struct EquivalenceMember @@ -651,6 +683,7 @@ typedef struct EquivalenceMember Expr *em_expr; /* the expression represented */ Relids em_relids; /* all relids appearing in em_expr */ + Relids em_nullable_relids; /* nullable by lower outer joins */ bool em_is_const; /* expression is pseudoconstant? */ bool em_is_child; /* derived version for a child relation? */ Oid em_datatype; /* the "nominal type" used by the opfamily */ @@ -670,7 +703,7 @@ typedef struct EquivalenceMember * information.) * * Note: pk_strategy is either BTLessStrategyNumber (for ASC) or - * BTGreaterStrategyNumber (for DESC). We assume that all ordering-capable + * BTGreaterStrategyNumber (for DESC). We assume that all ordering-capable * index types will use btree-compatible strategy numbers. */ typedef struct PathKey @@ -721,7 +754,7 @@ typedef struct ParamPathInfo * "param_info", if not NULL, links to a ParamPathInfo that identifies outer * relation(s) that provide parameter values to each scan of this path. * That means this path can only be joined to those rels by means of nestloop - * joins with this path on the inside. Also note that a parameterized path + * joins with this path on the inside. Also note that a parameterized path * is responsible for testing all "movable" joinclauses involving this rel * and the specified outer rel(s). * @@ -832,7 +865,7 @@ typedef struct IndexPath * * The individual indexscans are represented by IndexPath nodes, and any * logic on top of them is represented by a tree of BitmapAndPath and - * BitmapOrPath nodes. Notice that we can use the same IndexPath node both + * BitmapOrPath nodes. Notice that we can use the same IndexPath node both * to represent a regular (or index-only) index scan plan, and as the child * of a BitmapHeapPath that represents scanning the same index using a * BitmapIndexScan. The startup_cost and total_cost figures of an IndexPath @@ -888,7 +921,7 @@ typedef struct TidPath /* * ForeignPath represents a potential scan of a foreign table * - * fdw_private stores FDW private data about the scan. While fdw_private is + * fdw_private stores FDW private data about the scan. While fdw_private is * not actually touched by the core code during normal operations, it's * generally a good idea to use a representation that can be dumped by * nodeToString(), so that you can examine the structure during debugging @@ -965,7 +998,7 @@ typedef struct MaterialPath * * This is unlike the other Path nodes in that it can actually generate * different plans: either hash-based or sort-based implementation, or a - * no-op if the input path can be proven distinct already. The decision + * no-op if the input path can be proven distinct already. The decision * is sufficiently localized that it's not worth having separate Path node * types. (Note: in the no-op case, we could eliminate the UniquePath node * entirely and just return the subpath; but it's convenient to have a @@ -1099,7 +1132,7 @@ typedef struct HashPath * When we construct a join rel that includes all the base rels referenced * in a multi-relation restriction clause, we place that clause into the * joinrestrictinfo lists of paths for the join rel, if neither left nor - * right sub-path includes all base rels referenced in the clause. The clause + * right sub-path includes all base rels referenced in the clause. The clause * will be applied at that join level, and will not propagate any further up * the join tree. (Note: the "predicate migration" code was once intended to * push restriction clauses up and down the plan tree based on evaluation @@ -1139,13 +1172,13 @@ typedef struct HashPath * that appeared elsewhere in the tree and were pushed down to the join rel * because they used no other rels. That's what the is_pushed_down flag is * for; it tells us that a qual is not an OUTER JOIN qual for the set of base - * rels listed in required_relids. A clause that originally came from WHERE + * rels listed in required_relids. A clause that originally came from WHERE * or an INNER JOIN condition will *always* have its is_pushed_down flag set. * It's possible for an OUTER JOIN clause to be marked is_pushed_down too, * if we decide that it can be pushed down into the nullable side of the join. * In that case it acts as a plain filter qual for wherever it gets evaluated. * (In short, is_pushed_down is only false for non-degenerate outer join - * conditions. Possibly we should rename it to reflect that meaning?) + * conditions. Possibly we should rename it to reflect that meaning?) * * RestrictInfo nodes also contain an outerjoin_delayed flag, which is true * if the clause's applicability must be delayed due to any outer joins @@ -1167,7 +1200,7 @@ typedef struct HashPath * outer join(s). A clause that is not outerjoin_delayed can be enforced * anywhere it is computable. * - * In general, the referenced clause might be arbitrarily complex. The + * In general, the referenced clause might be arbitrarily complex. The * kinds of clauses we can handle as indexscan quals, mergejoin clauses, * or hashjoin clauses are limited (e.g., no volatile functions). The code * for each kind of path is responsible for identifying the restrict clauses @@ -1192,7 +1225,7 @@ typedef struct HashPath * * The pseudoconstant flag is set true if the clause contains no Vars of * the current query level and no volatile functions. Such a clause can be - * pulled out and used as a one-time qual in a gating Result node. We keep + * pulled out and used as a one-time qual in a gating Result node. We keep * pseudoconstant clauses in the same lists as other RestrictInfos so that * the regular clause-pushing machinery can assign them to the correct join * level, but they need to be treated specially for cost and selectivity @@ -1202,7 +1235,7 @@ typedef struct HashPath * * When join clauses are generated from EquivalenceClasses, there may be * several equally valid ways to enforce join equivalence, of which we need - * apply only one. We mark clauses of this kind by setting parent_ec to + * apply only one. We mark clauses of this kind by setting parent_ec to * point to the generating EquivalenceClass. Multiple clauses with the same * parent_ec in the same join are redundant. */ @@ -1295,8 +1328,8 @@ typedef struct MergeScanSelCache /* * Placeholder node for an expression to be evaluated below the top level - * of a plan tree. This is used during planning to represent the contained - * expression. At the end of the planning process it is replaced by either + * of a plan tree. This is used during planning to represent the contained + * expression. At the end of the planning process it is replaced by either * the contained expression or a Var referring to a lower-level evaluation of * the contained expression. Typically the evaluation occurs below an outer * join, and Var references above the outer join might thereby yield NULL @@ -1320,9 +1353,9 @@ typedef struct PlaceHolderVar * "Special join" info. * * One-sided outer joins constrain the order of joining partially but not - * completely. We flatten such joins into the planner's top-level list of + * completely. We flatten such joins into the planner's top-level list of * relations to join, but record information about each outer join in a - * SpecialJoinInfo struct. These structs are kept in the PlannerInfo node's + * SpecialJoinInfo struct. These structs are kept in the PlannerInfo node's * join_info_list. * * Similarly, semijoins and antijoins created by flattening IN (subselect) @@ -1350,7 +1383,7 @@ typedef struct PlaceHolderVar * to be evaluated after this join is formed (because it references the RHS). * Any outer joins that have such a clause and this join in their RHS cannot * commute with this join, because that would leave noplace to check the - * pushed-down clause. (We don't track this for FULL JOINs, either.) + * pushed-down clause. (We don't track this for FULL JOINs, either.) * * join_quals is an implicit-AND list of the quals syntactically associated * with the join (they may or may not end up being applied at the join level). @@ -1386,6 +1419,43 @@ typedef struct SpecialJoinInfo } SpecialJoinInfo; /* + * "Lateral join" info. + * + * Lateral references constrain the join order in a way that's somewhat like + * outer joins, though different in detail. We construct a LateralJoinInfo + * for each lateral cross-reference, placing them in the PlannerInfo node's + * lateral_info_list. + * + * For unflattened LATERAL RTEs, we generate LateralJoinInfo(s) in which + * lateral_rhs is the relid of the LATERAL baserel, and lateral_lhs is a set + * of relids of baserels it references, all of which must be present on the + * LHS to compute a parameter needed by the RHS. Typically, lateral_lhs is + * a singleton, but it can include multiple rels if the RHS references a + * PlaceHolderVar with a multi-rel ph_eval_at level. We disallow joining to + * only part of the LHS in such cases, since that would result in a join tree + * with no convenient place to compute the PHV. + * + * When an appendrel contains lateral references (eg "LATERAL (SELECT x.col1 + * UNION ALL SELECT y.col2)"), the LateralJoinInfos reference the parent + * baserel not the member otherrels, since it is the parent relid that is + * considered for joining purposes. + * + * If any LATERAL RTEs were flattened into the parent query, it is possible + * that the query now contains PlaceHolderVars containing lateral references, + * representing expressions that need to be evaluated at particular spots in + * the jointree but contain lateral references to Vars from elsewhere. These + * give rise to LateralJoinInfos in which lateral_rhs is the evaluation point + * of a PlaceHolderVar and lateral_lhs is the set of lateral rels it needs. + */ + +typedef struct LateralJoinInfo +{ + NodeTag type; + Relids lateral_lhs; /* rels needed to compute a lateral value */ + Relids lateral_rhs; /* rel where lateral value is needed */ +} LateralJoinInfo; + +/* * Append-relation info. * * When we expand an inheritable table or a UNION-ALL subselect into an @@ -1435,7 +1505,7 @@ typedef struct AppendRelInfo /* * For an inheritance appendrel, the parent and child are both regular * relations, and we store their rowtype OIDs here for use in translating - * whole-row Vars. For a UNION-ALL appendrel, the parent and child are + * whole-row Vars. For a UNION-ALL appendrel, the parent and child are * both subqueries with no named rowtype, and we store InvalidOid here. */ Oid parent_reltype; /* OID of parent's composite type */ @@ -1447,14 +1517,14 @@ typedef struct AppendRelInfo * used to translate Vars referencing the parent rel into references to * the child. A list element is NULL if it corresponds to a dropped * column of the parent (this is only possible for inheritance cases, not - * UNION ALL). The list elements are always simple Vars for inheritance + * UNION ALL). The list elements are always simple Vars for inheritance * cases, but can be arbitrary expressions in UNION ALL cases. * * Notice we only store entries for user columns (attno > 0). Whole-row * Vars are special-cased, and system columns (attno < 0) need no special * translation since their attnos are the same for all tables. * - * Caution: the Vars have varlevelsup = 0. Be careful to adjust as needed + * Caution: the Vars have varlevelsup = 0. Be careful to adjust as needed * when copying into a subquery. */ List *translated_vars; /* Expressions in the child's Vars */ @@ -1471,7 +1541,7 @@ typedef struct AppendRelInfo * For each distinct placeholder expression generated during planning, we * store a PlaceHolderInfo node in the PlannerInfo node's placeholder_list. * This stores info that is needed centrally rather than in each copy of the - * PlaceHolderVar. The phid fields identify which PlaceHolderInfo goes with + * PlaceHolderVar. The phid fields identify which PlaceHolderInfo goes with * each PlaceHolderVar. Note that phid is unique throughout a planner run, * not just within a query level --- this is so that we need not reassign ID's * when pulling a subquery into its parent. @@ -1480,18 +1550,13 @@ typedef struct AppendRelInfo * then allow it to bubble up like a Var until the ph_needed join level. * ph_needed has the same definition as attr_needed for a regular Var. * - * ph_may_need is an initial estimate of ph_needed, formed using the - * syntactic locations of references to the PHV. We need this in order to - * determine whether the PHV reference forces a join ordering constraint: - * if the PHV has to be evaluated below the nullable side of an outer join, - * and then used above that outer join, we must constrain join order to ensure - * there's a valid place to evaluate the PHV below the join. The final - * actual ph_needed level might be lower than ph_may_need, but we can't - * determine that until later on. Fortunately this doesn't matter for what - * we need ph_may_need for: if there's a PHV reference syntactically - * above the outer join, it's not going to be allowed to drop below the outer - * join, so we would come to the same conclusions about join order even if - * we had the final ph_needed value to compare to. + * The PlaceHolderVar's expression might contain LATERAL references to vars + * coming from outside its syntactic scope. If so, those rels are *not* + * included in ph_eval_at, but they are recorded in ph_lateral. + * + * Notice that when ph_eval_at is a join rather than a single baserel, the + * PlaceHolderInfo may create constraints on join order: the ph_eval_at join + * has to be formed below any outer joins that should null the PlaceHolderVar. * * We create a PlaceHolderInfo only after determining that the PlaceHolderVar * is actually referenced in the plan tree, so that unreferenced placeholders @@ -1505,8 +1570,8 @@ typedef struct PlaceHolderInfo Index phid; /* ID for PH (unique within planner run) */ PlaceHolderVar *ph_var; /* copy of PlaceHolderVar tree */ Relids ph_eval_at; /* lowest level we can evaluate value at */ + Relids ph_lateral; /* relids of contained lateral refs, if any */ Relids ph_needed; /* highest level the value is needed at */ - Relids ph_may_need; /* highest level it might be needed at */ int32 ph_width; /* estimated attribute width */ } PlaceHolderInfo; @@ -1528,26 +1593,29 @@ typedef struct MinMaxAggInfo } MinMaxAggInfo; /* - * glob->paramlist keeps track of the PARAM_EXEC slots that we have decided - * we need for the query. At runtime these slots are used to pass values - * around from one plan node to another. They can be used to pass values - * down into subqueries (for outer references in subqueries), or up out of - * subqueries (for the results of a subplan), or from a NestLoop plan node - * into its inner relation (when the inner scan is parameterized with values - * from the outer relation). The n'th entry in the list (n counts from 0) - * corresponds to Param->paramid = n. - * - * Each paramlist item shows the absolute query level it is associated with, - * where the outermost query is level 1 and nested subqueries have higher - * numbers. The item the parameter slot represents can be one of four kinds: - * - * A Var: the slot represents a variable of that level that must be passed + * At runtime, PARAM_EXEC slots are used to pass values around from one plan + * node to another. They can be used to pass values down into subqueries (for + * outer references in subqueries), or up out of subqueries (for the results + * of a subplan), or from a NestLoop plan node into its inner relation (when + * the inner scan is parameterized with values from the outer relation). + * The planner is responsible for assigning nonconflicting PARAM_EXEC IDs to + * the PARAM_EXEC Params it generates. + * + * Outer references are managed via root->plan_params, which is a list of + * PlannerParamItems. While planning a subquery, each parent query level's + * plan_params contains the values required from it by the current subquery. + * During create_plan(), we use plan_params to track values that must be + * passed from outer to inner sides of NestLoop plan nodes. + * + * The item a PlannerParamItem represents can be one of three kinds: + * + * A Var: the slot represents a variable of this level that must be passed * down because subqueries have outer references to it, or must be passed - * from a NestLoop node of that level to its inner scan. The varlevelsup - * value in the Var will always be zero. + * from a NestLoop node to its inner scan. The varlevelsup value in the Var + * will always be zero. * * A PlaceHolderVar: this works much like the Var case, except that the - * entry is a PlaceHolderVar node with a contained expression. The PHV + * entry is a PlaceHolderVar node with a contained expression. The PHV * will have phlevelsup = 0, and the contained expression is adjusted * to match in level. * @@ -1556,25 +1624,27 @@ typedef struct MinMaxAggInfo * subquery. The Aggref itself has agglevelsup = 0, and its argument tree * is adjusted to match in level. * - * A Param: the slot holds the result of a subplan (it is a setParam item - * for that subplan). The absolute level shown for such items corresponds - * to the parent query of the subplan. - * * Note: we detect duplicate Var and PlaceHolderVar parameters and coalesce - * them into one slot, but we do not bother to do this for Aggrefs, and it - * would be incorrect to do so for Param slots. Duplicate detection is - * actually *necessary* for NestLoop parameters since it serves to match up - * the usage of a Param (in the inner scan) with the assignment of the value - * (in the NestLoop node). This might result in the same PARAM_EXEC slot being - * used by multiple NestLoop nodes or SubPlan nodes, but no harm is done since - * the same value would be assigned anyway. + * them into one slot, but we do not bother to do that for Aggrefs. + * The scope of duplicate-elimination only extends across the set of + * parameters passed from one query level into a single subquery, or for + * nestloop parameters across the set of nestloop parameters used in a single + * query level. So there is no possibility of a PARAM_EXEC slot being used + * for conflicting purposes. + * + * In addition, PARAM_EXEC slots are assigned for Params representing outputs + * from subplans (values that are setParam items for those subplans). These + * IDs need not be tracked via PlannerParamItems, since we do not need any + * duplicate-elimination nor later processing of the represented expressions. + * Instead, we just record the assignment of the slot number by incrementing + * root->glob->nParamExec. */ typedef struct PlannerParamItem { NodeTag type; - Node *item; /* the Var, PlaceHolderVar, Aggref, or Param */ - Index abslevel; /* its absolute query level */ + Node *item; /* the Var, PlaceHolderVar, or Aggref */ + int paramId; /* its assigned PARAM_EXEC slot number */ } PlannerParamItem; /* diff --git a/src/include/nodes/replnodes.h b/src/include/nodes/replnodes.h index 236a36dd98..0f94a40312 100644 --- a/src/include/nodes/replnodes.h +++ b/src/include/nodes/replnodes.h @@ -4,7 +4,7 @@ * definitions for replication grammar parse nodes * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/replnodes.h @@ -17,6 +17,12 @@ #include "access/xlogdefs.h" #include "nodes/pg_list.h" +typedef enum ReplicationKind +{ + REPLICATION_KIND_PHYSICAL, + REPLICATION_KIND_LOGICAL +} ReplicationKind; + /* ---------------------- * IDENTIFY_SYSTEM command @@ -40,13 +46,52 @@ typedef struct BaseBackupCmd /* ---------------------- + * CREATE_REPLICATION_SLOT command + * ---------------------- + */ +typedef struct CreateReplicationSlotCmd +{ + NodeTag type; + char *slotname; + ReplicationKind kind; + char *plugin; +} CreateReplicationSlotCmd; + + +/* ---------------------- + * DROP_REPLICATION_SLOT command + * ---------------------- + */ +typedef struct DropReplicationSlotCmd +{ + NodeTag type; + char *slotname; +} DropReplicationSlotCmd; + + +/* ---------------------- * START_REPLICATION command * ---------------------- */ typedef struct StartReplicationCmd { NodeTag type; + ReplicationKind kind; + char *slotname; + TimeLineID timeline; XLogRecPtr startpoint; + List *options; } StartReplicationCmd; + +/* ---------------------- + * TIMELINE_HISTORY command + * ---------------------- + */ +typedef struct TimeLineHistoryCmd +{ + NodeTag type; + TimeLineID timeline; +} TimeLineHistoryCmd; + #endif /* REPLNODES_H */ diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h index a52c16ff66..444d4d8ae3 100644 --- a/src/include/nodes/tidbitmap.h +++ b/src/include/nodes/tidbitmap.h @@ -13,7 +13,7 @@ * fact that a particular page needs to be visited. * * - * Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/nodes/tidbitmap.h * @@ -26,7 +26,7 @@ /* - * Actual bitmap representation is private to tidbitmap.c. Callers can + * Actual bitmap representation is private to tidbitmap.c. Callers can * do IsA(x, TIDBitmap) on it, but nothing else. */ typedef struct TIDBitmap TIDBitmap; diff --git a/src/include/nodes/value.h b/src/include/nodes/value.h index 523a906573..45e5ec3906 100644 --- a/src/include/nodes/value.h +++ b/src/include/nodes/value.h @@ -4,7 +4,7 @@ * interface for Value nodes * * - * Copyright (c) 2003-2012, PostgreSQL Global Development Group + * Copyright (c) 2003-2014, PostgreSQL Global Development Group * * src/include/nodes/value.h * @@ -29,7 +29,7 @@ * * (Before Postgres 7.0, we used a double to represent T_Float, * but that creates loss-of-precision problems when the value is - * ultimately destined to be converted to NUMERIC. Since Value nodes + * ultimately destined to be converted to NUMERIC. Since Value nodes * are only used in the parsing process, not for runtime data, it's * better to use the more general representation.) * diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h index 1713b70400..dd991b16bc 100644 --- a/src/include/optimizer/clauses.h +++ b/src/include/optimizer/clauses.h @@ -4,7 +4,7 @@ * prototypes for clauses.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/clauses.h @@ -55,11 +55,13 @@ extern bool contain_window_function(Node *clause); extern WindowFuncLists *find_window_functions(Node *clause, Index maxWinRef); extern double expression_returns_set_rows(Node *clause); +extern double tlist_returns_set_rows(List *tlist); extern bool contain_subplans(Node *clause); extern bool contain_mutable_functions(Node *clause); extern bool contain_volatile_functions(Node *clause); +extern bool contain_volatile_functions_not_nextval(Node *clause); extern bool contain_nonstrict_functions(Node *clause); extern bool contain_leaky_functions(Node *clause); @@ -76,10 +78,6 @@ extern int NumRelids(Node *clause); extern void CommuteOpExpr(OpExpr *clause); extern void CommuteRowCompareExpr(RowCompareExpr *clause); -extern Node *strip_implicit_coercions(Node *node); - -extern void set_coercionform_dontcare(Node *node); - extern Node *eval_const_expressions(PlannerInfo *root, Node *node); extern Node *estimate_expression_value(PlannerInfo *root, Node *node); diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index 2f40438398..70aa6b2594 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/cost.h @@ -36,7 +36,7 @@ #define DEFAULT_REMOTE_QUERY_COST 100.0 #endif -#define DEFAULT_EFFECTIVE_CACHE_SIZE 16384 /* measured in pages */ +#define DEFAULT_EFFECTIVE_CACHE_SIZE 524288 /* measured in pages */ typedef enum { @@ -94,17 +94,18 @@ extern void cost_bitmap_and_node(BitmapAndPath *path, PlannerInfo *root); extern void cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root); extern void cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec); extern void cost_tidscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, List *tidquals); + RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info); extern void cost_subqueryscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_functionscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel); + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_valuesscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel); + RelOptInfo *baserel, ParamPathInfo *param_info); #ifdef PGXC extern void cost_remotequery(Path *path, PlannerInfo *root, RelOptInfo *baserel); #endif -extern void cost_ctescan(Path *path, PlannerInfo *root, RelOptInfo *baserel); +extern void cost_ctescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_recursive_union(Plan *runion, Plan *nrterm, Plan *rterm); extern void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, Cost input_cost, double tuples, int width, diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h index 1a6dc3142b..790f99eef8 100644 --- a/src/include/optimizer/geqo.h +++ b/src/include/optimizer/geqo.h @@ -3,7 +3,7 @@ * geqo.h * prototypes for various files in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo.h diff --git a/src/include/optimizer/geqo_copy.h b/src/include/optimizer/geqo_copy.h index 2387b896e5..1066422266 100644 --- a/src/include/optimizer/geqo_copy.h +++ b/src/include/optimizer/geqo_copy.h @@ -3,7 +3,7 @@ * geqo_copy.h * prototypes for copy functions in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_copy.h diff --git a/src/include/optimizer/geqo_gene.h b/src/include/optimizer/geqo_gene.h index 220119ccb6..11be0af256 100644 --- a/src/include/optimizer/geqo_gene.h +++ b/src/include/optimizer/geqo_gene.h @@ -3,7 +3,7 @@ * geqo_gene.h * genome representation in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_gene.h diff --git a/src/include/optimizer/geqo_misc.h b/src/include/optimizer/geqo_misc.h index 4650fdf6d8..fbff49f08b 100644 --- a/src/include/optimizer/geqo_misc.h +++ b/src/include/optimizer/geqo_misc.h @@ -3,7 +3,7 @@ * geqo_misc.h * prototypes for printout routines in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_misc.h diff --git a/src/include/optimizer/geqo_mutation.h b/src/include/optimizer/geqo_mutation.h index a0db07e38d..13d49013c9 100644 --- a/src/include/optimizer/geqo_mutation.h +++ b/src/include/optimizer/geqo_mutation.h @@ -3,7 +3,7 @@ * geqo_mutation.h * prototypes for mutation functions in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_mutation.h diff --git a/src/include/optimizer/geqo_pool.h b/src/include/optimizer/geqo_pool.h index 8726bfc98a..522794db4b 100644 --- a/src/include/optimizer/geqo_pool.h +++ b/src/include/optimizer/geqo_pool.h @@ -3,7 +3,7 @@ * geqo_pool.h * pool representation in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_pool.h diff --git a/src/include/optimizer/geqo_random.h b/src/include/optimizer/geqo_random.h index 9615a6f089..80f756977e 100644 --- a/src/include/optimizer/geqo_random.h +++ b/src/include/optimizer/geqo_random.h @@ -3,7 +3,7 @@ * geqo_random.h * random number generator * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_random.h diff --git a/src/include/optimizer/geqo_recombination.h b/src/include/optimizer/geqo_recombination.h index cd82678b2e..09d68f2159 100644 --- a/src/include/optimizer/geqo_recombination.h +++ b/src/include/optimizer/geqo_recombination.h @@ -3,7 +3,7 @@ * geqo_recombination.h * prototypes for recombination in the genetic query optimizer * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_recombination.h diff --git a/src/include/optimizer/geqo_selection.h b/src/include/optimizer/geqo_selection.h index f3d5605ace..df6a729532 100644 --- a/src/include/optimizer/geqo_selection.h +++ b/src/include/optimizer/geqo_selection.h @@ -3,7 +3,7 @@ * geqo_selection.h * prototypes for selection routines in optimizer/geqo * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_selection.h diff --git a/src/include/optimizer/joininfo.h b/src/include/optimizer/joininfo.h index a639b5b443..21a81dd149 100644 --- a/src/include/optimizer/joininfo.h +++ b/src/include/optimizer/joininfo.h @@ -4,7 +4,7 @@ * prototypes for joininfo.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/joininfo.h diff --git a/src/include/optimizer/orclauses.h b/src/include/optimizer/orclauses.h new file mode 100644 index 0000000000..5a3020d641 --- /dev/null +++ b/src/include/optimizer/orclauses.h @@ -0,0 +1,21 @@ +/*------------------------------------------------------------------------- + * + * orclauses.h + * prototypes for orclauses.c. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/orclauses.h + * + *------------------------------------------------------------------------- + */ +#ifndef ORCLAUSES_H +#define ORCLAUSES_H + +#include "nodes/relation.h" + +extern void extract_restriction_or_clauses(PlannerInfo *root); + +#endif /* ORCLAUSES_H */ diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 2fd43c0cc6..057b37aaf6 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/pathnode.h @@ -60,7 +60,7 @@ extern BitmapOrPath *create_bitmap_or_path(PlannerInfo *root, RelOptInfo *rel, List *bitmapquals); extern TidPath *create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, - List *tidquals); + List *tidquals, Relids required_outer); extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths, Relids required_outer); extern MergeAppendPath *create_merge_append_path(PlannerInfo *root, @@ -80,10 +80,14 @@ extern Path *create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, extern Path *create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer); #endif -extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel); -extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel); -extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel); -extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel); +extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, + List *pathkeys, Relids required_outer); +extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); +extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); extern ForeignPath *create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, double rows, Cost startup_cost, Cost total_cost, List *pathkeys, @@ -154,6 +158,7 @@ extern RelOptInfo *build_join_rel(PlannerInfo *root, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List **restrictlist_ptr); +extern RelOptInfo *build_empty_join_rel(PlannerInfo *root); extern AppendRelInfo *find_childrel_appendrelinfo(PlannerInfo *root, RelOptInfo *rel); extern ParamPathInfo *get_baserel_parampathinfo(PlannerInfo *root, diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index b6fb8ee5ce..9b22fda1ef 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -4,7 +4,7 @@ * prototypes for various files in optimizer/path * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/paths.h @@ -43,15 +43,9 @@ extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel); * routines to generate index paths */ extern void create_index_paths(PlannerInfo *root, RelOptInfo *rel); -extern List *generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, - List *clauses, List *other_clauses, - bool restriction_only); extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List *exprlist, List *oprlist); -extern bool eclass_member_matches_indexcol(EquivalenceClass *ec, - EquivalenceMember *em, - IndexOptInfo *index, int indexcol); extern bool match_index_to_operand(Node *operand, int indexcol, IndexOptInfo *index); extern void expand_indexqual_conditions(IndexOptInfo *index, @@ -65,12 +59,6 @@ extern Expr *adjust_rowcompare_for_index(RowCompareExpr *clause, bool *var_on_left_p); /* - * orindxpath.c - * additional routines for indexable OR clauses - */ -extern bool create_or_index_quals(PlannerInfo *root, RelOptInfo *rel); - -/* * tidpath.h * routines to generate tid paths */ @@ -99,6 +87,12 @@ extern bool have_join_order_restriction(PlannerInfo *root, * equivclass.c * routines for managing EquivalenceClasses */ +typedef bool (*ec_matches_callback_type) (PlannerInfo *root, + RelOptInfo *rel, + EquivalenceClass *ec, + EquivalenceMember *em, + void *arg); + extern bool process_equivalence(PlannerInfo *root, RestrictInfo *restrictinfo, bool below_outer_join); extern Expr *canonicalize_ec_expression(Expr *expr, @@ -106,6 +100,7 @@ extern Expr *canonicalize_ec_expression(Expr *expr, extern void reconsider_outer_join_clauses(PlannerInfo *root); extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, + Relids nullable_relids, List *opfamilies, Oid opcintype, Oid collation, @@ -124,10 +119,13 @@ extern void add_child_rel_equivalences(PlannerInfo *root, RelOptInfo *child_rel); extern void mutate_eclass_expressions(PlannerInfo *root, Node *(*mutator) (), - void *context); -extern List *generate_implied_equalities_for_indexcol(PlannerInfo *root, - IndexOptInfo *index, - int indexcol); + void *context, + bool include_child_exprs); +extern List *generate_implied_equalities_for_column(PlannerInfo *root, + RelOptInfo *rel, + ec_matches_callback_type callback, + void *callback_arg, + Relids prohibited_rels); extern bool have_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2); extern bool has_relevant_eclass_joinclause(PlannerInfo *root, @@ -148,7 +146,6 @@ typedef enum PATHKEYS_DIFFERENT /* neither pathkey includes the other */ } PathKeysComparison; -extern List *canonicalize_pathkeys(PlannerInfo *root, List *pathkeys); extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2); extern bool pathkeys_contained_in(List *keys1, List *keys2); extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, @@ -160,6 +157,9 @@ extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths, double fraction); extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index, ScanDirection scandir); +extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr, + Relids nullable_relids, Oid opno, + Relids rel, bool create_it); extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *subquery_pathkeys); extern List *build_join_pathkeys(PlannerInfo *root, @@ -168,8 +168,7 @@ extern List *build_join_pathkeys(PlannerInfo *root, List *outer_pathkeys); extern List *make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, - List *tlist, - bool canonicalize); + List *tlist); extern void initialize_mergeclause_eclasses(PlannerInfo *root, RestrictInfo *restrictinfo); extern void update_mergeclause_eclasses(PlannerInfo *root, diff --git a/src/include/optimizer/placeholder.h b/src/include/optimizer/placeholder.h index b8ac25367e..273a012678 100644 --- a/src/include/optimizer/placeholder.h +++ b/src/include/optimizer/placeholder.h @@ -4,7 +4,7 @@ * prototypes for optimizer/util/placeholder.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/placeholder.h @@ -22,8 +22,6 @@ extern PlaceHolderVar *make_placeholder_expr(PlannerInfo *root, Expr *expr, extern PlaceHolderInfo *find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv, bool create_new_ph); extern void find_placeholders_in_jointree(PlannerInfo *root); -extern void mark_placeholder_maybe_needed(PlannerInfo *root, - PlaceHolderInfo *phinfo, Relids relids); extern void update_placeholder_eval_levels(PlannerInfo *root, SpecialJoinInfo *new_sjinfo); extern void fix_placeholder_input_needed_levels(PlannerInfo *root); diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h index cf4a3f2b99..7eb4d7ccf6 100644 --- a/src/include/optimizer/plancat.h +++ b/src/include/optimizer/plancat.h @@ -4,7 +4,7 @@ * prototypes for plancat.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/plancat.h @@ -43,11 +43,13 @@ extern bool has_unique_index(RelOptInfo *rel, AttrNumber attno); extern Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, + Oid inputcollid, int varRelid); extern Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, + Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo); diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index d26c12dcfe..487cd46fa0 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/planmain.h @@ -29,13 +29,14 @@ #define DEFAULT_CURSOR_TUPLE_FRACTION 0.1 extern double cursor_tuple_fraction; +/* query_planner callback to compute query_pathkeys */ +typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra); + /* * prototypes for plan/planmain.c */ -extern void query_planner(PlannerInfo *root, List *tlist, - double tuple_fraction, double limit_tuples, - Path **cheapest_path, Path **sorted_path, - double *num_groups); +extern RelOptInfo *query_planner(PlannerInfo *root, List *tlist, + query_pathkeys_callback qp_callback, void *qp_extra); /* * prototypes for plan/planagg.c @@ -87,8 +88,10 @@ extern SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, long numGroups, double outputRows); extern Result *make_result(PlannerInfo *root, List *tlist, Node *resconstantqual, Plan *subplan); -extern ModifyTable *make_modifytable(CmdType operation, bool canSetTag, - List *resultRelations, List *subplans, List *returningLists, +extern ModifyTable *make_modifytable(PlannerInfo *root, + CmdType operation, bool canSetTag, + List *resultRelations, List *subplans, + List *withCheckOptionLists, List *returningLists, List *rowMarks, int epqParam); extern bool is_projection_capable_plan(Plan *plan); @@ -102,6 +105,8 @@ extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode); extern void build_base_rel_tlists(PlannerInfo *root, List *final_tlist); extern void add_vars_to_targetlist(PlannerInfo *root, List *vars, Relids where_needed, bool create_new_ph); +extern void find_lateral_references(PlannerInfo *root); +extern void create_lateral_join_info(PlannerInfo *root); extern List *deconstruct_jointree(PlannerInfo *root); extern void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo); @@ -111,13 +116,15 @@ extern void process_implied_equality(PlannerInfo *root, Expr *item1, Expr *item2, Relids qualscope, + Relids nullable_relids, bool below_outer_join, bool both_const); extern RestrictInfo *build_implied_join_equality(Oid opno, Oid collation, Expr *item1, Expr *item2, - Relids qualscope); + Relids qualscope, + Relids nullable_relids); /* * prototypes for plan/analyzejoins.c diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index 79f71cdd36..29431d4468 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -4,7 +4,7 @@ * prototypes for planner.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/planner.h @@ -35,6 +35,9 @@ extern Plan *subquery_planner(PlannerGlobal *glob, Query *parse, bool hasRecursion, double tuple_fraction, PlannerInfo **subroot); +extern void add_tlist_costs_to_plan(PlannerInfo *root, Plan *plan, + List *tlist); + extern bool is_dummy_plan(Plan *plan); extern Expr *expression_planner(Expr *expr); @@ -43,6 +46,8 @@ extern void GetHashExecNodes(RelationLocInfo *rel_loc_info, ExecNodes **exec_nodes, const Expr *expr); #endif +extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr); + extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid); #endif /* PLANNER_H */ diff --git a/src/include/optimizer/predtest.h b/src/include/optimizer/predtest.h index bee102e82d..3573e3982c 100644 --- a/src/include/optimizer/predtest.h +++ b/src/include/optimizer/predtest.h @@ -4,7 +4,7 @@ * prototypes for predtest.c * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/predtest.h diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h index 47a27b66e8..f5fc7e8e71 100644 --- a/src/include/optimizer/prep.h +++ b/src/include/optimizer/prep.h @@ -4,7 +4,7 @@ * prototypes for files in optimizer/prep/ * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/prep.h @@ -23,9 +23,7 @@ */ extern void pull_up_sublinks(PlannerInfo *root); extern void inline_set_returning_functions(PlannerInfo *root); -extern Node *pull_up_subqueries(PlannerInfo *root, Node *jtnode, - JoinExpr *lowest_outer_join, - AppendRelInfo *containing_appendrel); +extern Node *pull_up_subqueries(PlannerInfo *root, Node *jtnode); extern void flatten_simple_union_all(PlannerInfo *root); extern void reduce_outer_joins(PlannerInfo *root); extern Relids get_relids_in_jointree(Node *jtnode, bool include_joins); @@ -38,6 +36,11 @@ extern Node *negate_clause(Node *node); extern Expr *canonicalize_qual(Expr *qual); /* + * prototypes for prepsecurity.c + */ +extern void expand_security_quals(PlannerInfo *root, List *tlist); + +/* * prototypes for preptlist.c */ extern List *preprocess_targetlist(PlannerInfo *root, List *tlist); diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 6c88aa679f..d404b2a2dc 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -4,7 +4,7 @@ * prototypes for restrictinfo.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/restrictinfo.h @@ -28,9 +28,6 @@ extern RestrictInfo *make_restrictinfo(Expr *clause, Relids required_relids, Relids outer_relids, Relids nullable_relids); -extern List *make_restrictinfo_from_bitmapqual(Path *bitmapqual, - bool is_pushed_down, - bool include_predicates); extern List *make_restrictinfos_from_actual_clauses(PlannerInfo *root, List *clause_list); extern bool restriction_is_or_clause(RestrictInfo *restrictinfo); @@ -41,7 +38,7 @@ extern List *extract_actual_clauses(List *restrictinfo_list, extern void extract_actual_join_clauses(List *restrictinfo_list, List **joinquals, List **otherquals); -extern bool join_clause_is_movable_to(RestrictInfo *rinfo, Index baserelid); +extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel); extern bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer); diff --git a/src/include/optimizer/subselect.h b/src/include/optimizer/subselect.h index 90fe8fc9c0..5607e98a13 100644 --- a/src/include/optimizer/subselect.h +++ b/src/include/optimizer/subselect.h @@ -2,7 +2,7 @@ * * subselect.h * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/subselect.h diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h index 693d58c6a1..122a17992c 100644 --- a/src/include/optimizer/tlist.h +++ b/src/include/optimizer/tlist.h @@ -4,7 +4,7 @@ * prototypes for tlist.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/tlist.h @@ -19,12 +19,16 @@ extern TargetEntry *tlist_member(Node *node, List *targetlist); extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist); +extern TargetEntry *tlist_member_match_var(Var *var, List *targetlist); extern List *flatten_tlist(List *tlist, PVCAggregateBehavior aggbehavior, PVCPlaceHolderBehavior phbehavior); extern List *add_to_flat_tlist(List *tlist, List *exprs); extern List *get_tlist_exprs(List *tlist, bool includeJunk); + +extern bool tlist_same_exprs(List *tlist1, List *tlist2); + extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK); extern bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK); diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h index f546362b68..fb99a1226c 100644 --- a/src/include/optimizer/var.h +++ b/src/include/optimizer/var.h @@ -4,7 +4,7 @@ * prototypes for optimizer/util/var.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/var.h @@ -31,12 +31,12 @@ typedef enum } PVCPlaceHolderBehavior; extern Relids pull_varnos(Node *node); +extern Relids pull_varnos_of_level(Node *node, int levelsup); extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos); +extern List *pull_vars_of_level(Node *node, int levelsup); extern bool contain_var_clause(Node *node); extern bool contain_vars_of_level(Node *node, int levelsup); extern int locate_var_of_level(Node *node, int levelsup); -extern int locate_var_of_relation(Node *node, int relid, int levelsup); -extern int find_minimum_var_level(Node *node); extern List *pull_var_clause(Node *node, PVCAggregateBehavior aggbehavior, PVCPlaceHolderBehavior phbehavior); extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node); diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h index 014bbd54ef..3cd52b30f9 100644 --- a/src/include/parser/analyze.h +++ b/src/include/parser/analyze.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/analyze.h @@ -41,9 +41,10 @@ extern Query *transformStmt(ParseState *pstate, Node *parseTree); extern bool analyze_requires_snapshot(Node *parseTree); -extern void CheckSelectLocking(Query *qry); +extern char *LCS_asString(LockClauseStrength strength); +extern void CheckSelectLocking(Query *qry, LockClauseStrength strength); extern void applyLockingClause(Query *qry, Index rtindex, - bool forUpdate, bool noWait, bool pushedDown); + LockClauseStrength strength, bool noWait, bool pushedDown); #ifdef XCP extern void ParseAnalyze_callback(ParseState *pstate, Query *query); diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h index 7ce369d645..90b74cc312 100644 --- a/src/include/parser/gramparse.h +++ b/src/include/parser/gramparse.h @@ -8,7 +8,7 @@ * outside the core parser should be in parser.h. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/gramparse.h @@ -29,7 +29,7 @@ #include "parser/gram.h" /* - * The YY_EXTRA data that a flex scanner allows us to pass around. Private + * The YY_EXTRA data that a flex scanner allows us to pass around. Private * state needed for raw parsing/lexing goes here. */ typedef struct base_yy_extra_type diff --git a/src/include/parser/keywords.h b/src/include/parser/keywords.h index 2b02ab0dd7..7316c80aff 100644 --- a/src/include/parser/keywords.h +++ b/src/include/parser/keywords.h @@ -4,7 +4,7 @@ * lexical token lookup for key words in PostgreSQL * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/keywords.h diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 977a5ba999..7ce84d2d0a 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -7,7 +7,7 @@ * by the PG_KEYWORD macro, which is not defined in this file; it can * be defined by the caller for special purposes. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -153,6 +153,7 @@ PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD) PG_KEYWORD("end", END_P, RESERVED_KEYWORD) PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD) PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD) +PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD) PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD) PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD) PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD) @@ -166,6 +167,7 @@ PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD) PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD) PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD) PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD) +PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD) PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD) PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD) PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD) @@ -224,6 +226,7 @@ PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD) PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD) PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD) PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD) +PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD) PG_KEYWORD("lc_collate", LC_COLLATE_P, UNRESERVED_KEYWORD) PG_KEYWORD("lc_ctype", LC_CTYPE_P, UNRESERVED_KEYWORD) PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD) @@ -242,6 +245,7 @@ PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD) PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD) PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD) PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD) +PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD) PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD) PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD) PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD) @@ -280,9 +284,10 @@ PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD) PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD) PG_KEYWORD("or", OR, RESERVED_KEYWORD) PG_KEYWORD("order", ORDER, RESERVED_KEYWORD) +PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD) PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD) PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD) -PG_KEYWORD("over", OVER, TYPE_FUNC_NAME_KEYWORD) +PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD) PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD) PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD) @@ -311,6 +316,7 @@ PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD) PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD) PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD) PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD) +PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD) PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD) PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD) PG_KEYWORD("read", READ, UNRESERVED_KEYWORD) @@ -320,6 +326,7 @@ PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD) PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD) PG_KEYWORD("ref", REF, UNRESERVED_KEYWORD) PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD) +PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD) PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD) PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD) PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD) @@ -423,12 +430,14 @@ PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD) PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD) PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD) +PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD) PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD) PG_KEYWORD("when", WHEN, RESERVED_KEYWORD) PG_KEYWORD("where", WHERE, RESERVED_KEYWORD) PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD) PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD) PG_KEYWORD("with", WITH, RESERVED_KEYWORD) +PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD) PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD) PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD) PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD) diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index 19fbb01535..ef7c1fb3f9 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -8,7 +8,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_agg.h @@ -27,10 +27,19 @@ extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, WindowDef *windef); extern void parseCheckAggregates(ParseState *pstate, Query *qry); -extern void parseCheckWindowFuncs(ParseState *pstate, Query *qry); + +extern int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes); + +extern Oid resolve_aggregate_transtype(Oid aggfuncid, + Oid aggtranstype, + Oid *inputTypes, + int numArguments); extern void build_aggregate_fnexprs(Oid *agg_input_types, int agg_num_inputs, + int agg_num_direct_inputs, + int num_finalfn_inputs, + bool agg_variadic, Oid agg_state_type, #ifdef XCP Oid agg_collect_type, @@ -41,11 +50,13 @@ extern void build_aggregate_fnexprs(Oid *agg_input_types, #ifdef XCP Oid collectfn_oid, #endif + Oid invtransfn_oid, Oid finalfn_oid, Expr **transfnexpr, #ifdef XCP Expr **collectfnexpr, #endif + Expr **invtransfnexpr, Expr **finalfnexpr); #endif /* PARSE_AGG_H */ diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index fd3fc8f570..e9e7cdc5eb 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -4,7 +4,7 @@ * handle clauses in parser * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_clause.h @@ -20,17 +20,18 @@ extern void transformFromClause(ParseState *pstate, List *frmList); extern int setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource, AclMode requiredPerms); extern bool interpretInhOption(InhOption inhOpt); -extern bool interpretOidsOption(List *defList); +extern bool interpretOidsOption(List *defList, bool allowOids); extern Node *transformWhereClause(ParseState *pstate, Node *clause, - const char *constructName); + ParseExprKind exprKind, const char *constructName); extern Node *transformLimitClause(ParseState *pstate, Node *clause, - const char *constructName); + ParseExprKind exprKind, const char *constructName); extern List *transformGroupClause(ParseState *pstate, List *grouplist, List **targetlist, List *sortClause, - bool useSQL99); + ParseExprKind exprKind, bool useSQL99); extern List *transformSortClause(ParseState *pstate, List *orderlist, - List **targetlist, bool resolveUnknown, bool useSQL99); + List **targetlist, ParseExprKind exprKind, + bool resolveUnknown, bool useSQL99); extern List *transformWindowDefinitions(ParseState *pstate, List *windowdefs, @@ -41,6 +42,9 @@ extern List *transformDistinctClause(ParseState *pstate, extern List *transformDistinctOnClause(ParseState *pstate, List *distinctlist, List **targetlist, List *sortClause); +extern List *addTargetToSortList(ParseState *pstate, TargetEntry *tle, + List *sortlist, List *targetlist, SortBy *sortby, + bool resolveUnknown); extern Index assignSortGroupRef(TargetEntry *tle, List *tlist); extern bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList); diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index 11ccbeb2ec..b0d256744e 100644 --- a/src/include/parser/parse_coerce.h +++ b/src/include/parser/parse_coerce.h @@ -4,7 +4,7 @@ * Routines for type coercion. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_coerce.h diff --git a/src/include/parser/parse_collate.h b/src/include/parser/parse_collate.h index 900a0676d5..e48aba202b 100644 --- a/src/include/parser/parse_collate.h +++ b/src/include/parser/parse_collate.h @@ -4,7 +4,7 @@ * Routines for assigning collation information. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_collate.h diff --git a/src/include/parser/parse_cte.h b/src/include/parser/parse_cte.h index c928a45463..5c16d02ad1 100644 --- a/src/include/parser/parse_cte.h +++ b/src/include/parser/parse_cte.h @@ -4,7 +4,7 @@ * handle CTEs (common table expressions) in parser * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_cte.h diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index 79be1ffa66..da858eb0e3 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -3,7 +3,7 @@ * parse_expr.h * handle expressions in parser * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_expr.h @@ -18,5 +18,8 @@ /* GUC parameters */ extern bool Transform_null_equals; -extern Node *transformExpr(ParseState *pstate, Node *expr); +extern Node *transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind); + +extern const char *ParseExprKindName(ParseExprKind exprKind); + #endif /* PARSE_EXPR_H */ diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index a280f9e8d4..e36860e3ef 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_func.h @@ -42,19 +42,16 @@ typedef enum } FuncDetailCode; -extern Node *ParseFuncOrColumn(ParseState *pstate, - List *funcname, List *fargs, - List *agg_order, bool agg_star, bool agg_distinct, - bool func_variadic, - WindowDef *over, bool is_column, int location); +extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, + FuncCall *fn, int location); extern FuncDetailCode func_get_detail(List *funcname, List *fargs, List *fargnames, int nargs, Oid *argtypes, bool expand_variadic, bool expand_defaults, Oid *funcid, Oid *rettype, - bool *retset, int *nvargs, Oid **true_typeids, - List **argdefaults); + bool *retset, int *nvargs, Oid *vatype, + Oid **true_typeids, List **argdefaults); extern int func_match_argtypes(int nargs, Oid *input_typeids, diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index 670e084993..4ce802a128 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -4,7 +4,7 @@ * Internal definitions for parser * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_node.h @@ -19,6 +19,55 @@ /* + * Expression kinds distinguished by transformExpr(). Many of these are not + * semantically distinct so far as expression transformation goes; rather, + * we distinguish them so that context-specific error messages can be printed. + * + * Note: EXPR_KIND_OTHER is not used in the core code, but is left for use + * by extension code that might need to call transformExpr(). The core code + * will not enforce any context-driven restrictions on EXPR_KIND_OTHER + * expressions, so the caller would have to check for sub-selects, aggregates, + * and window functions if those need to be disallowed. + */ +typedef enum ParseExprKind +{ + EXPR_KIND_NONE = 0, /* "not in an expression" */ + EXPR_KIND_OTHER, /* reserved for extensions */ + EXPR_KIND_JOIN_ON, /* JOIN ON */ + EXPR_KIND_JOIN_USING, /* JOIN USING */ + EXPR_KIND_FROM_SUBSELECT, /* sub-SELECT in FROM clause */ + EXPR_KIND_FROM_FUNCTION, /* function in FROM clause */ + EXPR_KIND_WHERE, /* WHERE */ + EXPR_KIND_HAVING, /* HAVING */ + EXPR_KIND_FILTER, /* FILTER */ + EXPR_KIND_WINDOW_PARTITION, /* window definition PARTITION BY */ + EXPR_KIND_WINDOW_ORDER, /* window definition ORDER BY */ + EXPR_KIND_WINDOW_FRAME_RANGE, /* window frame clause with RANGE */ + EXPR_KIND_WINDOW_FRAME_ROWS, /* window frame clause with ROWS */ + EXPR_KIND_SELECT_TARGET, /* SELECT target list item */ + EXPR_KIND_INSERT_TARGET, /* INSERT target list item */ + EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */ + EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */ + EXPR_KIND_GROUP_BY, /* GROUP BY */ + EXPR_KIND_ORDER_BY, /* ORDER BY */ + EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */ + EXPR_KIND_LIMIT, /* LIMIT */ + EXPR_KIND_OFFSET, /* OFFSET */ + EXPR_KIND_RETURNING, /* RETURNING */ + EXPR_KIND_VALUES, /* VALUES */ + EXPR_KIND_CHECK_CONSTRAINT, /* CHECK constraint for a table */ + EXPR_KIND_DOMAIN_CHECK, /* CHECK constraint for a domain */ + EXPR_KIND_COLUMN_DEFAULT, /* default value for a table column */ + EXPR_KIND_FUNCTION_DEFAULT, /* default parameter value for function */ + EXPR_KIND_INDEX_EXPRESSION, /* index expression */ + EXPR_KIND_INDEX_PREDICATE, /* index predicate */ + EXPR_KIND_ALTER_COL_TRANSFORM, /* transform expr in ALTER COLUMN TYPE */ + EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */ + EXPR_KIND_TRIGGER_WHEN /* WHEN condition in CREATE TRIGGER */ +} ParseExprKind; + + +/* * Function signatures for parser hooks */ typedef struct ParseState ParseState; @@ -38,7 +87,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, * links to current parse state of outer query. * * p_sourcetext: source string that generated the raw parsetree being - * analyzed, or NULL if not available. (The string is used only to + * analyzed, or NULL if not available. (The string is used only to * generate cursor positions in error messages: we need it to convert * byte-wise locations in parse structures to character-wise cursor * positions.) @@ -54,25 +103,20 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, * p_joinlist: list of join items (RangeTblRef and JoinExpr nodes) that * will become the fromlist of the query's top-level FromExpr node. * - * p_relnamespace: list of RTEs that represents the current namespace for - * table lookup, ie, those RTEs that are accessible by qualified names. - * This may be just a subset of the rtable + joinlist, and/or may contain - * entries that are not yet added to the main joinlist. + * p_namespace: list of ParseNamespaceItems that represents the current + * namespace for table and column lookup. (The RTEs listed here may be just + * a subset of the whole rtable. See ParseNamespaceItem comments below.) * - * p_varnamespace: list of RTEs that represents the current namespace for - * column lookup, ie, those RTEs that are accessible by unqualified names. - * This is different from p_relnamespace because a JOIN without an alias does - * not hide the contained tables (so they must still be in p_relnamespace) - * but it does hide their columns (unqualified references to the columns must - * refer to the JOIN, not the member tables). Other special RTEs such as - * NEW/OLD for rules may also appear in just one of these lists. + * p_lateral_active: TRUE if we are currently parsing a LATERAL subexpression + * of this parse level. This makes p_lateral_only namespace items visible, + * whereas they are not visible when p_lateral_active is FALSE. * * p_ctenamespace: list of CommonTableExprs (WITH items) that are visible - * at the moment. This is different from p_relnamespace because you have - * to make an RTE before you can access a CTE. + * at the moment. This is entirely different from p_namespace because a CTE + * is not an RTE, rather "visibility" means you could make an RTE from it. * * p_future_ctes: list of CommonTableExprs (WITH items) that are not yet - * visible due to scope rules. This is used to help improve error messages. + * visible due to scope rules. This is used to help improve error messages. * * p_parent_cte: CommonTableExpr that immediately contains the current query, * if any. @@ -91,12 +135,14 @@ struct ParseState List *p_joinexprs; /* JoinExprs for RTE_JOIN p_rtable entries */ List *p_joinlist; /* join items so far (will become FromExpr * node's fromlist) */ - List *p_relnamespace; /* current namespace for relations */ - List *p_varnamespace; /* current namespace for columns */ + List *p_namespace; /* currently-referenceable RTEs (List of + * ParseNamespaceItem) */ + bool p_lateral_active; /* p_lateral_only items visible? */ List *p_ctenamespace; /* current namespace for common table exprs */ List *p_future_ctes; /* common table exprs not yet in namespace */ CommonTableExpr *p_parent_cte; /* this query's containing CTE */ List *p_windowdefs; /* raw representations of window clauses */ + ParseExprKind p_expr_kind; /* what kind of expression we're parsing */ int p_next_resno; /* next targetlist resno to assign */ List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */ Node *p_value_substitute; /* what to replace VALUE with, if any */ @@ -121,12 +167,48 @@ struct ParseState void *p_ref_hook_state; /* common passthrough link for above */ }; +/* + * An element of a namespace list. + * + * Namespace items with p_rel_visible set define which RTEs are accessible by + * qualified names, while those with p_cols_visible set define which RTEs are + * accessible by unqualified names. These sets are different because a JOIN + * without an alias does not hide the contained tables (so they must be + * visible for qualified references) but it does hide their columns + * (unqualified references to the columns refer to the JOIN, not the member + * tables, so we must not complain that such a reference is ambiguous). + * Various special RTEs such as NEW/OLD for rules may also appear with only + * one flag set. + * + * While processing the FROM clause, namespace items may appear with + * p_lateral_only set, meaning they are visible only to LATERAL + * subexpressions. (The pstate's p_lateral_active flag tells whether we are + * inside such a subexpression at the moment.) If p_lateral_ok is not set, + * it's an error to actually use such a namespace item. One might think it + * would be better to just exclude such items from visibility, but the wording + * of SQL:2008 requires us to do it this way. We also use p_lateral_ok to + * forbid LATERAL references to an UPDATE/DELETE target table. + * + * At no time should a namespace list contain two entries that conflict + * according to the rules in checkNameSpaceConflicts; but note that those + * are more complicated than "must have different alias names", so in practice + * code searching a namespace list has to check for ambiguous references. + */ +typedef struct ParseNamespaceItem +{ + RangeTblEntry *p_rte; /* The relation's rangetable entry */ + bool p_rel_visible; /* Relation name is visible? */ + bool p_cols_visible; /* Column names visible as unqualified refs? */ + bool p_lateral_only; /* Is only visible to LATERAL expressions? */ + bool p_lateral_ok; /* If so, does join type allow use? */ +} ParseNamespaceItem; + /* Support for parser_errposition_callback function */ typedef struct ParseCallbackState { ParseState *pstate; int location; - ErrorContextCallback errcontext; + ErrorContextCallback errcallback; } ParseCallbackState; diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h index 3d05300693..7e94c10a99 100644 --- a/src/include/parser/parse_oper.h +++ b/src/include/parser/parse_oper.h @@ -4,7 +4,7 @@ * handle operator things for parser * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_oper.h diff --git a/src/include/parser/parse_param.h b/src/include/parser/parse_param.h index 07fb4a41f8..30645fd852 100644 --- a/src/include/parser/parse_param.h +++ b/src/include/parser/parse_param.h @@ -3,7 +3,7 @@ * parse_param.h * handle parameters in parser * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_param.h @@ -20,5 +20,6 @@ extern void parse_fixed_parameters(ParseState *pstate, extern void parse_variable_parameters(ParseState *pstate, Oid **paramTypes, int *numParams); extern void check_variable_parameters(ParseState *pstate, Query *query); +extern bool query_contains_extern_params(Query *query); #endif /* PARSE_PARAM_H */ diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index 66b5005ffc..aaa5ff5207 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -4,7 +4,7 @@ * prototypes for parse_relation.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_relation.h @@ -55,16 +55,20 @@ extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate, extern RangeTblEntry *addRangeTableEntryForSubquery(ParseState *pstate, Query *subquery, Alias *alias, + bool lateral, bool inFromCl); extern RangeTblEntry *addRangeTableEntryForFunction(ParseState *pstate, - char *funcname, - Node *funcexpr, + List *funcnames, + List *funcexprs, + List *coldeflists, RangeFunction *rangefunc, + bool lateral, bool inFromCl); extern RangeTblEntry *addRangeTableEntryForValues(ParseState *pstate, List *exprs, List *collations, Alias *alias, + bool lateral, bool inFromCl); extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate, List *colnames, @@ -81,7 +85,9 @@ extern bool isLockedRefname(ParseState *pstate, const char *refname); extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, bool addToJoinList, bool addToRelNameSpace, bool addToVarNameSpace); -extern void errorMissingRTE(ParseState *pstate, RangeVar *relation); +extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) __attribute__((noreturn)); +extern void errorMissingColumn(ParseState *pstate, + char *relname, char *colname, int location) __attribute__((noreturn)); extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, int location, bool include_dropped, List **colnames, List **colvars); @@ -91,6 +97,7 @@ extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK); extern Name attnumAttName(Relation rd, int attid); extern Oid attnumTypeId(Relation rd, int attid); extern Oid attnumCollationId(Relation rd, int attid); +extern bool isQueryUsingTempRelation(Query *query); #ifdef PGXC extern int specialAttNum(const char *attname); diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h index d274a66b13..f565493599 100644 --- a/src/include/parser/parse_target.h +++ b/src/include/parser/parse_target.h @@ -4,7 +4,7 @@ * handle target lists * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_target.h @@ -17,13 +17,16 @@ #include "parser/parse_node.h" -extern List *transformTargetList(ParseState *pstate, List *targetlist); -extern List *transformExpressionList(ParseState *pstate, List *exprlist); +extern List *transformTargetList(ParseState *pstate, List *targetlist, + ParseExprKind exprKind); +extern List *transformExpressionList(ParseState *pstate, List *exprlist, + ParseExprKind exprKind); extern void markTargetListOrigins(ParseState *pstate, List *targetlist); extern TargetEntry *transformTargetEntry(ParseState *pstate, - Node *node, Node *expr, + Node *node, Node *expr, ParseExprKind exprKind, char *colname, bool resjunk); extern Expr *transformAssignedExpr(ParseState *pstate, Expr *expr, + ParseExprKind exprKind, char *colname, int attrno, List *indirection, diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index c283a9fe64..fa9cc5989b 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -3,7 +3,7 @@ * parse_type.h * handle type operations for parser * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_type.h @@ -20,7 +20,9 @@ typedef HeapTuple Type; extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p); + int32 *typmod_p, bool missing_ok); +extern Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, + bool missing_ok); extern Type typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p); extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName); @@ -45,7 +47,7 @@ extern Datum stringTypeDatum(Type tp, char *string, int32 atttypmod); extern Oid typeidTypeRelid(Oid type_id); -extern void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p); +extern void parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok); #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h index 355335ae83..e1f8d8a980 100644 --- a/src/include/parser/parse_utilcmd.h +++ b/src/include/parser/parse_utilcmd.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -29,9 +29,10 @@ extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString, #else extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString); #endif -extern List *transformAlterTableStmt(AlterTableStmt *stmt, +extern List *transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, const char *queryString); -extern IndexStmt *transformIndexStmt(IndexStmt *stmt, const char *queryString); +extern IndexStmt *transformIndexStmt(Oid relid, IndexStmt *stmt, + const char *queryString); extern void transformRuleStmt(RuleStmt *stmt, const char *queryString, List **actions, Node **whereClause); extern List *transformCreateSchemaStmt(CreateSchemaStmt *stmt); diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index b9be6988eb..8d2068ad9b 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -5,7 +5,7 @@ * * This is the external API for the raw lexing/parsing functions. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parser.h diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h index 6093823ed5..ef67b41478 100644 --- a/src/include/parser/parsetree.h +++ b/src/include/parser/parsetree.h @@ -5,7 +5,7 @@ * parse trees. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parsetree.h diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 101464d3c4..1f2d185234 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -4,11 +4,11 @@ * API for the core scanner (flex machine) * * The core scanner is also used by PL/pgsql, so we provide a public API - * for it. However, the rest of the backend is only expected to use the + * for it. However, the rest of the backend is only expected to use the * higher-level API provided by parser.h. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scanner.h @@ -58,7 +58,7 @@ typedef union core_YYSTYPE /* * The YY_EXTRA data that a flex scanner allows us to pass around. - * Private state needed by the core scanner goes here. Note that the actual + * Private state needed by the core scanner goes here. Note that the actual * yy_extra struct may be larger and have this as its first component, thus * allowing the calling parser to keep some fields of its own in YY_EXTRA. */ diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h index f49bc1cb87..801cb57a73 100644 --- a/src/include/parser/scansup.h +++ b/src/include/parser/scansup.h @@ -4,7 +4,7 @@ * scanner support routines. used by both the bootstrap lexer * as well as the normal lexer * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scansup.h diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index c1f0fc02cb..e77f30ed50 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -260,21 +260,6 @@ /* Define to 1 if you have isinf(). */ #undef HAVE_ISINF -/* Define to 1 if `e_data' is member of `krb5_error'. */ -#undef HAVE_KRB5_ERROR_E_DATA - -/* Define to 1 if `text.data' is member of `krb5_error'. */ -#undef HAVE_KRB5_ERROR_TEXT_DATA - -/* Define to 1 if you have krb5_free_unparsed_name. */ -#undef HAVE_KRB5_FREE_UNPARSED_NAME - -/* Define to 1 if `client' is member of `krb5_ticket'. */ -#undef HAVE_KRB5_TICKET_CLIENT - -/* Define to 1 if `enc_part2' is member of `krb5_ticket'. */ -#undef HAVE_KRB5_TICKET_ENC_PART2 - /* Define to 1 if you have the <langinfo.h> header file. */ #undef HAVE_LANGINFO_H @@ -333,6 +318,9 @@ /* Define to 1 if `long long int' works and is 64 bits. */ #undef HAVE_LONG_LONG_INT_64 +/* Define to 1 if you have the `mbstowcs_l' function. */ +#undef HAVE_MBSTOWCS_L + /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE @@ -421,6 +409,9 @@ /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID +/* Define to 1 if you have the `shm_open' function. */ +#undef HAVE_SHM_OPEN + /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK @@ -451,9 +442,6 @@ /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R -/* Define to 1 if cpp supports the ANSI # stringizing operator. */ -#undef HAVE_STRINGIZE - /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H @@ -487,30 +475,33 @@ /* Define to 1 if the system has the type `struct option'. */ #undef HAVE_STRUCT_OPTION -/* Define to 1 if `sa_len' is member of `struct sockaddr'. */ +/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN /* Define to 1 if the system has the type `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE -/* Define to 1 if `ss_family' is member of `struct sockaddr_storage'. */ +/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY -/* Define to 1 if `ss_len' is member of `struct sockaddr_storage'. */ +/* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN -/* Define to 1 if `__ss_family' is member of `struct sockaddr_storage'. */ +/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY -/* Define to 1 if `__ss_len' is member of `struct sockaddr_storage'. */ +/* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN -/* Define to 1 if `tm_zone' is member of `struct tm'. */ +/* Define to 1 if `tm_zone' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE /* Define to 1 if you have the `symlink' function. */ #undef HAVE_SYMLINK +/* Define to 1 if you have the `sync_file_range' function. */ +#undef HAVE_SYNC_FILE_RANGE + /* Define to 1 if you have the syslog interface. */ #undef HAVE_SYSLOG @@ -599,6 +590,9 @@ /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV +/* Define to 1 if the system has the type `unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + /* Define to 1 if you have the `utime' function. */ #undef HAVE_UTIME @@ -608,15 +602,24 @@ /* Define to 1 if you have the <utime.h> header file. */ #undef HAVE_UTIME_H +/* Define to 1 if you have BSD UUID support. */ +#undef HAVE_UUID_BSD + +/* Define to 1 if you have E2FS UUID support. */ +#undef HAVE_UUID_E2FS + /* Define to 1 if you have the <uuid.h> header file. */ #undef HAVE_UUID_H +/* Define to 1 if you have OSSP UUID support. */ +#undef HAVE_UUID_OSSP + +/* Define to 1 if you have the <uuid/uuid.h> header file. */ +#undef HAVE_UUID_UUID_H + /* Define to 1 if you have the `vsnprintf' function. */ #undef HAVE_VSNPRINTF -/* Define to 1 if you have the `waitpid' function. */ -#undef HAVE_WAITPID - /* Define to 1 if you have the <wchar.h> header file. */ #undef HAVE_WCHAR_H @@ -632,15 +635,24 @@ /* Define to 1 if you have the <winldap.h> header file. */ #undef HAVE_WINLDAP_H -/* Define to 1 if your libxml has xmlStructuredErrorContext. */ -#undef HAVE_XMLSTRUCTUREDERRORCONTEXT +/* Define to 1 if your compiler understands __builtin_constant_p. */ +#undef HAVE__BUILTIN_CONSTANT_P + +/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ +#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P + +/* Define to 1 if your compiler understands __builtin_unreachable. */ +#undef HAVE__BUILTIN_UNREACHABLE + +/* Define to 1 if your compiler understands _Static_assert. */ +#undef HAVE__STATIC_ASSERT + +/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */ +#undef HAVE__VA_ARGS /* Define to the appropriate snprintf format for 64-bit ints. */ #undef INT64_FORMAT -/* Define to build with Kerberos 5 support. (--with-krb5) */ -#undef KRB5 - /* Define to 1 if `locale_t' requires <xlocale.h>. */ #undef LOCALE_T_IN_XLOCALE @@ -662,16 +674,26 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME +/* Define to the home page for this package. */ +#undef PACKAGE_URL + /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Define to the name of the default PostgreSQL service principal in Kerberos. - (--with-krb-srvnam=NAME) */ +/* Define to the name of a signed 64-bit integer type. */ +#undef PG_INT64_TYPE + +/* Define to the name of the default PostgreSQL service principal in Kerberos + (GSSAPI). (--with-krb-srvnam=NAME) */ #undef PG_KRB_SRVNAM /* PostgreSQL major version as a string */ #undef PG_MAJORVERSION +/* Define to 1 if "static inline" works without unwanted warnings from + compilations where static inline functions are defined but not called. */ +#undef PG_USE_INLINE + /* PostgreSQL version as a string */ #undef PG_VERSION @@ -752,10 +774,6 @@ (--enable-float8-byval) */ #undef USE_FLOAT8_BYVAL -/* Define to 1 if "static inline" works without unwanted warnings from - compilations where static inline functions are defined but not called. */ -#undef USE_INLINE - /* Define to 1 if you want 64-bit integer timestamp and interval support. (--enable-integer-datetimes) */ #undef USE_INTEGER_DATETIMES @@ -821,6 +839,8 @@ XLOG_BLCKSZ). Changing XLOG_SEG_SIZE requires an initdb. */ #undef XLOG_SEG_SIZE + + /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS @@ -830,9 +850,6 @@ /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus @@ -849,7 +866,3 @@ /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t - -/* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ -#undef volatile diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 6a3bdd634d..68365294f4 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -7,7 +7,7 @@ * HAVE_CBRT, HAVE_FUNCNAME_FUNC, HAVE_GETOPT, HAVE_GETOPT_H, HAVE_INTTYPES_H, * HAVE_GETOPT_LONG, HAVE_LOCALE_T, HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL, * HAVE_STRTOULL, HAVE_STRUCT_OPTION, ENABLE_THREAD_SAFETY, - * USE_INLINE, inline + * PG_USE_INLINE, inline */ /* Define to the type of arg 1 of 'accept' */ @@ -185,7 +185,7 @@ //#define HAVE_INTTYPES_H 1 /* Define to 1 if you have the global variable 'int timezone'. */ -#define HAVE_INT_TIMEZONE +#define HAVE_INT_TIMEZONE 1 /* Define to 1 if you have support for IPv6. */ #define HAVE_IPV6 1 @@ -193,18 +193,6 @@ /* Define to 1 if you have isinf(). */ #define HAVE_ISINF 1 -/* Define to 1 if `e_data' is member of `krb5_error'. */ -/* #undef HAVE_KRB5_ERROR_E_DATA */ - -/* Define to 1 if `text.data' is member of `krb5_error'. */ -/* #undef HAVE_KRB5_ERROR_TEXT_DATA */ - -/* Define to 1 if `client' is member of `krb5_ticket'. */ -/* #undef HAVE_KRB5_TICKET_CLIENT */ - -/* Define to 1 if `enc_part2' is member of `krb5_ticket'. */ -/* #undef HAVE_KRB5_TICKET_ENC_PART2 */ - /* Define to 1 if you have the <langinfo.h> header file. */ /* #undef HAVE_LANGINFO_H */ @@ -249,6 +237,9 @@ #define HAVE_LONG_LONG_INT_64 #endif +/* Define to 1 if you have the `mbstowcs_l' function. */ +#define HAVE_MBSTOWCS_L 1 + /* Define to 1 if you have the `memmove' function. */ #define HAVE_MEMMOVE 1 @@ -304,7 +295,10 @@ /* #undef HAVE_READLINK */ /* Define to 1 if you have the `rint' function. */ -/*#define HAVE_RINT 1*/ +#if (_MSC_VER >= 1800) +#define HAVE_RINT 1 +#endif + /* Define to 1 if you have the global variable 'rl_completion_append_character'. */ @@ -357,9 +351,6 @@ /* Define to 1 if you have the `strerror_r' function. */ /* #undef HAVE_STRERROR_R */ -/* Define to 1 if cpp supports the ANSI # stringizing operator. */ -#define HAVE_STRINGIZE 1 - /* Define to 1 if you have the <strings.h> header file. */ /*#define HAVE_STRINGS_H 1 */ @@ -420,6 +411,9 @@ /* Define to 1 if you have the `symlink' function. */ #define HAVE_SYMLINK 1 +/* Define to 1 if you have the `sync_file_range' function. */ +/* #undef HAVE_SYNC_FILE_RANGE */ + /* Define to 1 if you have the `sysconf' function. */ /* #undef HAVE_SYSCONF */ @@ -505,9 +499,6 @@ /* Define to 1 if you have the `vsnprintf' function. */ #define HAVE_VSNPRINTF 1 -/* Define to 1 if you have the `waitpid' function. */ -/* #undef HAVE_WAITPID */ - /* Define to 1 if you have the <wchar.h> header file. */ #define HAVE_WCHAR_H 1 @@ -523,12 +514,24 @@ /* Define to 1 if you have the <winldap.h> header file. */ /* #undef HAVE_WINLDAP_H */ +/* Define to 1 if your compiler understands __builtin_constant_p. */ +/* #undef HAVE__BUILTIN_CONSTANT_P */ + +/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ +/* #undef HAVE__BUILTIN_TYPES_COMPATIBLE_P */ + +/* Define to 1 if your compiler understands __builtin_unreachable. */ +/* #undef HAVE__BUILTIN_UNREACHABLE */ + +/* Define to 1 if your compiler understands _Static_assert. */ +/* #undef HAVE__STATIC_ASSERT */ + +/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */ +#define HAVE__VA_ARGS 1 + /* Define to the appropriate snprintf format for 64-bit ints, if any. */ #define INT64_FORMAT "%lld" -/* Define to build with Kerberos 5 support. (--with-krb5) */ -/* #undef KRB5 */ - /* Define to 1 if `locale_t' requires <xlocale.h>. */ /* #undef LOCALE_T_IN_XLOCALE */ @@ -548,16 +551,19 @@ #define PACKAGE_NAME "Postgres-XL" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Postgres-XL 9.2.0" +#define PACKAGE_STRING "Postgres-XL 9.4beta1" /* Define to the version of this package. */ -#define PACKAGE_VERSION "9.2beta2" +#define PACKAGE_VERSION "9.4beta1" + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long long int /* PostgreSQL version as a string */ -#define PG_VERSION "9.2beta2" +#define PG_VERSION "9.4beta1" /* PostgreSQL version as a number */ -#define PG_VERSION_NUM 90200 +#define PG_VERSION_NUM 90400 /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "postgres-xl" @@ -620,7 +626,7 @@ /* Define to 1 if "static inline" works without unwanted warnings from compilations where static inline functions are defined but not called. */ -#define USE_INLINE 1 +#define PG_USE_INLINE 1 /* Define to 1 if you want 64-bit integer timestamp and interval support. (--enable-integer-datetimes) */ @@ -651,7 +657,7 @@ /* #undef USE_UNNAMED_POSIX_SEMAPHORES */ /* Define to select Win32-style semaphores. */ -#define USE_WIN32_SEMAPHORES +#define USE_WIN32_SEMAPHORES 1 /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ @@ -662,9 +668,6 @@ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus @@ -673,7 +676,3 @@ /* Define to empty if the C compiler does not understand signed types. */ /* #undef signed */ - -/* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ -/* #undef volatile */ diff --git a/src/include/pg_config_ext.h.in b/src/include/pg_config_ext.h.in new file mode 100644 index 0000000000..8acadbdafd --- /dev/null +++ b/src/include/pg_config_ext.h.in @@ -0,0 +1,7 @@ +/* + * src/include/pg_config_ext.h.in. This is generated manually, not by + * autoheader, since we want to limit which symbols get defined here. + */ + +/* Define to the name of a signed 64-bit integer type. */ +#undef PG_INT64_TYPE diff --git a/src/include/pg_config_ext.h.win32 b/src/include/pg_config_ext.h.win32 new file mode 100644 index 0000000000..65bbb5d80d --- /dev/null +++ b/src/include/pg_config_ext.h.win32 @@ -0,0 +1,7 @@ +/* + * src/include/pg_config_ext.h.win32. This is generated manually, not by + * autoheader, since we want to limit which symbols get defined here. + */ + +/* Define to the name of a signed 64-bit integer type. */ +#define PG_INT64_TYPE long long int diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index f29f9e64e3..d1f99fbafe 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -3,10 +3,10 @@ * * This file contains various configuration symbols and limits. In * all cases, changing them is only useful in very rare situations or - * for developers. If you edit any of these, be sure to do a *full* + * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/pg_config_manual.h @@ -57,9 +57,17 @@ #define NUM_USER_DEFINED_LWLOCKS 4 /* + * When we don't have native spinlocks, we use semaphores to simulate them. + * Decreasing this value reduces consumption of OS resources; increasing it + * may improve performance, but supplying a real spinlock implementation is + * probably far better. + */ +#define NUM_SPINLOCK_SEMAPHORES 1024 + +/* * Define this if you want to allow the lo_import and lo_export SQL - * functions to be executed by ordinary users. By default these - * functions are only available to the Postgres superuser. CAUTION: + * functions to be executed by ordinary users. By default these + * functions are only available to the Postgres superuser. CAUTION: * These functions are SECURITY HOLES since they can read and write * any file that the PostgreSQL server has permission to access. If * you turn this on, don't say we didn't warn you. @@ -138,7 +146,7 @@ /* * This is the default directory in which AF_UNIX socket files are - * placed. Caution: changing this risks breaking your existing client + * placed. Caution: changing this risks breaking your existing client * applications, which are likely to continue to look in the old * directory. But if you just hate the idea of sockets in /tmp, * here's where to twiddle it. You can also override this at runtime @@ -151,7 +159,7 @@ * MAX_RANDOM_VALUE. Currently, all known implementations yield * 0..2^31-1, so we just hardwire this constant. We could do a * configure test if it proves to be necessary. CAUTION: Think not to - * replace this with RAND_MAX. RAND_MAX defines the maximum value of + * replace this with RAND_MAX. RAND_MAX defines the maximum value of * the older rand() function, which is often different from --- and * considerably inferior to --- random(). */ @@ -190,7 +198,7 @@ /* * On PPC machines, decide whether to use LWSYNC instructions in place of - * ISYNC and SYNC. This provides slightly better performance, but will + * ISYNC and SYNC. This provides slightly better performance, but will * result in illegal-instruction failures on some pre-POWER4 machines. * By default we use LWSYNC when building for 64-bit PPC, which should be * safe in nearly all cases. @@ -200,6 +208,17 @@ #endif /* + * Assumed cache line size. This doesn't affect correctness, but can be + * used for low-level optimizations. Currently, this is only used to pad + * some data structures in xlog.c, to ensure that highly-contended fields + * are on different cache lines. Too small a value can hurt performance due + * to false sharing, while the only downside of too large a value is a few + * bytes of wasted memory. The default is 128, which should be large enough + * for all supported platforms. + */ +#define CACHE_LINE_SIZE 128 + +/* *------------------------------------------------------------------------ * The following symbols are for enabling debugging code, not for * controlling user-visible features or resource limits. @@ -207,6 +226,21 @@ */ /* + * Include Valgrind "client requests", mostly in the memory allocator, so + * Valgrind understands PostgreSQL memory contexts. This permits detecting + * memory errors that Valgrind would not detect on a vanilla build. See also + * src/tools/valgrind.supp. "make installcheck" runs 20-30x longer under + * Valgrind. Note that USE_VALGRIND slowed older versions of Valgrind by an + * additional order of magnitude; Valgrind 3.8.1 does not have this problem. + * The client requests fall in hot code paths, so USE_VALGRIND also slows + * native execution by a few percentage points. + * + * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; + * instrumentation of repalloc() is inferior without it. + */ +/* #define USE_VALGRIND */ + +/* * Define this to cause pfree()'d memory to be cleared immediately, to * facilitate catching bugs that refer to already-freed values. * Right now, this gets defined automatically if --enable-cassert. @@ -217,17 +251,17 @@ /* * Define this to check memory allocation errors (scribbling on more - * bytes than were allocated). Right now, this gets defined - * automatically if --enable-cassert. + * bytes than were allocated). Right now, this gets defined + * automatically if --enable-cassert or USE_VALGRIND. */ -#ifdef USE_ASSERT_CHECKING +#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND) #define MEMORY_CONTEXT_CHECKING #endif /* * Define this to cause palloc()'d memory to be filled with random data, to * facilitate catching code that depends on the contents of uninitialized - * memory. Caution: this is horrendously expensive. + * memory. Caution: this is horrendously expensive. */ /* #define RANDOMIZE_ALLOCATED_MEMORY */ @@ -266,3 +300,10 @@ /* #define HEAPDEBUGALL */ /* #define ACLDEBUG */ /* #define RTDEBUG */ + +/* + * Automatic configuration file name for ALTER SYSTEM. + * This file will be used to store values of configuration parameters + * set by ALTER SYSTEM command. + */ +#define PG_AUTOCONF_FILENAME "postgresql.auto.conf" diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h new file mode 100644 index 0000000000..531c265f7c --- /dev/null +++ b/src/include/pg_getopt.h @@ -0,0 +1,46 @@ +/* + * Portions Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Portions Copyright (c) 2003-2014, PostgreSQL Global Development Group + * + * src/include/pg_getopt.h + */ +#ifndef PG_GETOPT_H +#define PG_GETOPT_H + +/* POSIX says getopt() is provided by unistd.h */ +#include <unistd.h> + +/* rely on the system's getopt.h if present */ +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif + +/* + * If we have <getopt.h>, assume it declares these variables, else do that + * ourselves. (We used to just declare them unconditionally, but Cygwin + * doesn't like that.) + */ +#ifndef HAVE_GETOPT_H + +extern char *optarg; +extern int optind; +extern int opterr; +extern int optopt; + +#endif /* HAVE_GETOPT_H */ + +/* + * Some platforms have optreset but fail to declare it in <getopt.h>, so cope. + * Cygwin, however, doesn't like this either. + */ +#if defined(HAVE_INT_OPTRESET) && !defined(__CYGWIN__) +extern int optreset; +#endif + +#ifndef HAVE_GETOPT +extern int getopt(int nargc, char *const * nargv, const char *ostr); +#endif + +#endif /* PG_GETOPT_H */ diff --git a/src/include/pg_trace.h b/src/include/pg_trace.h index 45d495fc0d..7e014b75c1 100644 --- a/src/include/pg_trace.h +++ b/src/include/pg_trace.h @@ -3,7 +3,7 @@ * * Definitions for the PostgreSQL tracing framework * - * Copyright (c) 2006-2012, PostgreSQL Global Development Group + * Copyright (c) 2006-2014, PostgreSQL Global Development Group * * src/include/pg_trace.h * ---------- diff --git a/src/include/pgstat.h b/src/include/pgstat.h index fdff029017..69e31ef667 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -8,7 +8,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Copyright (c) 2001-2012, PostgreSQL Global Development Group + * Copyright (c) 2001-2014, PostgreSQL Global Development Group * * src/include/pgstat.h * ---------- @@ -20,10 +20,22 @@ #include "fmgr.h" #include "libpq/pqcomm.h" #include "portability/instr_time.h" +#include "postmaster/pgarch.h" #include "utils/hsearch.h" #include "utils/relcache.h" +/* ---------- + * Paths for the statistics files (relative to installation's $PGDATA). + * ---------- + */ +#define PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat" +#define PGSTAT_STAT_PERMANENT_FILENAME "pg_stat/global.stat" +#define PGSTAT_STAT_PERMANENT_TMPFILE "pg_stat/global.tmp" + +/* Default directory to store temporary statistics data in */ +#define PG_STAT_TMP_DIR "pg_stat_tmp" + /* Values for track_functions GUC variable --- order is significant! */ typedef enum TrackFunctionsLevel { @@ -49,6 +61,7 @@ typedef enum StatMsgType PGSTAT_MTYPE_AUTOVAC_START, PGSTAT_MTYPE_VACUUM, PGSTAT_MTYPE_ANALYZE, + PGSTAT_MTYPE_ARCHIVER, PGSTAT_MTYPE_BGWRITER, PGSTAT_MTYPE_FUNCSTAT, PGSTAT_MTYPE_FUNCPURGE, @@ -107,6 +120,7 @@ typedef struct PgStat_TableCounts /* Possible targets for resetting cluster-wide shared values */ typedef enum PgStat_Shared_Reset_Target { + RESET_ARCHIVER, RESET_BGWRITER } PgStat_Shared_Reset_Target; @@ -128,7 +142,7 @@ typedef enum PgStat_Single_Reset_Type * * Many of the event counters are nontransactional, ie, we count events * in committed and aborted transactions alike. For these, we just count - * directly in the PgStat_TableStatus. However, delta_live_tuples, + * directly in the PgStat_TableStatus. However, delta_live_tuples, * delta_dead_tuples, and changed_tuples must be derived from event counts * with awareness of whether the transaction or subtransaction committed or * aborted. Hence, we also keep a stack of per-(sub)transaction status @@ -182,11 +196,13 @@ typedef struct PgStat_MsgHdr /* ---------- * Space available in a message. This will keep the UDP packets below 1K, - * which should fit unfragmented into the MTU of the lo interface on most - * platforms. Does anybody care for platforms where it doesn't? + * which should fit unfragmented into the MTU of the loopback interface. + * (Larger values of PGSTAT_MAX_MSG_SIZE would work for that on most + * platforms, but we're being conservative here.) * ---------- */ -#define PGSTAT_MSG_PAYLOAD (1000 - sizeof(PgStat_MsgHdr)) +#define PGSTAT_MAX_MSG_SIZE 1000 +#define PGSTAT_MSG_PAYLOAD (PGSTAT_MAX_MSG_SIZE - sizeof(PgStat_MsgHdr)) /* ---------- @@ -208,7 +224,9 @@ typedef struct PgStat_MsgDummy typedef struct PgStat_MsgInquiry { PgStat_MsgHdr m_hdr; - TimestampTz inquiry_time; /* minimum acceptable file timestamp */ + TimestampTz clock_time; /* observed local clock time */ + TimestampTz cutoff_time; /* minimum acceptable file timestamp */ + Oid databaseid; /* requested DB (InvalidOid => all DBs) */ } PgStat_MsgInquiry; @@ -228,7 +246,7 @@ typedef struct PgStat_TableEntry * ---------- */ #define PGSTAT_NUM_TABENTRIES \ - ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int)) \ + ((PGSTAT_MSG_PAYLOAD - sizeof(Oid) - 3 * sizeof(int) - 2 * sizeof(PgStat_Counter)) \ / sizeof(PgStat_TableEntry)) typedef struct PgStat_MsgTabstat @@ -334,7 +352,8 @@ typedef struct PgStat_MsgVacuum Oid m_tableoid; bool m_autovacuum; TimestampTz m_vacuumtime; - PgStat_Counter m_tuples; + PgStat_Counter m_live_tuples; + PgStat_Counter m_dead_tuples; } PgStat_MsgVacuum; @@ -356,6 +375,18 @@ typedef struct PgStat_MsgAnalyze /* ---------- + * PgStat_MsgArchiver Sent by the archiver to update statistics. + * ---------- + */ +typedef struct PgStat_MsgArchiver +{ + PgStat_MsgHdr m_hdr; + bool m_failed; /* Failed attempt */ + char m_xlog[MAX_XFN_CHARS + 1]; + TimestampTz m_timestamp; +} PgStat_MsgArchiver; + +/* ---------- * PgStat_MsgBgWriter Sent by the bgwriter to update statistics. * ---------- */ @@ -502,6 +533,7 @@ typedef union PgStat_Msg PgStat_MsgAutovacStart msg_autovacuum; PgStat_MsgVacuum msg_vacuum; PgStat_MsgAnalyze msg_analyze; + PgStat_MsgArchiver msg_archiver; PgStat_MsgBgWriter msg_bgwriter; PgStat_MsgFuncstat msg_funcstat; PgStat_MsgFuncpurge msg_funcpurge; @@ -518,7 +550,7 @@ typedef union PgStat_Msg * ------------------------------------------------------------ */ -#define PGSTAT_FILE_FORMAT_ID 0x01A5BC9A +#define PGSTAT_FILE_FORMAT_ID 0x01A5BC9C /* ---------- * PgStat_StatDBEntry The collector's data per database @@ -549,6 +581,7 @@ typedef struct PgStat_StatDBEntry PgStat_Counter n_block_write_time; TimestampTz stat_reset_timestamp; + TimestampTz stats_timestamp; /* time of db stats file update */ /* * tables and functions must be last in the struct, because we don't write @@ -611,6 +644,22 @@ typedef struct PgStat_StatFuncEntry /* + * Archiver statistics kept in the stats collector + */ +typedef struct PgStat_ArchiverStats +{ + PgStat_Counter archived_count; /* archival successes */ + char last_archived_wal[MAX_XFN_CHARS + 1]; /* last WAL file + * archived */ + TimestampTz last_archived_timestamp; /* last archival success time */ + PgStat_Counter failed_count; /* failed archival attempts */ + char last_failed_wal[MAX_XFN_CHARS + 1]; /* WAL file involved in + * last failure */ + TimestampTz last_failed_timestamp; /* last archival failure time */ + TimestampTz stat_reset_timestamp; +} PgStat_ArchiverStats; + +/* * Global statistics kept in the stats collector */ typedef struct PgStat_GlobalStats @@ -642,7 +691,7 @@ typedef enum BackendState STATE_IDLEINTRANSACTION, STATE_FASTPATH, STATE_IDLEINTRANSACTION_ABORTED, - STATE_DISABLED, + STATE_DISABLED } BackendState; /* ---------- @@ -701,6 +750,34 @@ typedef struct PgBackendStatus char *st_activity; } PgBackendStatus; +/* ---------- + * LocalPgBackendStatus + * + * When we build the backend status array, we use LocalPgBackendStatus to be + * able to add new values to the struct when needed without adding new fields + * to the shared memory. It contains the backend status as a first member. + * ---------- + */ +typedef struct LocalPgBackendStatus +{ + /* + * Local version of the backend status entry. + */ + PgBackendStatus backendStatus; + + /* + * The xid of the current transaction if available, InvalidTransactionId + * if not. + */ + TransactionId backend_xid; + + /* + * The xmin of the current session if available, InvalidTransactionId if + * not. + */ + TransactionId backend_xmin; +} LocalPgBackendStatus; + /* * Working state needed to accumulate per-function-call timing statistics. */ @@ -726,6 +803,7 @@ extern bool pgstat_track_activities; extern bool pgstat_track_counts; extern int pgstat_track_functions; extern PGDLLIMPORT int pgstat_track_activity_query_size; +extern char *pgstat_stat_directory; extern char *pgstat_stat_tmpname; extern char *pgstat_stat_filename; @@ -753,7 +831,7 @@ extern void pgstat_reset_all(void); extern void allow_immediate_pgstat_restart(void); #ifdef EXEC_BACKEND -extern void PgstatCollectorMain(int argc, char *argv[]); +extern void PgstatCollectorMain(int argc, char *argv[]) __attribute__((noreturn)); #endif @@ -774,7 +852,7 @@ extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type t extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, - PgStat_Counter tuples); + PgStat_Counter livetuples, PgStat_Counter deadtuples); extern void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples); @@ -866,6 +944,7 @@ extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info, extern void pgstat_twophase_postabort(TransactionId xid, uint16 info, void *recdata, uint32 len); +extern void pgstat_send_archiver(const char *xlog, bool failed); extern void pgstat_send_bgwriter(void); /* ---------- @@ -876,8 +955,10 @@ extern void pgstat_send_bgwriter(void); extern PgStat_StatDBEntry *pgstat_fetch_stat_dbentry(Oid dbid); extern PgStat_StatTabEntry *pgstat_fetch_stat_tabentry(Oid relid); extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid); +extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid); extern PgStat_StatFuncEntry *pgstat_fetch_stat_funcentry(Oid funcid); extern int pgstat_fetch_stat_numbackends(void); +extern PgStat_ArchiverStats *pgstat_fetch_stat_archiver(void); extern PgStat_GlobalStats *pgstat_fetch_global(void); #endif /* PGSTAT_H */ diff --git a/src/include/pgtar.h b/src/include/pgtar.h new file mode 100644 index 0000000000..2dd6f6b6a7 --- /dev/null +++ b/src/include/pgtar.h @@ -0,0 +1,15 @@ +/*------------------------------------------------------------------------- + * + * pgtar.h + * Functions for manipulating tarfile datastructures (src/port/tar.c) + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/pgtar.h + * + *------------------------------------------------------------------------- + */ +extern void tarCreateHeader(char *h, const char *filename, const char *linktarget, size_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime); +extern int tarChecksum(char *header); diff --git a/src/include/pgtime.h b/src/include/pgtime.h index f6e2514fdc..b3c867a4cf 100644 --- a/src/include/pgtime.h +++ b/src/include/pgtime.h @@ -3,7 +3,7 @@ * pgtime.h * PostgreSQL internal timezone library * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/pgtime.h @@ -68,6 +68,7 @@ extern pg_tz *log_timezone; extern void pg_timezone_initialize(void); extern pg_tz *pg_tzset(const char *tzname); +extern pg_tz *pg_tzset_offset(long gmtoffset); extern pg_tzenum *pg_tzenumerate_start(void); extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir); diff --git a/src/include/pgxc/barrier.h b/src/include/pgxc/barrier.h index 1ed9ffb445..084cc7f151 100644 --- a/src/include/pgxc/barrier.h +++ b/src/include/pgxc/barrier.h @@ -13,8 +13,8 @@ *------------------------------------------------------------------------- */ -#ifndef BARRIER_H -#define BARRIER_H +#ifndef PGXC_BARRIER_H +#define PGXC_BARRIER_H #include "access/xlog.h" #include "access/xlogdefs.h" diff --git a/src/include/port.h b/src/include/port.h index 25c4e9883d..c9226f3dac 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -3,7 +3,7 @@ * port.h * Header for src/port/ compatibility functions. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port.h @@ -45,6 +45,7 @@ extern void make_native_path(char *path); extern bool path_contains_parent_reference(const char *path); extern bool path_is_relative_and_below_cwd(const char *path); extern bool path_is_prefix_of_path(const char *path1, const char *path2); +extern char *make_absolute_path(const char *path); extern const char *get_progname(const char *argv0); extern void get_share_path(const char *my_exec_path, char *ret_path); extern void get_etc_path(const char *my_exec_path, char *ret_path); @@ -110,42 +111,8 @@ extern BOOL AddUserToTokenDacl(HANDLE hToken); #if defined(WIN32) && !defined(__CYGWIN__) #define DEVNULL "nul" -/* "con" does not work from the Msys 1.0.10 console (part of MinGW). */ -#define DEVTTY "con" #else #define DEVNULL "/dev/null" -#define DEVTTY "/dev/tty" -#endif - -/* - * Win32 needs double quotes at the beginning and end of system() - * strings. If not, it gets confused with multiple quoted strings. - * It also requires double-quotes around the executable name and - * any files used for redirection. Other args can use single-quotes. - * - * Generated using Win32 "CMD /?": - * - * 1. If all of the following conditions are met, then quote characters - * on the command line are preserved: - * - * - no /S switch - * - exactly two quote characters - * - no special characters between the two quote characters, where special - * is one of: &<>()@^| - * - there are one or more whitespace characters between the two quote - * characters - * - the string between the two quote characters is the name of an - * executable file. - * - * 2. Otherwise, old behavior is to see if the first character is a quote - * character and if so, strip the leading character and remove the last - * quote character on the command line, preserving any text after the last - * quote character. - */ -#if defined(WIN32) && !defined(__CYGWIN__) -#define SYSTEMQUOTE "\"" -#else -#define SYSTEMQUOTE "" #endif /* Portable delay handling */ @@ -163,7 +130,7 @@ extern unsigned char pg_ascii_tolower(unsigned char ch); /* * Versions of libintl >= 0.13 try to replace printf() and friends with - * macros to their own versions that understand the %$ format. We do the + * macros to their own versions that understand the %$ format. We do the * same, so disable their macros, if they exist. */ #ifdef vsnprintf @@ -334,13 +301,29 @@ extern FILE *pgwin32_fopen(const char *, const char *); #define fopen(a,b) pgwin32_fopen(a,b) #endif -#ifndef popen -#define popen(a,b) _popen(a,b) +/* + * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want + * to use our popen wrapper, rather than plain _popen, so override that. For + * consistency, use our version of pclose, too. + */ +#ifdef popen +#undef popen #endif -#ifndef pclose -#define pclose(a) _pclose(a) +#ifdef pclose +#undef pclose #endif +/* + * system() and popen() replacements to enclose the command in an extra + * pair of quotes. + */ +extern int pgwin32_system(const char *command); +extern FILE *pgwin32_popen(const char *command, const char *type); + +#define system(a) pgwin32_system(a) +#define popen(a,b) pgwin32_popen(a,b) +#define pclose(a) _pclose(a) + /* New versions of MingW have gettimeofday, old mingw and msvc don't */ #ifndef HAVE_GETTIMEOFDAY /* Last parameter not used */ @@ -356,6 +339,20 @@ extern int gettimeofday(struct timeval * tp, struct timezone * tzp); #endif /* WIN32 */ /* + * On Windows, setvbuf() does not support _IOLBF mode, and interprets that + * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) + * crashes outright if "parameter validation" is enabled. Therefore, in + * places where we'd like to select line-buffered mode, we fall back to + * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF + * directly in order to implement this behavior. + */ +#ifndef WIN32 +#define PG_IOLBF _IOLBF +#else +#define PG_IOLBF _IONBF +#endif + +/* * Default "extern" declarations or macro substitutes for library routines. * When necessary, these routines are provided by files in src/port/. */ @@ -385,10 +382,6 @@ extern int fls(int mask); #define ftello(a) ftell(a) #endif -#ifndef HAVE_GETOPT -extern int getopt(int nargc, char *const * nargv, const char *ostr); -#endif - #if !defined(HAVE_GETPEEREID) && !defined(WIN32) extern int getpeereid(int sock, uid_t *uid, gid_t *gid); #endif @@ -443,6 +436,7 @@ extern int pqGethostbyname(const char *name, extern void pg_qsort(void *base, size_t nel, size_t elsize, int (*cmp) (const void *, const void *)); +extern int pg_qsort_strcmp(const void *a, const void *b); #define qsort(a,b,c,d) pg_qsort(a,b,c,d) @@ -454,6 +448,10 @@ extern void qsort_arg(void *base, size_t nel, size_t elsize, /* port/chklocale.c */ extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); +#if defined(WIN32) && !defined(FRONTEND) +extern int pg_codepage_to_encoding(UINT cp); +#endif + /* port/inet_net_ntop.c */ extern char *inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size); @@ -464,4 +462,14 @@ extern int pg_check_dir(const char *dir); /* port/pgmkdirp.c */ extern int pg_mkdir_p(char *path, int omode); +/* port/pqsignal.c */ +typedef void (*pqsigfunc) (int signo); +extern pqsigfunc pqsignal(int signo, pqsigfunc func); + +/* port/quotes.c */ +extern char *escape_single_quotes_ascii(const char *src); + +/* port/wait_error.c */ +extern char *wait_result_to_str(int exit_status); + #endif /* PG_PORT_H */ diff --git a/src/include/port/cygwin.h b/src/include/port/cygwin.h index 4aca4bf66f..5c149470c6 100644 --- a/src/include/port/cygwin.h +++ b/src/include/port/cygwin.h @@ -9,10 +9,6 @@ #undef HAVE_UNIX_SOCKETS #endif -#if __GNUC__ && ! defined (__declspec) -#error You need egcs 1.1 or newer for compiling! -#endif - #ifdef BUILDING_DLL #define PGDLLIMPORT __declspec (dllexport) #else diff --git a/src/include/port/irix.h b/src/include/port/irix.h deleted file mode 100644 index bb05314a79..0000000000 --- a/src/include/port/irix.h +++ /dev/null @@ -1,7 +0,0 @@ -/* src/include/port/irix.h */ - -/* - * IRIX 6.5.26f and 6.5.22f (at least) have a strtod() that accepts - * "infinity", but leaves endptr pointing to "inity". - */ -#define HAVE_BUGGY_IRIX_STRTOD diff --git a/src/include/port/linux.h b/src/include/port/linux.h index bcaa42dc4e..7a6e46cdbb 100644 --- a/src/include/port/linux.h +++ b/src/include/port/linux.h @@ -4,7 +4,7 @@ * As of July 2007, all known versions of the Linux kernel will sometimes * return EIDRM for a shmctl() operation when EINVAL is correct (it happens * when the low-order 15 bits of the supplied shm ID match the slot number - * assigned to a newer shmem segment). We deal with this by assuming that + * assigned to a newer shmem segment). We deal with this by assuming that * EIDRM means EINVAL in PGSharedMemoryIsInUse(). This is reasonably safe * since in fact Linux has no excuse for ever returning EIDRM; it doesn't * track removed segments in a way that would allow distinguishing them from diff --git a/src/include/port/win32.h b/src/include/port/win32.h index a00ec897d2..550c3ecff4 100644 --- a/src/include/port/win32.h +++ b/src/include/port/win32.h @@ -65,12 +65,14 @@ #define USES_WINSOCK -/* defines for dynamic linking on Win32 platform */ -#if defined(WIN32) || defined(__CYGWIN__) +/* defines for dynamic linking on Win32 platform + * + * http://support.microsoft.com/kb/132044 + * http://msdn.microsoft.com/en-us/library/8fskxacy(v=vs.80).aspx + * http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx + */ -#if __GNUC__ && ! defined (__declspec) -#error You need egcs 1.1 or newer for compiling! -#endif +#if defined(WIN32) || defined(__CYGWIN__) #ifdef BUILDING_DLL #define PGDLLIMPORT __declspec (dllexport) @@ -118,7 +120,7 @@ * Signal stuff * * For WIN32, there is no wait() call so there are no wait() macros - * to interpret the return value of system(). Instead, system() + * to interpret the return value of system(). Instead, system() * return values < 0x100 are used for exit() termination, and higher * values are used to indicated non-exit() termination, which is * similar to a unix-style signal exit (think SIGSEGV == @@ -156,7 +158,7 @@ * NTSTATUS.H from the Windows NT DDK. * * Some day we might want to print descriptions for the most common - * exceptions, rather than printing an include file name. We could use + * exceptions, rather than printing an include file name. We could use * RtlNtStatusToDosError() and pass to FormatMessage(), which can print * the text of error values, but MinGW does not support * RtlNtStatusToDosError(). @@ -270,36 +272,26 @@ typedef int pid_t; #undef EINTR #define EINTR WSAEINTR #define EAGAIN WSAEWOULDBLOCK -#ifndef EMSGSIZE +#undef EMSGSIZE #define EMSGSIZE WSAEMSGSIZE -#endif -#ifndef EAFNOSUPPORT +#undef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT -#endif -#ifndef EWOULDBLOCK +#undef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK -#endif -#ifndef ECONNRESET +#undef ECONNRESET #define ECONNRESET WSAECONNRESET -#endif -#ifndef EINPROGRESS +#undef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS -#endif -#ifndef ENOBUFS +#undef ENOBUFS #define ENOBUFS WSAENOBUFS -#endif -#ifndef EPROTONOSUPPORT +#undef EPROTONOSUPPORT #define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#endif -#ifndef ECONNREFUSED +#undef ECONNREFUSED #define ECONNREFUSED WSAECONNREFUSED -#endif -#ifndef EBADFD +#undef EBADFD #define EBADFD WSAENOTSOCK -#endif -#ifndef EOPNOTSUPP +#undef EOPNOTSUPP #define EOPNOTSUPP WSAEOPNOTSUPP -#endif /* * For Microsoft Visual Studio 2010 and above we intentionally redefine @@ -435,8 +427,10 @@ typedef unsigned short mode_t; #define W_OK 2 #define R_OK 4 +#if (_MSC_VER < 1800) #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) || (_fpclass(x) == _FPCLASS_NINF)) #define isnan(x) _isnan(x) +#endif /* Pulled from Makefile.port in mingw */ #define DLSUFFIX ".dll" diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h index d7dfda2114..91f38693f8 100644 --- a/src/include/portability/instr_time.h +++ b/src/include/portability/instr_time.h @@ -10,8 +10,8 @@ * high-precision-timing APIs on yet other platforms. * * The basic data type is instr_time, which all callers should treat as an - * opaque typedef. instr_time can store either an absolute time (of - * unspecified reference time) or an interval. The operations provided + * opaque typedef. instr_time can store either an absolute time (of + * unspecified reference time) or an interval. The operations provided * for it are: * * INSTR_TIME_IS_ZERO(t) is t equal to zero? @@ -43,7 +43,7 @@ * Beware of multiple evaluations of the macro arguments. * * - * Copyright (c) 2001-2012, PostgreSQL Global Development Group + * Copyright (c) 2001-2014, PostgreSQL Global Development Group * * src/include/portability/instr_time.h * diff --git a/src/include/portability/mem.h b/src/include/portability/mem.h new file mode 100644 index 0000000000..a0bde5e1a3 --- /dev/null +++ b/src/include/portability/mem.h @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------- + * + * mem.h + * portability definitions for various memory operations + * + * Copyright (c) 2001-2014, PostgreSQL Global Development Group + * + * src/include/portability/mem.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEM_H +#define MEM_H + +#define IPCProtection (0600) /* access/modify by user only */ + +#ifdef SHM_SHARE_MMU /* use intimate shared memory on Solaris */ +#define PG_SHMAT_FLAGS SHM_SHARE_MMU +#else +#define PG_SHMAT_FLAGS 0 +#endif + +/* Linux prefers MAP_ANONYMOUS, but the flag is called MAP_ANON on other systems. */ +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +/* BSD-derived systems have MAP_HASSEMAPHORE, but it's not present (or needed) on Linux. */ +#ifndef MAP_HASSEMAPHORE +#define MAP_HASSEMAPHORE 0 +#endif + +#define PG_MMAP_FLAGS (MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE) + +/* Some really old systems don't define MAP_FAILED. */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif + +#endif /* MEM_H */ diff --git a/src/include/postgres.h b/src/include/postgres.h index 10b3d16760..8dea56a4f4 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -7,7 +7,7 @@ * Client-side code should include postgres_fe.h instead. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -26,7 +26,7 @@ * ------- ------------------------------------------------ * 1) variable-length datatypes (TOAST support) * 2) datum type + support macros - * 3) exception handling definitions + * 3) exception handling backend support * * NOTES * @@ -34,7 +34,7 @@ * in the backend environment, but are of no interest outside the backend. * * Simple type definitions live in c.h, where they are shared with - * postgres_fe.h. We do that since those type definitions are needed by + * postgres_fe.h. We do that since those type definitions are needed by * frontend modules that want to deal with binary data transmission to or * from the backend. Type definitions in this file should be for * representations that never escape the backend, such as Datum or @@ -55,23 +55,53 @@ */ /* - * struct varatt_external is a "TOAST pointer", that is, the information - * needed to fetch a stored-out-of-line Datum. The data is compressed - * if and only if va_extsize < va_rawsize - VARHDRSZ. This struct must not - * contain any padding, because we sometimes compare pointers using memcmp. + * struct varatt_external is a "TOAST pointer", that is, the information needed + * to fetch a Datum stored in an out-of-line on-disk Datum. The data is + * compressed if and only if va_extsize < va_rawsize - VARHDRSZ. This struct + * must not contain any padding, because we sometimes compare pointers using + * memcmp. * * Note that this information is stored unaligned within actual tuples, so * you need to memcpy from the tuple into a local struct variable before * you can look at these fields! (The reason we use memcmp is to avoid * having to do that just to detect equality of two TOAST pointers...) */ -struct varatt_external +typedef struct varatt_external { int32 va_rawsize; /* Original data size (includes header) */ int32 va_extsize; /* External saved size (doesn't) */ Oid va_valueid; /* Unique ID of value within TOAST table */ Oid va_toastrelid; /* RelID of TOAST table containing it */ -}; +} varatt_external; + +/* + * Out-of-line Datum thats stored in memory in contrast to varatt_external + * pointers which points to data in an external toast relation. + * + * Note that just as varatt_external's this is stored unaligned within the + * tuple. + */ +typedef struct varatt_indirect +{ + struct varlena *pointer; /* Pointer to in-memory varlena */ +} varatt_indirect; + + +/* + * Type of external toast datum stored. The peculiar value for VARTAG_ONDISK + * comes from the requirement for on-disk compatibility with the older + * definitions of varattrib_1b_e where v_tag was named va_len_1be... + */ +typedef enum vartag_external +{ + VARTAG_INDIRECT = 1, + VARTAG_ONDISK = 18 +} vartag_external; + +#define VARTAG_SIZE(tag) \ + ((tag) == VARTAG_INDIRECT ? sizeof(varatt_indirect) : \ + (tag) == VARTAG_ONDISK ? sizeof(varatt_external) : \ + TrapMacro(true, "unknown vartag")) /* * These structs describe the header of a varlena object that may have been @@ -103,11 +133,12 @@ typedef struct char va_data[1]; /* Data begins here */ } varattrib_1b; +/* inline portion of a short varlena pointing to an external resource */ typedef struct { uint8 va_header; /* Always 0x80 or 0x01 */ - uint8 va_len_1be; /* Physical length of datum */ - char va_data[1]; /* Data (for now always a TOAST pointer) */ + uint8 va_tag; /* Type of datum */ + char va_data[1]; /* Data (of the type indicated by va_tag) */ } varattrib_1b_e; /* @@ -128,9 +159,12 @@ typedef struct * The "xxx" bits are the length field (which includes itself in all cases). * In the big-endian case we mask to extract the length, in the little-endian * case we shift. Note that in both cases the flag bits are in the physically - * first byte. Also, it is not possible for a 1-byte length word to be zero; + * first byte. Also, it is not possible for a 1-byte length word to be zero; * this lets us disambiguate alignment padding bytes from the start of an * unaligned datum. (We now *require* pad bytes to be filled with zero!) + * + * In TOAST datums the tag field in varattrib_1b_e is used to discern whether + * its an indirection pointer or more commonly an on-disk tuple. */ /* @@ -162,8 +196,8 @@ typedef struct (((varattrib_4b *) (PTR))->va_4byte.va_header & 0x3FFFFFFF) #define VARSIZE_1B(PTR) \ (((varattrib_1b *) (PTR))->va_header & 0x7F) -#define VARSIZE_1B_E(PTR) \ - (((varattrib_1b_e *) (PTR))->va_len_1be) +#define VARTAG_1B_E(PTR) \ + (((varattrib_1b_e *) (PTR))->va_tag) #define SET_VARSIZE_4B(PTR,len) \ (((varattrib_4b *) (PTR))->va_4byte.va_header = (len) & 0x3FFFFFFF) @@ -171,9 +205,9 @@ typedef struct (((varattrib_4b *) (PTR))->va_4byte.va_header = ((len) & 0x3FFFFFFF) | 0x40000000) #define SET_VARSIZE_1B(PTR,len) \ (((varattrib_1b *) (PTR))->va_header = (len) | 0x80) -#define SET_VARSIZE_1B_E(PTR,len) \ +#define SET_VARTAG_1B_E(PTR,tag) \ (((varattrib_1b_e *) (PTR))->va_header = 0x80, \ - ((varattrib_1b_e *) (PTR))->va_len_1be = (len)) + ((varattrib_1b_e *) (PTR))->va_tag = (tag)) #else /* !WORDS_BIGENDIAN */ #define VARATT_IS_4B(PTR) \ @@ -194,8 +228,8 @@ typedef struct ((((varattrib_4b *) (PTR))->va_4byte.va_header >> 2) & 0x3FFFFFFF) #define VARSIZE_1B(PTR) \ ((((varattrib_1b *) (PTR))->va_header >> 1) & 0x7F) -#define VARSIZE_1B_E(PTR) \ - (((varattrib_1b_e *) (PTR))->va_len_1be) +#define VARTAG_1B_E(PTR) \ + (((varattrib_1b_e *) (PTR))->va_tag) #define SET_VARSIZE_4B(PTR,len) \ (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2)) @@ -203,12 +237,12 @@ typedef struct (((varattrib_4b *) (PTR))->va_4byte.va_header = (((uint32) (len)) << 2) | 0x02) #define SET_VARSIZE_1B(PTR,len) \ (((varattrib_1b *) (PTR))->va_header = (((uint8) (len)) << 1) | 0x01) -#define SET_VARSIZE_1B_E(PTR,len) \ +#define SET_VARTAG_1B_E(PTR,tag) \ (((varattrib_1b_e *) (PTR))->va_header = 0x01, \ - ((varattrib_1b_e *) (PTR))->va_len_1be = (len)) + ((varattrib_1b_e *) (PTR))->va_tag = (tag)) #endif /* WORDS_BIGENDIAN */ -#define VARHDRSZ_SHORT 1 +#define VARHDRSZ_SHORT offsetof(varattrib_1b, va_data) #define VARATT_SHORT_MAX 0x7F #define VARATT_CAN_MAKE_SHORT(PTR) \ (VARATT_IS_4B_U(PTR) && \ @@ -216,7 +250,7 @@ typedef struct #define VARATT_CONVERTED_SHORT_SIZE(PTR) \ (VARSIZE(PTR) - VARHDRSZ + VARHDRSZ_SHORT) -#define VARHDRSZ_EXTERNAL 2 +#define VARHDRSZ_EXTERNAL offsetof(varattrib_1b_e, va_data) #define VARDATA_4B(PTR) (((varattrib_4b *) (PTR))->va_4byte.va_data) #define VARDATA_4B_C(PTR) (((varattrib_4b *) (PTR))->va_compressed.va_data) @@ -250,26 +284,33 @@ typedef struct #define VARSIZE_SHORT(PTR) VARSIZE_1B(PTR) #define VARDATA_SHORT(PTR) VARDATA_1B(PTR) -#define VARSIZE_EXTERNAL(PTR) VARSIZE_1B_E(PTR) +#define VARTAG_EXTERNAL(PTR) VARTAG_1B_E(PTR) +#define VARSIZE_EXTERNAL(PTR) (VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR))) #define VARDATA_EXTERNAL(PTR) VARDATA_1B_E(PTR) #define VARATT_IS_COMPRESSED(PTR) VARATT_IS_4B_C(PTR) #define VARATT_IS_EXTERNAL(PTR) VARATT_IS_1B_E(PTR) +#define VARATT_IS_EXTERNAL_ONDISK(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_ONDISK) +#define VARATT_IS_EXTERNAL_INDIRECT(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_INDIRECT) #define VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR) #define VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR)) #define SET_VARSIZE(PTR, len) SET_VARSIZE_4B(PTR, len) #define SET_VARSIZE_SHORT(PTR, len) SET_VARSIZE_1B(PTR, len) #define SET_VARSIZE_COMPRESSED(PTR, len) SET_VARSIZE_4B_C(PTR, len) -#define SET_VARSIZE_EXTERNAL(PTR, len) SET_VARSIZE_1B_E(PTR, len) + +#define SET_VARTAG_EXTERNAL(PTR, tag) SET_VARTAG_1B_E(PTR, tag) #define VARSIZE_ANY(PTR) \ - (VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR) : \ + (VARATT_IS_1B_E(PTR) ? VARSIZE_EXTERNAL(PTR) : \ (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR) : \ VARSIZE_4B(PTR))) +/* Size of a varlena data, excluding header */ #define VARSIZE_ANY_EXHDR(PTR) \ - (VARATT_IS_1B_E(PTR) ? VARSIZE_1B_E(PTR)-VARHDRSZ_EXTERNAL : \ + (VARATT_IS_1B_E(PTR) ? VARSIZE_EXTERNAL(PTR)-VARHDRSZ_EXTERNAL : \ (VARATT_IS_1B(PTR) ? VARSIZE_1B(PTR)-VARHDRSZ_SHORT : \ VARSIZE_4B(PTR)-VARHDRSZ)) @@ -458,6 +499,13 @@ typedef Datum *DatumPtr; #define TransactionIdGetDatum(X) ((Datum) SET_4_BYTES((X))) /* + * MultiXactIdGetDatum + * Returns datum representation for a multixact identifier. + */ + +#define MultiXactIdGetDatum(X) ((Datum) SET_4_BYTES((X))) + +/* * DatumGetCommandId * Returns command identifier value of a datum. */ @@ -628,61 +676,17 @@ extern Datum Float8GetDatum(float8 X); /* ---------------------------------------------------------------- - * Section 3: exception handling definitions - * Assert, Trap, etc macros + * Section 3: exception handling backend support * ---------------------------------------------------------------- */ -extern PGDLLIMPORT bool assert_enabled; - /* - * USE_ASSERT_CHECKING, if defined, turns on all the assertions. - * - plai 9/5/90 - * - * It should _NOT_ be defined in releases or in benchmark copies + * These declarations supports the assertion-related macros in c.h. + * assert_enabled is here because that file doesn't have PGDLLIMPORT in the + * right place, and ExceptionalCondition must be present, for the backend only, + * even when assertions are not enabled. */ - -/* - * Trap - * Generates an exception if the given condition is true. - */ -#define Trap(condition, errorType) \ - do { \ - if ((assert_enabled) && (condition)) \ - ExceptionalCondition(CppAsString(condition), (errorType), \ - __FILE__, __LINE__); \ - } while (0) - -/* - * TrapMacro is the same as Trap but it's intended for use in macros: - * - * #define foo(x) (AssertMacro(x != 0), bar(x)) - * - * Isn't CPP fun? - */ -#define TrapMacro(condition, errorType) \ - ((bool) ((! assert_enabled) || ! (condition) || \ - (ExceptionalCondition(CppAsString(condition), (errorType), \ - __FILE__, __LINE__), 0))) - -#ifndef USE_ASSERT_CHECKING -#define Assert(condition) -#define AssertMacro(condition) ((void)true) -#define AssertArg(condition) -#define AssertState(condition) -#else -#define Assert(condition) \ - Trap(!(condition), "FailedAssertion") - -#define AssertMacro(condition) \ - ((void) TrapMacro(!(condition), "FailedAssertion")) - -#define AssertArg(condition) \ - Trap(!(condition), "BadArgument") - -#define AssertState(condition) \ - Trap(!(condition), "BadState") -#endif /* USE_ASSERT_CHECKING */ +extern PGDLLIMPORT bool assert_enabled; extern void ExceptionalCondition(const char *conditionName, const char *errorType, diff --git a/src/include/postgres_ext.h b/src/include/postgres_ext.h index b6ebb7aac3..74c344c704 100644 --- a/src/include/postgres_ext.h +++ b/src/include/postgres_ext.h @@ -7,7 +7,7 @@ * For example, the Oid type is part of the API of libpq and other libraries. * * Declarations which are specific to a particular interface should - * go in the header file for that interface (such as libpq-fe.h). This + * go in the header file for that interface (such as libpq-fe.h). This * file is only for fundamental Postgres declarations. * * User-written C functions don't count as "external to Postgres." @@ -23,6 +23,8 @@ #ifndef POSTGRES_EXT_H #define POSTGRES_EXT_H +#include "pg_config_ext.h" + /* * Object ID is a fundamental type in Postgres. */ @@ -37,6 +39,9 @@ typedef unsigned int Oid; #define OID_MAX UINT_MAX /* you will need to include <limits.h> to use the above #define */ +/* Define a signed 64-bit integer type for use in client API declarations. */ +typedef PG_INT64_TYPE pg_int64; + /* * Identifiers of error message fields. Kept here to keep common @@ -52,8 +57,13 @@ typedef unsigned int Oid; #define PG_DIAG_INTERNAL_POSITION 'p' #define PG_DIAG_INTERNAL_QUERY 'q' #define PG_DIAG_CONTEXT 'W' +#define PG_DIAG_SCHEMA_NAME 's' +#define PG_DIAG_TABLE_NAME 't' +#define PG_DIAG_COLUMN_NAME 'c' +#define PG_DIAG_DATATYPE_NAME 'd' +#define PG_DIAG_CONSTRAINT_NAME 'n' #define PG_DIAG_SOURCE_FILE 'F' #define PG_DIAG_SOURCE_LINE 'L' #define PG_DIAG_SOURCE_FUNCTION 'R' -#endif +#endif /* POSTGRES_EXT_H */ diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h index fcfbd31d35..8647ca8a53 100644 --- a/src/include/postgres_fe.h +++ b/src/include/postgres_fe.h @@ -8,7 +8,7 @@ * postgres.h. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * * src/include/postgres_fe.h @@ -24,4 +24,6 @@ #include "c.h" +#include "common/fe_memutils.h" + #endif /* POSTGRES_FE_H */ diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h index 8f11d221a1..9c98e9ac9f 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -4,7 +4,7 @@ * header file for integrated autovacuum daemon * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -24,12 +24,14 @@ /* GUC variables */ extern bool autovacuum_start_daemon; extern int autovacuum_max_workers; +extern int autovacuum_work_mem; extern int autovacuum_naptime; extern int autovacuum_vac_thresh; extern double autovacuum_vac_scale; extern int autovacuum_anl_thresh; extern double autovacuum_anl_scale; extern int autovacuum_freeze_max_age; +extern int autovacuum_multixact_freeze_max_age; extern int autovacuum_vac_cost_delay; extern int autovacuum_vac_cost_limit; @@ -58,8 +60,8 @@ extern void AutoVacWorkerFailed(void); extern void AutoVacuumUpdateDelay(void); #ifdef EXEC_BACKEND -extern void AutoVacLauncherMain(int argc, char *argv[]); -extern void AutoVacWorkerMain(int argc, char *argv[]); +extern void AutoVacLauncherMain(int argc, char *argv[]) __attribute__((noreturn)); +extern void AutoVacWorkerMain(int argc, char *argv[]) __attribute__((noreturn)); extern void AutovacuumWorkerIAm(void); extern void AutovacuumLauncherIAm(void); #endif diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h new file mode 100644 index 0000000000..a3b3d5f1a3 --- /dev/null +++ b/src/include/postmaster/bgworker.h @@ -0,0 +1,137 @@ +/*-------------------------------------------------------------------- + * bgworker.h + * POSTGRES pluggable background workers interface + * + * A background worker is a process able to run arbitrary, user-supplied code, + * including normal transactions. + * + * Any external module loaded via shared_preload_libraries can register a + * worker. Workers can also be registered dynamically at runtime. In either + * case, the worker process is forked from the postmaster and runs the + * user-supplied "main" function. This code may connect to a database and + * run transactions. Workers can remain active indefinitely, but will be + * terminated if a shutdown or crash occurs. + * + * If the fork() call fails in the postmaster, it will try again later. Note + * that the failure can only be transient (fork failure due to high load, + * memory pressure, too many processes, etc); more permanent problems, like + * failure to connect to a database, are detected later in the worker and dealt + * with just by having the worker exit normally. A worker which exits with + * a return code of 0 will never be restarted and will be removed from worker + * list. A worker which exits with a return code of 1 will be restarted after + * the configured restart interval (unless that interval is BGW_NEVER_RESTART). + * The TerminateBackgroundWorker() function can be used to terminate a + * dynamically registered background worker; the worker will be sent a SIGTERM + * and will not be restarted after it exits. Whenever the postmaster knows + * that a worker will not be restarted, it unregisters the worker, freeing up + * that worker's slot for use by a new worker. + * + * Note that there might be more than one worker in a database concurrently, + * and the same module may request more than one worker running the same (or + * different) code. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/bgworker.h + *-------------------------------------------------------------------- + */ +#ifndef BGWORKER_H +#define BGWORKER_H + +/*--------------------------------------------------------------------- + * External module API. + *--------------------------------------------------------------------- + */ + +/* + * Pass this flag to have your worker be able to connect to shared memory. + */ +#define BGWORKER_SHMEM_ACCESS 0x0001 + +/* + * This flag means the bgworker requires a database connection. The connection + * is not established automatically; the worker must establish it later. + * It requires that BGWORKER_SHMEM_ACCESS was passed too. + */ +#define BGWORKER_BACKEND_DATABASE_CONNECTION 0x0002 + + +typedef void (*bgworker_main_type) (Datum main_arg); + +/* + * Points in time at which a bgworker can request to be started + */ +typedef enum +{ + BgWorkerStart_PostmasterStart, + BgWorkerStart_ConsistentState, + BgWorkerStart_RecoveryFinished +} BgWorkerStartTime; + +#define BGW_DEFAULT_RESTART_INTERVAL 60 +#define BGW_NEVER_RESTART -1 +#define BGW_MAXLEN 64 + +typedef struct BackgroundWorker +{ + char bgw_name[BGW_MAXLEN]; + int bgw_flags; + BgWorkerStartTime bgw_start_time; + int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ + bgworker_main_type bgw_main; + char bgw_library_name[BGW_MAXLEN]; /* only if bgw_main is NULL */ + char bgw_function_name[BGW_MAXLEN]; /* only if bgw_main is NULL */ + Datum bgw_main_arg; + pid_t bgw_notify_pid; /* SIGUSR1 this backend on start/stop */ +} BackgroundWorker; + +typedef enum BgwHandleStatus +{ + BGWH_STARTED, /* worker is running */ + BGWH_NOT_YET_STARTED, /* worker hasn't been started yet */ + BGWH_STOPPED, /* worker has exited */ + BGWH_POSTMASTER_DIED /* postmaster died; worker status unclear */ +} BgwHandleStatus; + +struct BackgroundWorkerHandle; +typedef struct BackgroundWorkerHandle BackgroundWorkerHandle; + +/* Register a new bgworker during shared_preload_libraries */ +extern void RegisterBackgroundWorker(BackgroundWorker *worker); + +/* Register a new bgworker from a regular backend */ +extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, + BackgroundWorkerHandle **handle); + +/* Query the status of a bgworker */ +extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, + pid_t *pidp); +extern BgwHandleStatus +WaitForBackgroundWorkerStartup(BackgroundWorkerHandle * + handle, pid_t *pid); + +/* Terminate a bgworker */ +extern void TerminateBackgroundWorker(BackgroundWorkerHandle *handle); + +/* This is valid in a running worker */ +extern PGDLLIMPORT BackgroundWorker *MyBgworkerEntry; + +/* + * Connect to the specified database, as the specified user. Only a worker + * that passed BGWORKER_BACKEND_DATABASE_CONNECTION during registration may + * call this. + * + * If username is NULL, bootstrapping superuser is used. + * If dbname is NULL, connection is made to no specific database; + * only shared catalogs can be accessed. + */ +extern void BackgroundWorkerInitializeConnection(char *dbname, char *username); + +/* Block/unblock signals in a background worker process */ +extern void BackgroundWorkerBlockSignals(void); +extern void BackgroundWorkerUnblockSignals(void); + +#endif /* BGWORKER_H */ diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h new file mode 100644 index 0000000000..c2518a6c8d --- /dev/null +++ b/src/include/postmaster/bgworker_internals.h @@ -0,0 +1,55 @@ +/*-------------------------------------------------------------------- + * bgworker_internals.h + * POSTGRES pluggable background workers internals + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/include/postmaster/bgworker_internals.h + *-------------------------------------------------------------------- + */ +#ifndef BGWORKER_INTERNALS_H +#define BGWORKER_INTERNALS_H + +#include "datatype/timestamp.h" +#include "lib/ilist.h" +#include "postmaster/bgworker.h" + +/* + * List of background workers, private to postmaster. + * + * A worker that requests a database connection during registration will have + * rw_backend set, and will be present in BackendList. Note: do not rely on + * rw_backend being non-NULL for shmem-connected workers! + */ +typedef struct RegisteredBgWorker +{ + BackgroundWorker rw_worker; /* its registry entry */ + struct bkend *rw_backend; /* its BackendList entry, or NULL */ + pid_t rw_pid; /* 0 if not running */ + int rw_child_slot; + TimestampTz rw_crashed_at; /* if not 0, time it last crashed */ + int rw_shmem_slot; + bool rw_terminate; + slist_node rw_lnode; /* list link */ +} RegisteredBgWorker; + +extern slist_head BackgroundWorkerList; + +extern Size BackgroundWorkerShmemSize(void); +extern void BackgroundWorkerShmemInit(void); +extern void BackgroundWorkerStateChange(void); +extern void ForgetBackgroundWorker(slist_mutable_iter *cur); +extern void ReportBackgroundWorkerPID(RegisteredBgWorker *); +extern void BackgroundWorkerStopNotifications(pid_t pid); +extern void ResetBackgroundWorkerCrashTimes(void); + +/* Function to start a background worker, called from postmaster.c */ +extern void StartBackgroundWorker(void); + +#ifdef EXEC_BACKEND +extern BackgroundWorker *BackgroundWorkerEntry(int slotno); +#endif + +#endif /* BGWORKER_INTERNALS_H */ diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h index f46d4ad707..149ec72ebc 100644 --- a/src/include/postmaster/bgwriter.h +++ b/src/include/postmaster/bgwriter.h @@ -6,7 +6,7 @@ * The bgwriter process used to handle checkpointing duties too. Now * there is a separate process, but we did not bother to split this header. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/postmaster/bgwriter.h * @@ -25,13 +25,13 @@ extern int CheckPointTimeout; extern int CheckPointWarning; extern double CheckPointCompletionTarget; -extern void BackgroundWriterMain(void); -extern void CheckpointerMain(void); +extern void BackgroundWriterMain(void) __attribute__((noreturn)); +extern void CheckpointerMain(void) __attribute__((noreturn)); extern void RequestCheckpoint(int flags); extern void CheckpointWriteDelay(int flags, double progress); -extern bool ForwardFsyncRequest(RelFileNodeBackend rnode, ForkNumber forknum, +extern bool ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno); extern void AbsorbFsyncRequests(void); diff --git a/src/include/postmaster/fork_process.h b/src/include/postmaster/fork_process.h index e19564e567..d23f44e440 100644 --- a/src/include/postmaster/fork_process.h +++ b/src/include/postmaster/fork_process.h @@ -3,7 +3,7 @@ * fork_process.h * Exports from postmaster/fork_process.c. * - * Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/postmaster/fork_process.h * diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h index 8e4472544f..482546c185 100644 --- a/src/include/postmaster/pgarch.h +++ b/src/include/postmaster/pgarch.h @@ -3,7 +3,7 @@ * pgarch.h * Exports from postmaster/pgarch.c. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/postmaster/pgarch.h @@ -14,13 +14,26 @@ #define _PGARCH_H /* ---------- + * Archiver control info. + * + * We expect that archivable files within pg_xlog will have names between + * MIN_XFN_CHARS and MAX_XFN_CHARS in length, consisting only of characters + * appearing in VALID_XFN_CHARS. The status files in archive_status have + * corresponding names with ".ready" or ".done" appended. + * ---------- + */ +#define MIN_XFN_CHARS 16 +#define MAX_XFN_CHARS 40 +#define VALID_XFN_CHARS "0123456789ABCDEF.history.backup" + +/* ---------- * Functions called from postmaster * ---------- */ extern int pgarch_start(void); #ifdef EXEC_BACKEND -extern void PgArchiverMain(int argc, char *argv[]); +extern void PgArchiverMain(int argc, char *argv[]) __attribute__((noreturn)); #endif #endif /* _PGARCH_H */ diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 683ce3c407..de46332780 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -3,7 +3,7 @@ * postmaster.h * Exports from postmaster/postmaster.c. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/postmaster/postmaster.h @@ -19,7 +19,7 @@ extern int ReservedBackends; extern int PostPortNumber; extern int Unix_socket_permissions; extern char *Unix_socket_group; -extern char *UnixSocketDir; +extern char *Unix_socket_directories; extern char *ListenAddresses; extern bool ClientAuthInProgress; extern int PreAuthDelay; @@ -46,17 +46,29 @@ extern int postmaster_alive_fds[2]; extern const char *progname; -extern int PostmasterMain(int argc, char *argv[]); +extern void PostmasterMain(int argc, char *argv[]) __attribute__((noreturn)); extern void ClosePostmasterPorts(bool am_syslogger); extern int MaxLivePostmasterChildren(void); +extern int GetNumShmemAttachedBgworkers(void); +extern bool PostmasterMarkPIDForWorkerNotify(int); + #ifdef EXEC_BACKEND extern pid_t postmaster_forkexec(int argc, char *argv[]); -extern int SubPostmasterMain(int argc, char *argv[]); +extern void SubPostmasterMain(int argc, char *argv[]) __attribute__((noreturn)); extern Size ShmemBackendArraySize(void); extern void ShmemBackendArrayAllocation(void); #endif +/* + * Note: MAX_BACKENDS is limited to 2^23-1 because inval.c stores the + * backend ID as a 3-byte signed integer. Even if that limitation were + * removed, we still could not exceed INT_MAX/4 because some places compute + * 4*MaxBackends without any overflow check. This is rechecked in the relevant + * GUC check hooks and in RegisterBackgroundWorker(). + */ +#define MAX_BACKENDS 0x7fffff + #endif /* _POSTMASTER_H */ diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h index 3ec69502eb..9a28fcdd38 100644 --- a/src/include/postmaster/startup.h +++ b/src/include/postmaster/startup.h @@ -3,7 +3,7 @@ * startup.h * Exports from postmaster/startup.c. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/postmaster/startup.h * @@ -13,7 +13,7 @@ #define _STARTUP_H extern void HandleStartupProcInterrupts(void); -extern void StartupProcessMain(void); +extern void StartupProcessMain(void) __attribute__((noreturn)); extern void PreRestoreCommand(void); extern void PostRestoreCommand(void); extern bool IsPromoteTriggered(void); diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h index dc88207b3d..da462cd700 100644 --- a/src/include/postmaster/syslogger.h +++ b/src/include/postmaster/syslogger.h @@ -3,7 +3,7 @@ * syslogger.h * Exports from postmaster/syslogger.c. * - * Copyright (c) 2004-2012, PostgreSQL Global Development Group + * Copyright (c) 2004-2014, PostgreSQL Global Development Group * * src/include/postmaster/syslogger.h * @@ -20,7 +20,7 @@ * here is to divide long messages into chunks that are not more than * PIPE_BUF bytes long, which according to POSIX spec must be written into * the pipe atomically. The pipe reader then uses the protocol headers to - * reassemble the parts of a message into a single string. The reader can + * reassemble the parts of a message into a single string. The reader can * also cope with non-protocol data coming down the pipe, though we cannot * guarantee long strings won't get split apart. * @@ -84,7 +84,7 @@ extern int SysLogger_Start(void); extern void write_syslogger_file(const char *buffer, int count, int dest); #ifdef EXEC_BACKEND -extern void SysLoggerMain(int argc, char *argv[]); +extern void SysLoggerMain(int argc, char *argv[]) __attribute__((noreturn)); #endif #endif /* _SYSLOGGER_H */ diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h index 41c539a359..d21e44ce66 100644 --- a/src/include/postmaster/walwriter.h +++ b/src/include/postmaster/walwriter.h @@ -3,7 +3,7 @@ * walwriter.h * Exports from postmaster/walwriter.c. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/postmaster/walwriter.h * @@ -15,6 +15,6 @@ /* GUC options */ extern int WalWriterDelay; -extern void WalWriterMain(void); +extern void WalWriterMain(void) __attribute__((noreturn)); #endif /* _WALWRITER_H */ diff --git a/src/include/regex/regcustom.h b/src/include/regex/regcustom.h index 04849f291f..dbb461a0ce 100644 --- a/src/include/regex/regcustom.h +++ b/src/include/regex/regcustom.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * * Development of this software was funded, in part, by Cray Research Inc., * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics diff --git a/src/include/regex/regerrs.h b/src/include/regex/regerrs.h index a761371e5d..809b511266 100644 --- a/src/include/regex/regerrs.h +++ b/src/include/regex/regerrs.h @@ -77,3 +77,11 @@ { REG_ETOOBIG, "REG_ETOOBIG", "nfa has too many states" }, + +{ + REG_ECOLORS, "REG_ECOLORS", "too many colors" +}, + +{ + REG_CANCEL, "REG_CANCEL", "operation cancelled" +}, diff --git a/src/include/regex/regex.h b/src/include/regex/regex.h index cec4b837cd..3020b0ff0f 100644 --- a/src/include/regex/regex.h +++ b/src/include/regex/regex.h @@ -3,7 +3,7 @@ /* * regular expressions * - * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * * Development of this software was funded, in part, by Cray Research Inc., * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics @@ -153,9 +153,14 @@ typedef struct #define REG_MIXED 17 /* character widths of regex and string differ */ #define REG_BADOPT 18 /* invalid embedded option */ #define REG_ETOOBIG 19 /* nfa has too many states */ +#define REG_ECOLORS 20 /* too many colors */ +#define REG_CANCEL 21 /* operation cancelled */ /* two specials for debugging and testing */ #define REG_ATOI 101 /* convert error-code name to number */ #define REG_ITOA 102 /* convert error-code number to name */ +/* non-error result codes for pg_regprefix */ +#define REG_PREFIX (-1) /* identified a common prefix */ +#define REG_EXACT (-2) /* identified an exact match */ @@ -164,6 +169,7 @@ typedef struct */ extern int pg_regcomp(regex_t *, const pg_wchar *, size_t, int, Oid); extern int pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *, size_t, regmatch_t[], int); +extern int pg_regprefix(regex_t *, pg_wchar **, size_t *); extern void pg_regfree(regex_t *); extern size_t pg_regerror(int, const regex_t *, char *, size_t); extern void pg_set_regex_collation(Oid collation); diff --git a/src/include/regex/regexport.h b/src/include/regex/regexport.h new file mode 100644 index 0000000000..90a27c5442 --- /dev/null +++ b/src/include/regex/regexport.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + * + * regexport.h + * Declarations for exporting info about a regex's NFA (nondeterministic + * finite automaton) + * + * The functions declared here provide accessors to extract the NFA state + * graph and color character sets of a successfully-compiled regex. + * + * An NFA contains one or more states, numbered 0..N-1. There is an initial + * state, as well as a final state --- reaching the final state denotes + * successful matching of an input string. Each state except the final one + * has some out-arcs that lead to successor states, each arc being labeled + * with a color that represents one or more concrete character codes. + * (The colors of a state's out-arcs need not be distinct, since this is an + * NFA not a DFA.) There are also "pseudocolors" representing start/end of + * line and start/end of string. Colors are numbered 0..C-1, but note that + * color 0 is "white" (all unused characters) and can generally be ignored. + * + * Portions Copyright (c) 2013-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1998, 1999 Henry Spencer + * + * IDENTIFICATION + * src/include/regex/regexport.h + * + *------------------------------------------------------------------------- + */ +#ifndef _REGEXPORT_H_ +#define _REGEXPORT_H_ + +#include "regex/regex.h" + +/* information about one arc of a regex's NFA */ +typedef struct +{ + int co; /* label (character-set color) of arc */ + int to; /* next state number */ +} regex_arc_t; + + +/* Functions for gathering information about NFA states and arcs */ +extern int pg_reg_getnumstates(const regex_t *regex); +extern int pg_reg_getinitialstate(const regex_t *regex); +extern int pg_reg_getfinalstate(const regex_t *regex); +extern int pg_reg_getnumoutarcs(const regex_t *regex, int st); +extern void pg_reg_getoutarcs(const regex_t *regex, int st, + regex_arc_t *arcs, int arcs_len); + +/* Functions for gathering information about colors */ +extern int pg_reg_getnumcolors(const regex_t *regex); +extern int pg_reg_colorisbegin(const regex_t *regex, int co); +extern int pg_reg_colorisend(const regex_t *regex, int co); +extern int pg_reg_getnumcharacters(const regex_t *regex, int co); +extern void pg_reg_getcharacters(const regex_t *regex, int co, + pg_wchar *chars, int chars_len); + +#endif /* _REGEXPORT_H_ */ diff --git a/src/include/regex/regguts.h b/src/include/regex/regguts.h index e8415799ec..7d5d85577d 100644 --- a/src/include/regex/regguts.h +++ b/src/include/regex/regguts.h @@ -1,7 +1,7 @@ /* * Internal interface definitions, etc., for the reg package * - * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. + * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved. * * Development of this software was funded, in part, by Cray Research Inc., * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics @@ -126,8 +126,8 @@ /* - * We dissect a chr into byts for colormap table indexing. Here we define - * a byt, which will be the same as a byte on most machines... The exact + * We dissect a chr into byts for colormap table indexing. Here we define + * a byt, which will be the same as a byte on most machines... The exact * size of a byt is not critical, but about 8 bits is good, and extraction * of 8-bit chunks is sometimes especially fast. */ @@ -148,6 +148,7 @@ typedef short color; /* colors of characters */ typedef int pcolor; /* what color promotes to */ +#define MAX_COLOR 32767 /* max color (must fit in 'color' datatype) */ #define COLORLESS (-1) /* impossible color */ #define WHITE 0 /* default color, parent of all others */ @@ -155,9 +156,9 @@ typedef int pcolor; /* what color promotes to */ /* * A colormap is a tree -- more precisely, a DAG -- indexed at each level - * by a byt of the chr, to map the chr to a color efficiently. Because + * by a byt of the chr, to map the chr to a color efficiently. Because * lower sections of the tree can be shared, it can exploit the usual - * sparseness of such a mapping table. The tree is always NBYTS levels + * sparseness of such a mapping table. The tree is always NBYTS levels * deep (in the past it was shallower during construction but was "filled" * to full depth at the end of that); areas that are unaltered as yet point * to "fill blocks" which are entirely WHITE in color. @@ -186,12 +187,12 @@ union tree * * If "sub" is not NOSUB then it is the number of the color's current * subcolor, i.e. we are in process of dividing this color (character - * equivalence class) into two colors. See src/backend/regex/README for + * equivalence class) into two colors. See src/backend/regex/README for * discussion of subcolors. * * Currently-unused colors have the FREECOL bit set and are linked into a * freelist using their "sub" fields, but only if their color numbers are - * less than colormap.max. Any array entries beyond "max" are just garbage. + * less than colormap.max. Any array entries beyond "max" are just garbage. */ struct colordesc { @@ -199,19 +200,21 @@ struct colordesc color sub; /* open subcolor, if any; or free-chain ptr */ #define NOSUB COLORLESS /* value of "sub" when no open subcolor */ struct arc *arcs; /* chain of all arcs of this color */ + chr firstchr; /* char first assigned to this color */ int flags; /* bit values defined next */ #define FREECOL 01 /* currently free */ #define PSEUDO 02 /* pseudocolor, no real chars */ -#define UNUSEDCOLOR(cd) ((cd)->flags&FREECOL) +#define UNUSEDCOLOR(cd) ((cd)->flags & FREECOL) union tree *block; /* block of solid color, if any */ }; /* * The color map itself * - * Only the "tree" part is used at execution time, and that only via the - * GETCOLOR() macro. Possibly that should be separated from the compile-time - * data. + * Much of the data in the colormap struct is only used at compile time. + * However, the bulk of the space usage is in the "tree" structure, so it's + * not clear that there's much point in converting the rest to a more compact + * form when compilation is finished. */ struct colormap { @@ -279,15 +282,14 @@ struct state; struct arc { - int type; -#define ARCFREE '\0' + int type; /* 0 if free, else an NFA arc type code */ color co; struct state *from; /* where it's from (and contained within) */ struct state *to; /* where it's to */ - struct arc *outchain; /* *from's outs chain or free chain */ + struct arc *outchain; /* link in *from's outs chain or free chain */ #define freechain outchain - struct arc *inchain; /* *to's ins chain */ - struct arc *colorchain; /* color's arc chain */ + struct arc *inchain; /* link in *to's ins chain */ + struct arc *colorchain; /* link in color's arc chain */ struct arc *colorchainRev; /* back-link in color's arc chain */ }; @@ -329,8 +331,8 @@ struct nfa color bos[2]; /* colors, if any, assigned to BOS and BOL */ color eos[2]; /* colors, if any, assigned to EOS and EOL */ size_t size; /* Current NFA size; differs from nstates as - * it also counts the number of states created - * by children of this state. */ + * it also counts the number of states in + * children of this NFA. */ struct vars *v; /* simplifies compile error reporting */ struct nfa *parent; /* parent NFA, if any */ }; @@ -339,24 +341,38 @@ struct nfa /* * definitions for compacted NFA + * + * The main space savings in a compacted NFA is from making the arcs as small + * as possible. We store only the transition color and next-state number for + * each arc. The list of out arcs for each state is an array beginning at + * cnfa.states[statenumber], and terminated by a dummy carc struct with + * co == COLORLESS. + * + * The non-dummy carc structs are of two types: plain arcs and LACON arcs. + * Plain arcs just store the transition color number as "co". LACON arcs + * store the lookahead constraint number plus cnfa.ncolors as "co". LACON + * arcs can be distinguished from plain by testing for co >= cnfa.ncolors. */ struct carc { color co; /* COLORLESS is list terminator */ - int to; /* state number */ + int to; /* next-state number */ }; struct cnfa { int nstates; /* number of states */ - int ncolors; /* number of colors */ + int ncolors; /* number of colors (max color in use + 1) */ int flags; -#define HASLACONS 01 /* uses lookahead constraints */ +#define HASLACONS 01 /* uses lookahead constraints */ int pre; /* setup state number */ int post; /* teardown state number */ color bos[2]; /* colors, if any, assigned to BOS and BOL */ color eos[2]; /* colors, if any, assigned to EOS and EOL */ + char *stflags; /* vector of per-state flags bytes */ +#define CNFA_NOPROGRESS 01 /* flag bit for a no-progress state */ struct carc **states; /* vector of pointers to outarc lists */ + /* states[n] are pointers into a single malloc'd array of arcs */ struct carc *arcs; /* the area for the lists */ }; @@ -430,8 +446,11 @@ struct subre struct fns { void FUNCPTR(free, (regex_t *)); + int FUNCPTR(cancel_requested, (void)); }; +#define CANCEL_REQUESTED(re) \ + ((*((struct fns *) (re)->re_fns)->cancel_requested) ()) /* diff --git a/src/include/replication/basebackup.h b/src/include/replication/basebackup.h index 89df592efb..988bce7f8b 100644 --- a/src/include/replication/basebackup.h +++ b/src/include/replication/basebackup.h @@ -3,7 +3,7 @@ * basebackup.h * Exports from replication/basebackup.c. * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2014, PostgreSQL Global Development Group * * src/include/replication/basebackup.h * @@ -14,6 +14,13 @@ #include "nodes/replnodes.h" +/* + * Minimum and maximum values of MAX_RATE option in BASE_BACKUP command. + */ +#define MAX_RATE_LOWER 32 +#define MAX_RATE_UPPER 1048576 + + extern void SendBaseBackup(BaseBackupCmd *cmd); #endif /* _BASEBACKUP_H */ diff --git a/src/include/replication/decode.h b/src/include/replication/decode.h new file mode 100644 index 0000000000..d9e30776af --- /dev/null +++ b/src/include/replication/decode.h @@ -0,0 +1,19 @@ +/*------------------------------------------------------------------------- + * decode.h + * PostgreSQL WAL to logical transformation + * + * Portions Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef DECODE_H +#define DECODE_H + +#include "access/xlogreader.h" +#include "replication/reorderbuffer.h" +#include "replication/logical.h" + +void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, + XLogRecord *record); + +#endif diff --git a/src/include/replication/logical.h b/src/include/replication/logical.h new file mode 100644 index 0000000000..26be127bf7 --- /dev/null +++ b/src/include/replication/logical.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------- + * logical.h + * PostgreSQL logical decoding coordination + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICAL_H +#define LOGICAL_H + +#include "replication/slot.h" + +#include "access/xlog.h" +#include "access/xlogreader.h" +#include "replication/output_plugin.h" + +struct LogicalDecodingContext; + +typedef void (*LogicalOutputPluginWriterWrite) ( + struct LogicalDecodingContext *lr, + XLogRecPtr Ptr, + TransactionId xid, + bool last_write +); + +typedef LogicalOutputPluginWriterWrite LogicalOutputPluginWriterPrepareWrite; + +typedef struct LogicalDecodingContext +{ + /* memory context this is all allocated in */ + MemoryContext context; + + /* infrastructure pieces */ + XLogReaderState *reader; + ReplicationSlot *slot; + struct ReorderBuffer *reorder; + struct SnapBuild *snapshot_builder; + + OutputPluginCallbacks callbacks; + OutputPluginOptions options; + + /* + * User specified options + */ + List *output_plugin_options; + + /* + * User-Provided callback for writing/streaming out data. + */ + LogicalOutputPluginWriterPrepareWrite prepare_write; + LogicalOutputPluginWriterWrite write; + + /* + * Output buffer. + */ + StringInfo out; + + /* + * Private data pointer of the output plugin. + */ + void *output_plugin_private; + + /* + * Private data pointer for the data writer. + */ + void *output_writer_private; + + /* + * State for writing output. + */ + bool accept_writes; + bool prepared_write; + XLogRecPtr write_location; + TransactionId write_xid; +} LogicalDecodingContext; + +extern void CheckLogicalDecodingRequirements(void); + +extern LogicalDecodingContext *CreateInitDecodingContext(char *plugin, + List *output_plugin_options, + XLogPageReadCB read_page, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write); +extern LogicalDecodingContext *CreateDecodingContext( + XLogRecPtr start_lsn, + List *output_plugin_options, + XLogPageReadCB read_page, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write); +extern void DecodingContextFindStartpoint(LogicalDecodingContext *ctx); +extern bool DecodingContextReady(LogicalDecodingContext *ctx); +extern void FreeDecodingContext(LogicalDecodingContext *ctx); + +extern void LogicalIncreaseXminForSlot(XLogRecPtr lsn, TransactionId xmin); +extern void LogicalIncreaseRestartDecodingForSlot(XLogRecPtr current_lsn, + XLogRecPtr restart_lsn); +extern void LogicalConfirmReceivedLocation(XLogRecPtr lsn); + +#endif diff --git a/src/include/replication/logicalfuncs.h b/src/include/replication/logicalfuncs.h new file mode 100644 index 0000000000..21bf44ec4b --- /dev/null +++ b/src/include/replication/logicalfuncs.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * logicalfuncs.h + * PostgreSQL WAL to logical transformation support functions + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef LOGICALFUNCS_H +#define LOGICALFUNCS_H + +#include "replication/logical.h" + +extern int logical_read_local_xlog_page(XLogReaderState *state, + XLogRecPtr targetPagePtr, + int reqLen, XLogRecPtr targetRecPtr, + char *cur_page, TimeLineID *pageTLI); + +extern Datum pg_logical_slot_get_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_get_binary_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_peek_changes(PG_FUNCTION_ARGS); +extern Datum pg_logical_slot_peek_binary_changes(PG_FUNCTION_ARGS); + +#endif diff --git a/src/include/replication/output_plugin.h b/src/include/replication/output_plugin.h new file mode 100644 index 0000000000..a58e68d30a --- /dev/null +++ b/src/include/replication/output_plugin.h @@ -0,0 +1,98 @@ +/*------------------------------------------------------------------------- + * output_plugin.h + * PostgreSQL Logical Decode Plugin Interface + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef OUTPUT_PLUGIN_H +#define OUTPUT_PLUGIN_H + +#include "replication/reorderbuffer.h" + +struct LogicalDecodingContext; +struct OutputPluginCallbacks; + +typedef enum OutputPluginOutputType +{ + OUTPUT_PLUGIN_BINARY_OUTPUT, + OUTPUT_PLUGIN_TEXTUAL_OUTPUT +} OutputPluginOutputType; + +/* + * Options set by the output plugin, in the startup callback. + */ +typedef struct OutputPluginOptions +{ + OutputPluginOutputType output_type; +} OutputPluginOptions; + +/* + * Type of the shared library symbol _PG_output_plugin_init that is looked up + * when loading an output plugin shared library. + */ +typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb); + +/* + * Callback that gets called in a user-defined plugin. ctx->private_data can + * be set to some private data. + * + * "is_init" will be set to "true" if the decoding slot just got defined. When + * the same slot is used from there one, it will be "false". + */ +typedef void (*LogicalDecodeStartupCB) ( + struct LogicalDecodingContext *ctx, + OutputPluginOptions *options, + bool is_init +); + +/* + * Callback called for every (explicit or implicit) BEGIN of a successful + * transaction. + */ +typedef void (*LogicalDecodeBeginCB) ( + struct LogicalDecodingContext *, + ReorderBufferTXN *txn); + +/* + * Callback for every individual change in a successful transaction. + */ +typedef void (*LogicalDecodeChangeCB) ( + struct LogicalDecodingContext *, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change +); + +/* + * Called for every (explicit or implicit) COMMIT of a successful transaction. + */ +typedef void (*LogicalDecodeCommitCB) ( + struct LogicalDecodingContext *, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +/* + * Called to shutdown an output plugin. + */ +typedef void (*LogicalDecodeShutdownCB) ( + struct LogicalDecodingContext * +); + +/* + * Output plugin callbacks + */ +typedef struct OutputPluginCallbacks +{ + LogicalDecodeStartupCB startup_cb; + LogicalDecodeBeginCB begin_cb; + LogicalDecodeChangeCB change_cb; + LogicalDecodeCommitCB commit_cb; + LogicalDecodeShutdownCB shutdown_cb; +} OutputPluginCallbacks; + +void OutputPluginPrepareWrite(struct LogicalDecodingContext *ctx, bool last_write); +void OutputPluginWrite(struct LogicalDecodingContext *ctx, bool last_write); + +#endif /* OUTPUT_PLUGIN_H */ diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h new file mode 100644 index 0000000000..eaea5884ef --- /dev/null +++ b/src/include/replication/reorderbuffer.h @@ -0,0 +1,362 @@ +/* + * reorderbuffer.h + * PostgreSQL logical replay/reorder buffer management. + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + * src/include/replication/reorderbuffer.h + */ +#ifndef REORDERBUFFER_H +#define REORDERBUFFER_H + +#include "access/htup_details.h" + +#include "lib/ilist.h" + +#include "storage/sinval.h" + +#include "utils/hsearch.h" +#include "utils/rel.h" +#include "utils/snapshot.h" +#include "utils/timestamp.h" + +/* an individual tuple, stored in one chunk of memory */ +typedef struct ReorderBufferTupleBuf +{ + /* position in preallocated list */ + slist_node node; + + /* tuple, stored sequentially */ + HeapTupleData tuple; + HeapTupleHeaderData header; + char data[MaxHeapTupleSize]; +} ReorderBufferTupleBuf; + +/* + * Types of the change passed to a 'change' callback. + * + * For efficiency and simplicity reasons we want to keep Snapshots, CommandIds + * and ComboCids in the same list with the user visible INSERT/UPDATE/DELETE + * changes. Users of the decoding facilities will never see changes with + * *_INTERNAL_* actions. + */ +enum ReorderBufferChangeType +{ + REORDER_BUFFER_CHANGE_INSERT, + REORDER_BUFFER_CHANGE_UPDATE, + REORDER_BUFFER_CHANGE_DELETE, + REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT, + REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID, + REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID +}; + +/* + * a single 'change', can be an insert (with one tuple), an update (old, new), + * or a delete (old). + * + * The same struct is also used internally for other purposes but that should + * never be visible outside reorderbuffer.c. + */ +typedef struct ReorderBufferChange +{ + XLogRecPtr lsn; + + /* The type of change. */ + enum ReorderBufferChangeType action; + + /* + * Context data for the change, which part of the union is valid depends + * on action/action_internal. + */ + union + { + /* Old, new tuples when action == *_INSERT|UPDATE|DELETE */ + struct + { + /* relation that has been changed */ + RelFileNode relnode; + /* valid for DELETE || UPDATE */ + ReorderBufferTupleBuf *oldtuple; + /* valid for INSERT || UPDATE */ + ReorderBufferTupleBuf *newtuple; + } tp; + + /* New snapshot, set when action == *_INTERNAL_SNAPSHOT */ + Snapshot snapshot; + + /* + * New command id for existing snapshot in a catalog changing tx. Set + * when action == *_INTERNAL_COMMAND_ID. + */ + CommandId command_id; + + /* + * New cid mapping for catalog changing transaction, set when action + * == *_INTERNAL_TUPLECID. + */ + struct + { + RelFileNode node; + ItemPointerData tid; + CommandId cmin; + CommandId cmax; + CommandId combocid; + } tuplecid; + } data; + + /* + * While in use this is how a change is linked into a transactions, + * otherwise it's the preallocated list. + */ + dlist_node node; +} ReorderBufferChange; + +typedef struct ReorderBufferTXN +{ + /* + * The transactions transaction id, can be a toplevel or sub xid. + */ + TransactionId xid; + + /* did the TX have catalog changes */ + bool has_catalog_changes; + + /* + * Do we know this is a subxact? + */ + bool is_known_as_subxact; + + /* + * LSN of the first data carrying, WAL record with knowledge about this + * xid. This is allowed to *not* be first record adorned with this xid, if + * the previous records aren't relevant for logical decoding. + */ + XLogRecPtr first_lsn; + + /* ---- + * LSN of the record that lead to this xact to be committed or + * aborted. This can be a + * * plain commit record + * * plain commit record, of a parent transaction + * * prepared transaction commit + * * plain abort record + * * prepared transaction abort + * * error during decoding + * ---- + */ + XLogRecPtr final_lsn; + + /* + * LSN pointing to the end of the commit record + 1. + */ + XLogRecPtr end_lsn; + + /* + * LSN of the last lsn at which snapshot information reside, so we can + * restart decoding from there and fully recover this transaction from + * WAL. + */ + XLogRecPtr restart_decoding_lsn; + + /* + * Commit time, only known when we read the actual commit record. + */ + TimestampTz commit_time; + + /* + * Base snapshot or NULL. + */ + Snapshot base_snapshot; + XLogRecPtr base_snapshot_lsn; + + /* + * How many ReorderBufferChange's do we have in this txn. + * + * Changes in subtransactions are *not* included but tracked separately. + */ + uint64 nentries; + + /* + * How many of the above entries are stored in memory in contrast to being + * spilled to disk. + */ + uint64 nentries_mem; + + /* + * List of ReorderBufferChange structs, including new Snapshots and new + * CommandIds + */ + dlist_head changes; + + /* + * List of (relation, ctid) => (cmin, cmax) mappings for catalog tuples. + * Those are always assigned to the toplevel transaction. (Keep track of + * #entries to create a hash of the right size) + */ + dlist_head tuplecids; + uint64 ntuplecids; + + /* + * On-demand built hash for looking up the above values. + */ + HTAB *tuplecid_hash; + + /* + * Hash containing (potentially partial) toast entries. NULL if no toast + * tuples have been found for the current change. + */ + HTAB *toast_hash; + + /* + * non-hierarchical list of subtransactions that are *not* aborted. Only + * used in toplevel transactions. + */ + dlist_head subtxns; + uint32 nsubtxns; + + /* + * Stored cache invalidations. This is not a linked list because we get + * all the invalidations at once. + */ + uint32 ninvalidations; + SharedInvalidationMessage *invalidations; + + /* --- + * Position in one of three lists: + * * list of subtransactions if we are *known* to be subxact + * * list of toplevel xacts (can be a as-yet unknown subxact) + * * list of preallocated ReorderBufferTXNs + * --- + */ + dlist_node node; + +} ReorderBufferTXN; + +/* so we can define the callbacks used inside struct ReorderBuffer itself */ +typedef struct ReorderBuffer ReorderBuffer; + +/* change callback signature */ +typedef void (*ReorderBufferApplyChangeCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + +/* begin callback signature */ +typedef void (*ReorderBufferBeginCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn); + +/* commit callback signature */ +typedef void (*ReorderBufferCommitCB) ( + ReorderBuffer *rb, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + +struct ReorderBuffer +{ + /* + * xid => ReorderBufferTXN lookup table + */ + HTAB *by_txn; + + /* + * Transactions that could be a toplevel xact, ordered by LSN of the first + * record bearing that xid.. + */ + dlist_head toplevel_by_lsn; + + /* + * one-entry sized cache for by_txn. Very frequently the same txn gets + * looked up over and over again. + */ + TransactionId by_txn_last_xid; + ReorderBufferTXN *by_txn_last_txn; + + /* + * Callacks to be called when a transactions commits. + */ + ReorderBufferBeginCB begin; + ReorderBufferApplyChangeCB apply_change; + ReorderBufferCommitCB commit; + + /* + * Pointer that will be passed untouched to the callbacks. + */ + void *private_data; + + /* + * Private memory context. + */ + MemoryContext context; + + /* + * Data structure slab cache. + * + * We allocate/deallocate some structures very frequently, to avoid bigger + * overhead we cache some unused ones here. + * + * The maximum number of cached entries is controlled by const variables + * ontop of reorderbuffer.c + */ + + /* cached ReorderBufferTXNs */ + dlist_head cached_transactions; + Size nr_cached_transactions; + + /* cached ReorderBufferChanges */ + dlist_head cached_changes; + Size nr_cached_changes; + + /* cached ReorderBufferTupleBufs */ + slist_head cached_tuplebufs; + Size nr_cached_tuplebufs; + + XLogRecPtr current_restart_decoding_lsn; + + /* buffer for disk<->memory conversions */ + char *outbuf; + Size outbufsize; +}; + + +ReorderBuffer *ReorderBufferAllocate(void); +void ReorderBufferFree(ReorderBuffer *); + +ReorderBufferTupleBuf *ReorderBufferGetTupleBuf(ReorderBuffer *); +void ReorderBufferReturnTupleBuf(ReorderBuffer *, ReorderBufferTupleBuf *tuple); +ReorderBufferChange *ReorderBufferGetChange(ReorderBuffer *); +void ReorderBufferReturnChange(ReorderBuffer *, ReorderBufferChange *); + +void ReorderBufferQueueChange(ReorderBuffer *, TransactionId, XLogRecPtr lsn, ReorderBufferChange *); +void ReorderBufferCommit(ReorderBuffer *, TransactionId, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + TimestampTz commit_time); +void ReorderBufferAssignChild(ReorderBuffer *, TransactionId, TransactionId, XLogRecPtr commit_lsn); +void ReorderBufferCommitChild(ReorderBuffer *, TransactionId, TransactionId, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn); +void ReorderBufferAbort(ReorderBuffer *, TransactionId, XLogRecPtr lsn); +void ReorderBufferAbortOld(ReorderBuffer *, TransactionId xid); +void ReorderBufferForget(ReorderBuffer *, TransactionId, XLogRecPtr lsn); + +void ReorderBufferSetBaseSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap); +void ReorderBufferAddSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap); +void ReorderBufferAddNewCommandId(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + CommandId cid); +void ReorderBufferAddNewTupleCids(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + RelFileNode node, ItemPointerData pt, + CommandId cmin, CommandId cmax, CommandId combocid); +void ReorderBufferAddInvalidations(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + Size nmsgs, SharedInvalidationMessage *msgs); +bool ReorderBufferIsXidKnown(ReorderBuffer *, TransactionId xid); +void ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn); +bool ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid); +bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid); + +ReorderBufferTXN *ReorderBufferGetOldestTXN(ReorderBuffer *); + +void ReorderBufferSetRestartPoint(ReorderBuffer *, XLogRecPtr ptr); + +void StartupReorderBuffer(void); + +#endif diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h new file mode 100644 index 0000000000..341e829bbb --- /dev/null +++ b/src/include/replication/slot.h @@ -0,0 +1,178 @@ +/*------------------------------------------------------------------------- + * slot.h + * Replication slot management. + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef SLOT_H +#define SLOT_H + +#include "fmgr.h" +#include "access/xlog.h" +#include "access/xlogreader.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" +#include "storage/spin.h" + +/* + * Behaviour of replication slots, upon release or crash. + * + * Slots marked as PERSISTENT are crashsafe and will not be dropped when + * released. Slots marked as EPHEMERAL will be dropped when released or after + * restarts. + * + * EPHEMERAL slots can be made PERSISTENT by calling ReplicationSlotPersist(). + */ +typedef enum ReplicationSlotPersistency +{ + RS_PERSISTENT, + RS_EPHEMERAL +} ReplicationSlotPersistency; + +/* + * On-Disk data of a replication slot, preserved across restarts. + */ +typedef struct ReplicationSlotPersistentData +{ + /* The slot's identifier */ + NameData name; + + /* database the slot is active on */ + Oid database; + + /* + * The slot's behaviour when being dropped (or restored after a crash). + */ + ReplicationSlotPersistency persistency; + + /* + * xmin horizon for data + * + * NB: This may represent a value that hasn't been written to disk yet; + * see notes for effective_xmin, below. + */ + TransactionId xmin; + + /* + * xmin horizon for catalog tuples + * + * NB: This may represent a value that hasn't been written to disk yet; + * see notes for effective_xmin, below. + */ + TransactionId catalog_xmin; + + /* oldest LSN that might be required by this replication slot */ + XLogRecPtr restart_lsn; + + /* oldest LSN that the client has acked receipt for */ + XLogRecPtr confirmed_flush; + + /* plugin name */ + NameData plugin; +} ReplicationSlotPersistentData; + +/* + * Shared memory state of a single replication slot. + */ +typedef struct ReplicationSlot +{ + /* lock, on same cacheline as effective_xmin */ + slock_t mutex; + + /* is this slot defined */ + bool in_use; + + /* is somebody streaming out changes for this slot */ + bool active; + + /* any outstanding modifications? */ + bool just_dirtied; + bool dirty; + + /* + * For logical decoding, it's extremely important that we never remove any + * data that's still needed for decoding purposes, even after a crash; + * otherwise, decoding will produce wrong answers. Ordinary streaming + * replication also needs to prevent old row versions from being removed + * too soon, but the worst consequence we might encounter there is + * unwanted query cancellations on the standby. Thus, for logical + * decoding, this value represents the latest xmin that has actually been + * written to disk, whereas for streaming replication, it's just the same + * as the persistent value (data.xmin). + */ + TransactionId effective_xmin; + TransactionId effective_catalog_xmin; + + /* data surviving shutdowns and crashes */ + ReplicationSlotPersistentData data; + + /* is somebody performing io on this slot? */ + LWLock *io_in_progress_lock; + + /* all the remaining data is only used for logical slots */ + + /* ---- + * When the client has confirmed flushes >= candidate_xmin_lsn we can + * advance the catalog xmin, when restart_valid has been passed, + * restart_lsn can be increased. + * ---- + */ + TransactionId candidate_catalog_xmin; + XLogRecPtr candidate_xmin_lsn; + XLogRecPtr candidate_restart_valid; + XLogRecPtr candidate_restart_lsn; +} ReplicationSlot; + +/* + * Shared memory control area for all of replication slots. + */ +typedef struct ReplicationSlotCtlData +{ + ReplicationSlot replication_slots[1]; +} ReplicationSlotCtlData; + +/* + * Pointers to shared memory + */ +extern ReplicationSlotCtlData *ReplicationSlotCtl; +extern ReplicationSlot *MyReplicationSlot; + +/* GUCs */ +extern PGDLLIMPORT int max_replication_slots; + +/* shmem initialization functions */ +extern Size ReplicationSlotsShmemSize(void); +extern void ReplicationSlotsShmemInit(void); + +/* management of individual slots */ +extern void ReplicationSlotCreate(const char *name, bool db_specific, + ReplicationSlotPersistency p); +extern void ReplicationSlotPersist(void); +extern void ReplicationSlotDrop(const char *name); + +extern void ReplicationSlotAcquire(const char *name); +extern void ReplicationSlotRelease(void); +extern void ReplicationSlotSave(void); +extern void ReplicationSlotMarkDirty(void); + +/* misc stuff */ +extern bool ReplicationSlotValidateName(const char *name, int elevel); +extern void ReplicationSlotsComputeRequiredXmin(bool already_locked); +extern void ReplicationSlotsComputeRequiredLSN(void); +extern XLogRecPtr ReplicationSlotsComputeLogicalRestartLSN(void); +extern bool ReplicationSlotsCountDBSlots(Oid dboid, int *nslots, int *nactive); + +extern void StartupReplicationSlots(XLogRecPtr checkPointRedo); +extern void CheckPointReplicationSlots(void); + +extern void CheckSlotRequirements(void); + +/* SQL callable functions */ +extern Datum pg_create_physical_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_create_logical_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_drop_replication_slot(PG_FUNCTION_ARGS); +extern Datum pg_get_replication_slots(PG_FUNCTION_ARGS); + +#endif /* SLOT_H */ diff --git a/src/include/replication/snapbuild.h b/src/include/replication/snapbuild.h new file mode 100644 index 0000000000..e5d61ff3c4 --- /dev/null +++ b/src/include/replication/snapbuild.h @@ -0,0 +1,83 @@ +/*------------------------------------------------------------------------- + * + * snapbuild.h + * Exports from replication/logical/snapbuild.c. + * + * Copyright (c) 2012-2014, PostgreSQL Global Development Group + * + * src/include/replication/snapbuild.h + * + *------------------------------------------------------------------------- + */ +#ifndef SNAPBUILD_H +#define SNAPBUILD_H + +#include "access/xlogdefs.h" +#include "utils/snapmgr.h" + +typedef enum +{ + /* + * Initial state, we can't do much yet. + */ + SNAPBUILD_START, + + /* + * We have collected enough information to decode tuples in transactions + * that started after this. + * + * Once we reached this we start to collect changes. We cannot apply them + * yet because the might be based on transactions that were still running + * when we reached them yet. + */ + SNAPBUILD_FULL_SNAPSHOT, + + /* + * Found a point after hitting built_full_snapshot where all transactions + * that were running at that point finished. Till we reach that we hold + * off calling any commit callbacks. + */ + SNAPBUILD_CONSISTENT +} SnapBuildState; + +/* forward declare so we don't have to expose the struct to the public */ +struct SnapBuild; +typedef struct SnapBuild SnapBuild; + +/* forward declare so we don't have to include reorderbuffer.h */ +struct ReorderBuffer; + +/* forward declare so we don't have to include heapam_xlog.h */ +struct xl_heap_new_cid; +struct xl_running_xacts; + +extern void CheckPointSnapBuild(void); + +extern SnapBuild *AllocateSnapshotBuilder(struct ReorderBuffer *cache, + TransactionId xmin_horizon, XLogRecPtr start_lsn); +extern void FreeSnapshotBuilder(SnapBuild *cache); + +extern void SnapBuildSnapDecRefcount(Snapshot snap); + +extern const char *SnapBuildExportSnapshot(SnapBuild *snapstate); +extern void SnapBuildClearExportedSnapshot(void); + +extern SnapBuildState SnapBuildCurrentState(SnapBuild *snapstate); + +extern bool SnapBuildXactNeedsSkip(SnapBuild *snapstate, XLogRecPtr ptr); + +extern void SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, + TransactionId xid, int nsubxacts, + TransactionId *subxacts); +extern void SnapBuildAbortTxn(SnapBuild *builder, XLogRecPtr lsn, + TransactionId xid, int nsubxacts, + TransactionId *subxacts); +extern bool SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, + XLogRecPtr lsn); +extern void SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid, + XLogRecPtr lsn, struct xl_heap_new_cid *cid); +extern void SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, + struct xl_running_xacts *running); +extern void SnapBuildSerializationPoint(SnapBuild *builder, XLogRecPtr lsn); + +#endif /* SNAPBUILD_H */ diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h index 74820cbbb4..7eeaf3b04c 100644 --- a/src/include/replication/syncrep.h +++ b/src/include/replication/syncrep.h @@ -3,7 +3,7 @@ * syncrep.h * Exports from replication/syncrep.c. * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2014, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/replication/syncrep.h @@ -13,6 +13,7 @@ #ifndef _SYNCREP_H #define _SYNCREP_H +#include "access/xlogdefs.h" #include "utils/guc.h" #define SyncRepRequested() \ @@ -43,7 +44,7 @@ extern void SyncRepCleanupAtProcExit(void); extern void SyncRepInitConfig(void); extern void SyncRepReleaseWaiters(void); -/* called by wal writer */ +/* called by checkpointer */ extern void SyncRepUpdateSyncStandbysDefined(void); /* called by various procs */ diff --git a/src/include/replication/walprotocol.h b/src/include/replication/walprotocol.h deleted file mode 100644 index 0305fb7e59..0000000000 --- a/src/include/replication/walprotocol.h +++ /dev/null @@ -1,116 +0,0 @@ -/*------------------------------------------------------------------------- - * - * walprotocol.h - * Definitions relevant to the streaming WAL transmission protocol. - * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group - * - * src/include/replication/walprotocol.h - * - *------------------------------------------------------------------------- - */ -#ifndef _WALPROTOCOL_H -#define _WALPROTOCOL_H - -#include "access/xlogdefs.h" -#include "datatype/timestamp.h" - - -/* - * All messages from WalSender must contain these fields to allow us to - * correctly calculate the replication delay. - */ -typedef struct -{ - /* Current end of WAL on the sender */ - XLogRecPtr walEnd; - - /* Sender's system clock at the time of transmission */ - TimestampTz sendTime; -} WalSndrMessage; - - -/* - * Header for a WAL data message (message type 'w'). This is wrapped within - * a CopyData message at the FE/BE protocol level. - * - * The header is followed by actual WAL data. Note that the data length is - * not specified in the header --- it's just whatever remains in the message. - * - * walEnd and sendTime are not essential data, but are provided in case - * the receiver wants to adjust its behavior depending on how far behind - * it is. - */ -typedef struct -{ - /* WAL start location of the data included in this message */ - XLogRecPtr dataStart; - - /* Current end of WAL on the sender */ - XLogRecPtr walEnd; - - /* Sender's system clock at the time of transmission */ - TimestampTz sendTime; -} WalDataMessageHeader; - -/* - * Keepalive message from primary (message type 'k'). (lowercase k) - * This is wrapped within a CopyData message at the FE/BE protocol level. - * - * Note that the data length is not specified here. - */ -typedef WalSndrMessage PrimaryKeepaliveMessage; - -/* - * Reply message from standby (message type 'r'). This is wrapped within - * a CopyData message at the FE/BE protocol level. - * - * Note that the data length is not specified here. - */ -typedef struct -{ - /* - * The xlog locations that have been written, flushed, and applied by - * standby-side. These may be invalid if the standby-side is unable to or - * chooses not to report these. - */ - XLogRecPtr write; - XLogRecPtr flush; - XLogRecPtr apply; - - /* Sender's system clock at the time of transmission */ - TimestampTz sendTime; -} StandbyReplyMessage; - -/* - * Hot Standby feedback from standby (message type 'h'). This is wrapped within - * a CopyData message at the FE/BE protocol level. - * - * Note that the data length is not specified here. - */ -typedef struct -{ - /* - * The current xmin and epoch from the standby, for Hot Standby feedback. - * This may be invalid if the standby-side does not support feedback, or - * Hot Standby is not yet available. - */ - TransactionId xmin; - uint32 epoch; - - /* Sender's system clock at the time of transmission */ - TimestampTz sendTime; -} StandbyHSFeedbackMessage; - -/* - * Maximum data payload in a WAL data message. Must be >= XLOG_BLCKSZ. - * - * We don't have a good idea of what a good value would be; there's some - * overhead per message in both walsender and walreceiver, but on the other - * hand sending large batches makes walsender less responsive to signals - * because signals are checked only between messages. 128kB (with - * default 8k blocks) seems like a reasonable guess for now. - */ -#define MAX_SEND_SIZE (XLOG_BLCKSZ * 16) - -#endif /* _WALPROTOCOL_H */ diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index d21ec94a45..7a249f14ca 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -3,7 +3,7 @@ * walreceiver.h * Exports from replication/walreceiverfuncs.c. * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2014, PostgreSQL Global Development Group * * src/include/replication/walreceiver.h * @@ -14,11 +14,13 @@ #include "access/xlog.h" #include "access/xlogdefs.h" +#include "storage/latch.h" #include "storage/spin.h" #include "pgtime.h" -extern bool am_walreceiver; +/* user-settable parameters */ extern int wal_receiver_status_interval; +extern int wal_receiver_timeout; extern bool hot_standby_feedback; /* @@ -39,7 +41,9 @@ typedef enum WALRCV_STOPPED, /* stopped and mustn't start up again */ WALRCV_STARTING, /* launched, but the process hasn't * initialized yet */ - WALRCV_RUNNING, /* walreceiver is running */ + WALRCV_STREAMING, /* walreceiver is streaming */ + WALRCV_WAITING, /* stopped streaming, waiting for orders */ + WALRCV_RESTARTING, /* asked to restart streaming */ WALRCV_STOPPING /* requested to stop, but still running */ } WalRcvState; @@ -56,24 +60,28 @@ typedef struct pg_time_t startTime; /* - * receiveStart is the first byte position that will be received. When - * startup process starts the walreceiver, it sets receiveStart to the - * point where it wants the streaming to begin. + * receiveStart and receiveStartTLI indicate the first byte position and + * timeline that will be received. When startup process starts the + * walreceiver, it sets these to the point where it wants the streaming to + * begin. */ XLogRecPtr receiveStart; + TimeLineID receiveStartTLI; /* * receivedUpto-1 is the last byte position that has already been - * received. At the first startup of walreceiver, receivedUpto is set to - * receiveStart. After that, walreceiver updates this whenever it flushes - * the received WAL to disk. + * received, and receivedTLI is the timeline it came from. At the first + * startup of walreceiver, these are set to receiveStart and + * receiveStartTLI. After that, walreceiver updates these whenever it + * flushes the received WAL to disk. */ XLogRecPtr receivedUpto; + TimeLineID receivedTLI; /* * latestChunkStart is the starting byte position of the current "batch" * of received WAL. It's actually the same as the previous value of - * receivedUpto before the last flush to disk. Startup process can use + * receivedUpto before the last flush to disk. Startup process can use * this to detect whether it's keeping up or not. */ XLogRecPtr latestChunkStart; @@ -85,21 +93,51 @@ typedef struct TimestampTz lastMsgReceiptTime; /* + * Latest reported end of WAL on the sender + */ + XLogRecPtr latestWalEnd; + TimestampTz latestWalEndTime; + + /* * connection string; is used for walreceiver to connect with the primary. */ char conninfo[MAXCONNINFO]; + /* + * replication slot name; is also used for walreceiver to connect with the + * primary + */ + char slotname[NAMEDATALEN]; + slock_t mutex; /* locks shared variables shown above */ + + /* + * Latch used by startup process to wake up walreceiver after telling it + * where to start streaming (after setting receiveStart and + * receiveStartTLI). + */ + Latch latch; } WalRcvData; extern WalRcvData *WalRcv; /* libpqwalreceiver hooks */ -typedef bool (*walrcv_connect_type) (char *conninfo, XLogRecPtr startpoint); +typedef void (*walrcv_connect_type) (char *conninfo); extern PGDLLIMPORT walrcv_connect_type walrcv_connect; -typedef bool (*walrcv_receive_type) (int timeout, unsigned char *type, - char **buffer, int *len); +typedef void (*walrcv_identify_system_type) (TimeLineID *primary_tli); +extern PGDLLIMPORT walrcv_identify_system_type walrcv_identify_system; + +typedef void (*walrcv_readtimelinehistoryfile_type) (TimeLineID tli, char **filename, char **content, int *size); +extern PGDLLIMPORT walrcv_readtimelinehistoryfile_type walrcv_readtimelinehistoryfile; + +typedef bool (*walrcv_startstreaming_type) (TimeLineID tli, XLogRecPtr startpoint, char *slotname); +extern PGDLLIMPORT walrcv_startstreaming_type walrcv_startstreaming; + +typedef void (*walrcv_endstreaming_type) (TimeLineID *next_tli); +extern PGDLLIMPORT walrcv_endstreaming_type walrcv_endstreaming; + +typedef int (*walrcv_receive_type) (int timeout, char **buffer); extern PGDLLIMPORT walrcv_receive_type walrcv_receive; typedef void (*walrcv_send_type) (const char *buffer, int nbytes); @@ -109,15 +147,17 @@ typedef void (*walrcv_disconnect_type) (void); extern PGDLLIMPORT walrcv_disconnect_type walrcv_disconnect; /* prototypes for functions in walreceiver.c */ -extern void WalReceiverMain(void); +extern void WalReceiverMain(void) __attribute__((noreturn)); /* prototypes for functions in walreceiverfuncs.c */ extern Size WalRcvShmemSize(void); extern void WalRcvShmemInit(void); extern void ShutdownWalRcv(void); -extern bool WalRcvInProgress(void); -extern void RequestXLogStreaming(XLogRecPtr recptr, const char *conninfo); -extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart); +extern bool WalRcvStreaming(void); +extern bool WalRcvRunning(void); +extern void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, + const char *conninfo, const char *slotname); +extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI); extern int GetReplicationApplyDelay(void); extern int GetReplicationTransferLatency(void); diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h index 128d2dbf59..cff2be6d8f 100644 --- a/src/include/replication/walsender.h +++ b/src/include/replication/walsender.h @@ -3,7 +3,7 @@ * walsender.h * Exports from replication/walsender.c. * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2014, PostgreSQL Global Development Group * * src/include/replication/walsender.h * @@ -19,14 +19,16 @@ /* global state */ extern bool am_walsender; extern bool am_cascading_walsender; -extern volatile sig_atomic_t walsender_shutdown_requested; -extern volatile sig_atomic_t walsender_ready_to_stop; +extern bool am_db_walsender; +extern bool wake_wal_senders; /* user-settable parameters */ extern int max_wal_senders; -extern int replication_timeout; +extern int wal_sender_timeout; -extern int WalSenderMain(void); +extern void InitWalSender(void); +extern void exec_replication_command(const char *query_string); +extern void WalSndErrorCleanup(void); extern void WalSndSignals(void); extern Size WalSndShmemSize(void); extern void WalSndShmemInit(void); @@ -35,4 +37,27 @@ extern void WalSndRqstFileReload(void); extern Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS); +/* + * Remember that we want to wakeup walsenders later + * + * This is separated from doing the actual wakeup because the writeout is done + * while holding contended locks. + */ +#define WalSndWakeupRequest() \ + do { wake_wal_senders = true; } while (0) + +/* + * wakeup walsenders if there is work to be done + */ +#define WalSndWakeupProcessRequests() \ + do \ + { \ + if (wake_wal_senders) \ + { \ + wake_wal_senders = false; \ + if (max_wal_senders > 0) \ + WalSndWakeup(); \ + } \ + } while (0) + #endif /* _WALSENDER_H */ diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h index 66234cd8b5..dff33549c8 100644 --- a/src/include/replication/walsender_private.h +++ b/src/include/replication/walsender_private.h @@ -3,7 +3,7 @@ * walsender_private.h * Private definitions from replication/walsender.c. * - * Portions Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2014, PostgreSQL Global Development Group * * src/include/replication/walsender_private.h * @@ -95,7 +95,6 @@ extern WalSndCtlData *WalSndCtl; extern void WalSndSetState(WalSndState state); -extern void XLogRead(char *buf, XLogRecPtr startptr, Size count); /* * Internal functions for parsing the replication grammar, in repl_gram.y and diff --git a/src/include/rewrite/prs2lock.h b/src/include/rewrite/prs2lock.h index 8b9537337d..0a9374fad5 100644 --- a/src/include/rewrite/prs2lock.h +++ b/src/include/rewrite/prs2lock.h @@ -3,7 +3,7 @@ * prs2lock.h * data structures for POSTGRES Rule System II (rewrite rules only) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/prs2lock.h @@ -25,7 +25,6 @@ typedef struct RewriteRule { Oid ruleId; CmdType event; - AttrNumber attrno; Node *qual; List *actions; char enabled; diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h index 6061725dc4..0eb364914f 100644 --- a/src/include/rewrite/rewriteDefine.h +++ b/src/include/rewrite/rewriteDefine.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteDefine.h @@ -22,9 +22,9 @@ #define RULE_FIRES_ON_REPLICA 'R' #define RULE_DISABLED 'D' -extern void DefineRule(RuleStmt *stmt, const char *queryString); +extern Oid DefineRule(RuleStmt *stmt, const char *queryString); -extern void DefineQueryRewrite(char *rulename, +extern Oid DefineQueryRewrite(char *rulename, Oid event_relid, Node *event_qual, CmdType event_type, @@ -32,7 +32,7 @@ extern void DefineQueryRewrite(char *rulename, bool replace, List *action); -extern void RenameRewriteRule(Oid owningRel, const char *oldName, +extern Oid RenameRewriteRule(RangeVar *relation, const char *oldName, const char *newName); extern void setRuleCheckAsUser(Node *node, Oid userid); diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h index 3585eeaf8d..6ef45b8e49 100644 --- a/src/include/rewrite/rewriteHandler.h +++ b/src/include/rewrite/rewriteHandler.h @@ -4,7 +4,7 @@ * External interface to query rewriter. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteHandler.h @@ -18,8 +18,17 @@ #include "nodes/parsenodes.h" extern List *QueryRewrite(Query *parsetree); -extern void AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown); +extern void AcquireRewriteLocks(Query *parsetree, + bool forExecute, + bool forUpdatePushedDown); + extern Node *build_column_default(Relation rel, int attrno); +extern Query *get_view_query(Relation view); +extern const char *view_query_is_auto_updatable(Query *viewquery, + bool check_cols); +extern int relation_is_updatable(Oid reloid, + bool include_triggers, + Bitmapset *include_cols); #ifdef PGXC extern List *QueryRewriteCTAS(Query *parsetree); diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h index 7226187849..c2e4af4c93 100644 --- a/src/include/rewrite/rewriteManip.h +++ b/src/include/rewrite/rewriteManip.h @@ -4,7 +4,7 @@ * Querytree manipulation subroutines for query rewriter. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteManip.h @@ -31,6 +31,13 @@ struct replace_rte_variables_context bool inserted_sublink; /* have we inserted a SubLink? */ }; +typedef enum ReplaceVarsNoMatchOption +{ + REPLACEVARS_REPORT_ERROR, /* throw error if no match */ + REPLACEVARS_CHANGE_VARNO, /* change the Var's varno, nothing else */ + REPLACEVARS_SUBSTITUTE_NULL /* replace with a NULL Const */ +} ReplaceVarsNoMatchOption; + extern void OffsetVarNodes(Node *node, int offset, int sublevels_up); extern void ChangeVarNodes(Node *node, int old_varno, int new_varno, @@ -42,8 +49,6 @@ extern void IncrementVarSublevelsUp_rtable(List *rtable, extern bool rangeTableEntry_used(Node *node, int rt_index, int sublevels_up); -extern bool attribute_used(Node *node, int rt_index, int attno, - int sublevels_up); extern Query *getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr); @@ -52,9 +57,8 @@ extern void AddInvertedQual(Query *parsetree, Node *qual); extern bool contain_aggs_of_level(Node *node, int levelsup); extern int locate_agg_of_level(Node *node, int levelsup); +extern bool contain_windowfuncs(Node *node); extern int locate_windowfunc(Node *node); -extern bool checkExprHasAggs(Node *node); -extern bool checkExprHasWindowFuncs(Node *node); extern bool checkExprHasSubLink(Node *node); extern Node *replace_rte_variables(Node *node, @@ -65,9 +69,17 @@ extern Node *replace_rte_variables(Node *node, extern Node *replace_rte_variables_mutator(Node *node, replace_rte_variables_context *context); -extern Node *ResolveNew(Node *node, int target_varno, int sublevels_up, - RangeTblEntry *target_rte, - List *targetlist, int event, int update_varno, - bool *outer_hasSubLinks); +extern Node *map_variable_attnos(Node *node, + int target_varno, int sublevels_up, + const AttrNumber *attno_map, int map_length, + bool *found_whole_row); + +extern Node *ReplaceVarsFromTargetList(Node *node, + int target_varno, int sublevels_up, + RangeTblEntry *target_rte, + List *targetlist, + ReplaceVarsNoMatchOption nomatch_option, + int nomatch_varno, + bool *outer_hasSubLinks); #endif /* REWRITEMANIP_H */ diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h index e4822303da..30dff0a91e 100644 --- a/src/include/rewrite/rewriteRemove.h +++ b/src/include/rewrite/rewriteRemove.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteRemove.h diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h index e61fc0582d..7315b38c05 100644 --- a/src/include/rewrite/rewriteSupport.h +++ b/src/include/rewrite/rewriteSupport.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteSupport.h @@ -19,8 +19,7 @@ extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName); -extern void SetRelationRuleStatus(Oid relationId, bool relHasRules, - bool relIsBecomingView); +extern void SetRelationRuleStatus(Oid relationId, bool relHasRules); extern Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok); extern Oid get_rewrite_oid_without_relid(const char *rulename, diff --git a/src/include/rusagestub.h b/src/include/rusagestub.h index 10641bcd42..e9fb5c72f1 100644 --- a/src/include/rusagestub.h +++ b/src/include/rusagestub.h @@ -4,7 +4,7 @@ * Stubs for getrusage(3). * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rusagestub.h diff --git a/src/include/snowball/header.h b/src/include/snowball/header.h index 159aa4d8e8..848805c56e 100644 --- a/src/include/snowball/header.h +++ b/src/include/snowball/header.h @@ -4,7 +4,7 @@ * Replacement header file for Snowball stemmer modules * * The Snowball stemmer modules do #include "header.h", and think they - * are including snowball/libstemmer/header.h. We adjust the CPPFLAGS + * are including snowball/libstemmer/header.h. We adjust the CPPFLAGS * so that this file is found instead, and thereby we can modify the * headers they see. The main point here is to ensure that pg_config.h * is included before any system headers such as <stdio.h>; without that, @@ -13,7 +13,7 @@ * * NOTE: this file should not be included into any non-snowball sources! * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/snowball/header.h * diff --git a/src/include/storage/backendid.h b/src/include/storage/backendid.h index 6b951b1566..e6323a4793 100644 --- a/src/include/storage/backendid.h +++ b/src/include/storage/backendid.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/backendid.h diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h index 5037870991..2bef2eb6ad 100644 --- a/src/include/storage/barrier.h +++ b/src/include/storage/barrier.h @@ -3,7 +3,7 @@ * barrier.h * Memory barrier operations. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/barrier.h @@ -33,7 +33,7 @@ extern slock_t dummy_spinlock; * * A read barrier must act as a compiler barrier, and in addition must * guarantee that any loads issued prior to the barrier are completed before - * any loads issued after the barrier. Similarly, a write barrier acts + * any loads issued after the barrier. Similarly, a write barrier acts * as a compiler barrier, and also orders stores. Read and write barriers * are thus weaker than a full memory barrier, but stronger than a compiler * barrier. In practice, on machines with strong memory ordering, read and @@ -53,7 +53,12 @@ extern slock_t dummy_spinlock; /* * icc defines __GNUC__, but doesn't support gcc's inline asm syntax */ +#if defined(__ia64__) || defined(__ia64) +#define pg_memory_barrier() __mf() +#elif defined(__i386__) || defined(__x86_64__) #define pg_memory_barrier() _mm_mfence() +#endif + #define pg_compiler_barrier() __memory_barrier() #elif defined(__GNUC__) @@ -70,7 +75,7 @@ extern slock_t dummy_spinlock; * "lock; addl" has worked for longer than "mfence". */ #define pg_memory_barrier() \ - __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") + __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory", "cc") #define pg_read_barrier() pg_compiler_barrier() #define pg_write_barrier() pg_compiler_barrier() #elif defined(__x86_64__) /* 64 bit x86 */ @@ -84,7 +89,7 @@ extern slock_t dummy_spinlock; * do those things, a compiler barrier should be enough. */ #define pg_memory_barrier() \ - __asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory") + __asm__ __volatile__ ("lock; addl $0,0(%%rsp)" : : : "memory", "cc") #define pg_read_barrier() pg_compiler_barrier() #define pg_write_barrier() pg_compiler_barrier() #elif defined(__ia64__) || defined(__ia64) @@ -114,6 +119,10 @@ extern slock_t dummy_spinlock; #define pg_memory_barrier() __asm__ __volatile__ ("mb" : : : "memory") #define pg_read_barrier() __asm__ __volatile__ ("rmb" : : : "memory") #define pg_write_barrier() __asm__ __volatile__ ("wmb" : : : "memory") +#elif defined(__hppa) || defined(__hppa__) /* HP PA-RISC */ + +/* HPPA doesn't do either read or write reordering */ +#define pg_memory_barrier() pg_compiler_barrier() #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) /* @@ -148,7 +157,7 @@ extern slock_t dummy_spinlock; * fence. But all of our actual implementations seem OK in this regard. */ #if !defined(pg_memory_barrier) -#define pg_memory_barrier(x) \ +#define pg_memory_barrier() \ do { S_LOCK(&dummy_spinlock); S_UNLOCK(&dummy_spinlock); } while (0) #endif diff --git a/src/include/storage/block.h b/src/include/storage/block.h index a805f95a54..0a61103cf5 100644 --- a/src/include/storage/block.h +++ b/src/include/storage/block.h @@ -4,7 +4,7 @@ * POSTGRES disk block definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/block.h @@ -37,7 +37,7 @@ typedef uint32 BlockNumber; /* * BlockId: * - * this is a storage type for BlockNumber. in other words, this type + * this is a storage type for BlockNumber. in other words, this type * is used for on-disk structures (e.g., in HeapTupleData) whereas * BlockNumber is the type on which calculations are performed (e.g., * in access method code). diff --git a/src/include/storage/buf.h b/src/include/storage/buf.h index 228dc0e8c4..f1f88015d6 100644 --- a/src/include/storage/buf.h +++ b/src/include/storage/buf.h @@ -4,7 +4,7 @@ * Basic buffer manager data types. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buf.h diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 43f83d1ecc..c019013e72 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -5,7 +5,7 @@ * strategy. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buf_internals.h @@ -104,16 +104,19 @@ typedef struct buftag #define BufTableHashPartition(hashcode) \ ((hashcode) % NUM_BUFFER_PARTITIONS) #define BufMappingPartitionLock(hashcode) \ - ((LWLockId) (FirstBufMappingLock + BufTableHashPartition(hashcode))) + (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + \ + BufTableHashPartition(hashcode)].lock) +#define BufMappingPartitionLockByIndex(i) \ + (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + (i)].lock) /* * BufferDesc -- shared descriptor/state data for a single shared buffer. * * Note: buf_hdr_lock must be held to examine or change the tag, flags, * usage_count, refcount, or wait_backend_pid fields. buf_id field never - * changes after initialization, so does not need locking. freeNext is + * changes after initialization, so does not need locking. freeNext is * protected by the BufFreelistLock not buf_hdr_lock. The LWLocks can take - * care of themselves. The buf_hdr_lock is *not* used to control access to + * care of themselves. The buf_hdr_lock is *not* used to control access to * the data in the buffer! * * An exception is that if we have the buffer pinned, its tag can't change @@ -124,7 +127,7 @@ typedef struct buftag * * We can't physically remove items from a disk page if another backend has * the buffer pinned. Hence, a backend may need to wait for all other pins - * to go away. This is signaled by storing its own PID into + * to go away. This is signaled by storing its own PID into * wait_backend_pid and setting flag bit BM_PIN_COUNT_WAITER. At present, * there can be only one such waiter per buffer. * @@ -144,8 +147,8 @@ typedef struct sbufdesc int buf_id; /* buffer's index number (from 0) */ int freeNext; /* link in freelist chain */ - LWLockId io_in_progress_lock; /* to wait for I/O to complete */ - LWLockId content_lock; /* to lock access to buffer contents */ + LWLock *io_in_progress_lock; /* to wait for I/O to complete */ + LWLock *content_lock; /* to lock access to buffer contents */ } BufferDesc; #define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1) diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h index 910504a68d..653b8e6e16 100644 --- a/src/include/storage/buffile.h +++ b/src/include/storage/buffile.h @@ -15,7 +15,7 @@ * but currently we have no need for oversize temp files without buffered * access. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buffile.h diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 51eb77b689..89447d0b3d 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -4,7 +4,7 @@ * POSTGRES buffer manager definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/bufmgr.h @@ -38,7 +38,9 @@ typedef enum RBM_NORMAL, /* Normal read */ RBM_ZERO, /* Don't read from disk, caller will * initialize */ - RBM_ZERO_ON_ERROR /* Read, but return an all-zeros page on error */ + RBM_ZERO_ON_ERROR, /* Read, but return an all-zeros page on error */ + RBM_NORMAL_NO_LOG /* Don't log page as invalid during WAL + * replay; otherwise same as RBM_NORMAL */ } ReadBufferMode; /* in globals.c ... this duplicates miscadmin.h */ @@ -188,13 +190,14 @@ extern void FlushRelationBuffers(Relation rel); extern void FlushDatabaseBuffers(Oid dbid); extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, BlockNumber firstDelBlock); -extern void DropRelFileNodeAllBuffers(RelFileNodeBackend rnode); +extern void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes); extern void DropDatabaseBuffers(Oid dbid); #define RelationGetNumberOfBlocks(reln) \ RelationGetNumberOfBlocksInFork(reln, MAIN_FORKNUM) extern bool BufferIsPermanent(Buffer buffer); +extern XLogRecPtr BufferGetLSNAtomic(Buffer buffer); #ifdef NOT_USED extern void PrintPinnedBufs(void); @@ -203,7 +206,7 @@ extern Size BufferShmemSize(void); extern void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum); -extern void SetBufferCommitInfoNeedsSave(Buffer buffer); +extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std); extern void UnlockBuffers(void); extern void LockBuffer(Buffer buffer, int mode); diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index 1ab64e021d..d96e375f3f 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -4,7 +4,7 @@ * Standard POSTGRES buffer page definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/bufpage.h @@ -15,6 +15,7 @@ #define BUFPAGE_H #include "access/xlogdefs.h" +#include "storage/block.h" #include "storage/item.h" #include "storage/off.h" @@ -26,7 +27,7 @@ * disk page is always a slotted page of the form: * * +----------------+---------------------------------+ - * | PageHeaderData | linp1 linp2 linp3 ... | + * | PageHeaderData | linp1 linp2 linp3 ... | * +-----------+----+---------------------------------+ * | ... linpN | | * +-----------+--------------------------------------+ @@ -34,7 +35,7 @@ * | | * | v pd_upper | * +-------------+------------------------------------+ - * | | tupleN ... | + * | | tupleN ... | * +-------------+------------------+-----------------+ * | ... tuple3 tuple2 tuple1 | "special space" | * +--------------------------------+-----------------+ @@ -65,7 +66,7 @@ * * AM-specific per-page data (if any) is kept in the area marked "special * space"; each AM has an "opaque" structure defined somewhere that is - * stored as the page trailer. an access method should always + * stored as the page trailer. an access method should always * initialize its pages with PageInit and then set its own opaque * fields. */ @@ -83,12 +84,27 @@ typedef uint16 LocationIndex; /* + * For historical reasons, the 64-bit LSN value is stored as two 32-bit + * values. + */ +typedef struct +{ + uint32 xlogid; /* high bits */ + uint32 xrecoff; /* low bits */ +} PageXLogRecPtr; + +#define PageXLogRecPtrGet(val) \ + ((uint64) (val).xlogid << 32 | (val).xrecoff) +#define PageXLogRecPtrSet(ptr, lsn) \ + ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn)) + +/* * disk page organization * * space management information generic to any page * * pd_lsn - identifies xlog record for last change to this page. - * pd_tli - ditto. + * pd_checksum - page checksum, if set. * pd_flags - flag bits. * pd_lower - offset to start of free space. * pd_upper - offset to end of free space. @@ -99,12 +115,20 @@ typedef uint16 LocationIndex; * The LSN is used by the buffer manager to enforce the basic rule of WAL: * "thou shalt write xlog before data". A dirty buffer cannot be dumped * to disk until xlog has been flushed at least as far as the page's LSN. - * We also store the 16 least significant bits of the TLI for identification - * purposes (it is not clear that this is actually necessary, but it seems - * like a good idea). + * + * pd_checksum stores the page checksum, if it has been set for this page; + * zero is a valid value for a checksum. If a checksum is not in use then + * we leave the field unset. This will typically mean the field is zero + * though non-zero values may also be present if databases have been + * pg_upgraded from releases prior to 9.3, when the same byte offset was + * used to store the current timelineid when the page was last updated. + * Note that there is no indication on a page as to whether the checksum + * is valid or not, a deliberate design choice which avoids the problem + * of relying on the page contents to decide whether to verify it. Hence + * there are no flag bits relating to checksums. * * pd_prune_xid is a hint field that helps determine whether pruning will be - * useful. It is currently unused in index pages. + * useful. It is currently unused in index pages. * * The page version number and page size are packed together into a single * uint16 field. This is for historical reasons: before PostgreSQL 7.3, @@ -119,13 +143,13 @@ typedef uint16 LocationIndex; * On the high end, we can only support pages up to 32KB because lp_off/lp_len * are 15 bits. */ + typedef struct PageHeaderData { /* XXX LSN is member of *any* block, not only page-organized ones */ - XLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog + PageXLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog * record for last change to this page */ - uint16 pd_tli; /* least significant bits of the TimeLineID - * containing the LSN */ + uint16 pd_checksum; /* checksum */ uint16 pd_flags; /* flag bits, see below */ LocationIndex pd_lower; /* offset to start of free space */ LocationIndex pd_upper; /* offset to end of free space */ @@ -165,9 +189,12 @@ typedef PageHeaderData *PageHeader; * Release 8.3 uses 4; it changed the HeapTupleHeader layout again, and * added the pd_flags field (by stealing some bits from pd_tli), * as well as adding the pd_prune_xid field (which enlarges the header). + * + * As of Release 9.3, the checksum version must also be considered when + * handling pages. */ #define PG_PAGE_LAYOUT_VERSION 4 - +#define PG_DATA_CHECKSUM_VERSION 1 /* ---------------------------------------------------------------- * page support macros @@ -311,18 +338,13 @@ typedef PageHeaderData *PageHeader; / sizeof(ItemIdData))) /* - * Additional macros for access to page headers + * Additional macros for access to page headers. (Beware multiple evaluation + * of the arguments!) */ #define PageGetLSN(page) \ - (((PageHeader) (page))->pd_lsn) + PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn) #define PageSetLSN(page, lsn) \ - (((PageHeader) (page))->pd_lsn = (lsn)) - -/* NOTE: only the 16 least significant bits are stored */ -#define PageGetTLI(page) \ - (((PageHeader) (page))->pd_tli) -#define PageSetTLI(page, tli) \ - (((PageHeader) (page))->pd_tli = (uint16) (tli)) + PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn) #define PageHasFreeLinePointers(page) \ (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES) @@ -368,7 +390,7 @@ do { \ */ extern void PageInit(Page page, Size pageSize, Size specialSize); -extern bool PageHeaderIsValid(PageHeader page); +extern bool PageIsVerified(Page page, BlockNumber blkno); extern OffsetNumber PageAddItem(Page page, Item item, Size size, OffsetNumber offsetNumber, bool overwrite, bool is_heap); extern Page PageGetTempPage(Page page); @@ -381,5 +403,7 @@ extern Size PageGetExactFreeSpace(Page page); extern Size PageGetHeapFreeSpace(Page page); extern void PageIndexTupleDelete(Page page, OffsetNumber offset); extern void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems); +extern char *PageSetChecksumCopy(Page page, BlockNumber blkno); +extern void PageSetChecksumInplace(Page page, BlockNumber blkno); #endif /* BUFPAGE_H */ diff --git a/src/include/storage/checksum.h b/src/include/storage/checksum.h new file mode 100644 index 0000000000..1cbedac061 --- /dev/null +++ b/src/include/storage/checksum.h @@ -0,0 +1,24 @@ +/*------------------------------------------------------------------------- + * + * checksum.h + * Checksum implementation for data pages. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/checksum.h + * + *------------------------------------------------------------------------- + */ +#ifndef CHECKSUM_H +#define CHECKSUM_H + +#include "storage/block.h" + +/* + * Compute the checksum for a Postgres page. The page must be aligned on a + * 4-byte boundary. + */ +extern uint16 pg_checksum_page(char *page, BlockNumber blkno); + +#endif /* CHECKSUM_H */ diff --git a/src/include/storage/checksum_impl.h b/src/include/storage/checksum_impl.h new file mode 100644 index 0000000000..612831c770 --- /dev/null +++ b/src/include/storage/checksum_impl.h @@ -0,0 +1,207 @@ +/*------------------------------------------------------------------------- + * + * checksum_impl.h + * Checksum implementation for data pages. + * + * This file exists for the benefit of external programs that may wish to + * check Postgres page checksums. They can #include this to get the code + * referenced by storage/checksum.h. (Note: you may need to redefine + * Assert() as empty to compile this successfully externally.) + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/checksum_impl.h + * + *------------------------------------------------------------------------- + */ + +/* + * The algorithm used to checksum pages is chosen for very fast calculation. + * Workloads where the database working set fits into OS file cache but not + * into shared buffers can read in pages at a very fast pace and the checksum + * algorithm itself can become the largest bottleneck. + * + * The checksum algorithm itself is based on the FNV-1a hash (FNV is shorthand + * for Fowler/Noll/Vo). The primitive of a plain FNV-1a hash folds in data 1 + * byte at a time according to the formula: + * + * hash = (hash ^ value) * FNV_PRIME + * + * FNV-1a algorithm is described at http://www.isthe.com/chongo/tech/comp/fnv/ + * + * PostgreSQL doesn't use FNV-1a hash directly because it has bad mixing of + * high bits - high order bits in input data only affect high order bits in + * output data. To resolve this we xor in the value prior to multiplication + * shifted right by 17 bits. The number 17 was chosen because it doesn't + * have common denominator with set bit positions in FNV_PRIME and empirically + * provides the fastest mixing for high order bits of final iterations quickly + * avalanche into lower positions. For performance reasons we choose to combine + * 4 bytes at a time. The actual hash formula used as the basis is: + * + * hash = (hash ^ value) * FNV_PRIME ^ ((hash ^ value) >> 17) + * + * The main bottleneck in this calculation is the multiplication latency. To + * hide the latency and to make use of SIMD parallelism multiple hash values + * are calculated in parallel. The page is treated as a 32 column two + * dimensional array of 32 bit values. Each column is aggregated separately + * into a partial checksum. Each partial checksum uses a different initial + * value (offset basis in FNV terminology). The initial values actually used + * were chosen randomly, as the values themselves don't matter as much as that + * they are different and don't match anything in real data. After initializing + * partial checksums each value in the column is aggregated according to the + * above formula. Finally two more iterations of the formula are performed with + * value 0 to mix the bits of the last value added. + * + * The partial checksums are then folded together using xor to form a single + * 32-bit checksum. The caller can safely reduce the value to 16 bits + * using modulo 2^16-1. That will cause a very slight bias towards lower + * values but this is not significant for the performance of the + * checksum. + * + * The algorithm choice was based on what instructions are available in SIMD + * instruction sets. This meant that a fast and good algorithm needed to use + * multiplication as the main mixing operator. The simplest multiplication + * based checksum primitive is the one used by FNV. The prime used is chosen + * for good dispersion of values. It has no known simple patterns that result + * in collisions. Test of 5-bit differentials of the primitive over 64bit keys + * reveals no differentials with 3 or more values out of 100000 random keys + * colliding. Avalanche test shows that only high order bits of the last word + * have a bias. Tests of 1-4 uncorrelated bit errors, stray 0 and 0xFF bytes, + * overwriting page from random position to end with 0 bytes, and overwriting + * random segments of page with 0x00, 0xFF and random data all show optimal + * 2e-16 false positive rate within margin of error. + * + * Vectorization of the algorithm requires 32bit x 32bit -> 32bit integer + * multiplication instruction. As of 2013 the corresponding instruction is + * available on x86 SSE4.1 extensions (pmulld) and ARM NEON (vmul.i32). + * Vectorization requires a compiler to do the vectorization for us. For recent + * GCC versions the flags -msse4.1 -funroll-loops -ftree-vectorize are enough + * to achieve vectorization. + * + * The optimal amount of parallelism to use depends on CPU specific instruction + * latency, SIMD instruction width, throughput and the amount of registers + * available to hold intermediate state. Generally, more parallelism is better + * up to the point that state doesn't fit in registers and extra load-store + * instructions are needed to swap values in/out. The number chosen is a fixed + * part of the algorithm because changing the parallelism changes the checksum + * result. + * + * The parallelism number 32 was chosen based on the fact that it is the + * largest state that fits into architecturally visible x86 SSE registers while + * leaving some free registers for intermediate values. For future processors + * with 256bit vector registers this will leave some performance on the table. + * When vectorization is not available it might be beneficial to restructure + * the computation to calculate a subset of the columns at a time and perform + * multiple passes to avoid register spilling. This optimization opportunity + * is not used. Current coding also assumes that the compiler has the ability + * to unroll the inner loop to avoid loop overhead and minimize register + * spilling. For less sophisticated compilers it might be beneficial to + * manually unroll the inner loop. + */ + +#include "storage/bufpage.h" + +/* number of checksums to calculate in parallel */ +#define N_SUMS 32 +/* prime multiplier of FNV-1a hash */ +#define FNV_PRIME 16777619 + +/* + * Base offsets to initialize each of the parallel FNV hashes into a + * different initial state. + */ +static const uint32 checksumBaseOffsets[N_SUMS] = { + 0x5B1F36E9, 0xB8525960, 0x02AB50AA, 0x1DE66D2A, + 0x79FF467A, 0x9BB9F8A3, 0x217E7CD2, 0x83E13D2C, + 0xF8D4474F, 0xE39EB970, 0x42C6AE16, 0x993216FA, + 0x7B093B5D, 0x98DAFF3C, 0xF718902A, 0x0B1C9CDB, + 0xE58F764B, 0x187636BC, 0x5D7B3BB1, 0xE73DE7DE, + 0x92BEC979, 0xCCA6C0B2, 0x304A0979, 0x85AA43D4, + 0x783125BB, 0x6CA8EAA2, 0xE407EAC6, 0x4B5CFC3E, + 0x9FBF8C76, 0x15CA20BE, 0xF2CA9FD3, 0x959BD756 +}; + +/* + * Calculate one round of the checksum. + */ +#define CHECKSUM_COMP(checksum, value) \ +do { \ + uint32 __tmp = (checksum) ^ (value); \ + (checksum) = __tmp * FNV_PRIME ^ (__tmp >> 17); \ +} while (0) + +/* + * Block checksum algorithm. The data argument must be aligned on a 4-byte + * boundary. + */ +static uint32 +pg_checksum_block(char *data, uint32 size) +{ + uint32 sums[N_SUMS]; + uint32 (*dataArr)[N_SUMS] = (uint32 (*)[N_SUMS]) data; + uint32 result = 0; + uint32 i, + j; + + /* ensure that the size is compatible with the algorithm */ + Assert((size % (sizeof(uint32) * N_SUMS)) == 0); + + /* initialize partial checksums to their corresponding offsets */ + memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets)); + + /* main checksum calculation */ + for (i = 0; i < size / sizeof(uint32) / N_SUMS; i++) + for (j = 0; j < N_SUMS; j++) + CHECKSUM_COMP(sums[j], dataArr[i][j]); + + /* finally add in two rounds of zeroes for additional mixing */ + for (i = 0; i < 2; i++) + for (j = 0; j < N_SUMS; j++) + CHECKSUM_COMP(sums[j], 0); + + /* xor fold partial checksums together */ + for (i = 0; i < N_SUMS; i++) + result ^= sums[i]; + + return result; +} + +/* + * Compute the checksum for a Postgres page. The page must be aligned on a + * 4-byte boundary. + * + * The checksum includes the block number (to detect the case where a page is + * somehow moved to a different location), the page header (excluding the + * checksum itself), and the page data. + */ +uint16 +pg_checksum_page(char *page, BlockNumber blkno) +{ + PageHeader phdr = (PageHeader) page; + uint16 save_checksum; + uint32 checksum; + + /* We only calculate the checksum for properly-initialized pages */ + Assert(!PageIsNew(page)); + + /* + * Save pd_checksum and temporarily set it to zero, so that the checksum + * calculation isn't affected by the old checksum stored on the page. + * Restore it after, because actually updating the checksum is NOT part of + * the API of this function. + */ + save_checksum = phdr->pd_checksum; + phdr->pd_checksum = 0; + checksum = pg_checksum_block(page, BLCKSZ); + phdr->pd_checksum = save_checksum; + + /* Mix in the block number to detect transposed pages */ + checksum ^= blkno; + + /* + * Reduce to a uint16 (to fit in the pd_checksum field) with an offset of + * one. That avoids checksums of zero, which seems like a good idea. + */ + return (checksum % 65535) + 1; +} diff --git a/src/include/storage/copydir.h b/src/include/storage/copydir.h index c7c39343f1..80767a12ad 100644 --- a/src/include/storage/copydir.h +++ b/src/include/storage/copydir.h @@ -3,7 +3,7 @@ * copydir.h * Copy a directory. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/copydir.h diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h new file mode 100644 index 0000000000..1d0110d4b2 --- /dev/null +++ b/src/include/storage/dsm.h @@ -0,0 +1,56 @@ +/*------------------------------------------------------------------------- + * + * dsm.h + * manage dynamic shared memory segments + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/dsm.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSM_H +#define DSM_H + +#include "storage/dsm_impl.h" + +typedef struct dsm_segment dsm_segment; + +/* Startup and shutdown functions. */ +struct PGShmemHeader; /* avoid including pg_shmem.h */ +extern void dsm_cleanup_using_control_segment(dsm_handle old_control_handle); +extern void dsm_postmaster_startup(struct PGShmemHeader *); +extern void dsm_backend_shutdown(void); +extern void dsm_detach_all(void); + +#ifdef EXEC_BACKEND +extern void dsm_set_control_handle(dsm_handle h); +#endif + +/* Functions that create, update, or remove mappings. */ +extern dsm_segment *dsm_create(Size size); +extern dsm_segment *dsm_attach(dsm_handle h); +extern void *dsm_resize(dsm_segment *seg, Size size); +extern void *dsm_remap(dsm_segment *seg); +extern void dsm_detach(dsm_segment *seg); + +/* Resource management functions. */ +extern void dsm_keep_mapping(dsm_segment *seg); +extern void dsm_keep_segment(dsm_segment *seg); +extern dsm_segment *dsm_find_mapping(dsm_handle h); + +/* Informational functions. */ +extern void *dsm_segment_address(dsm_segment *seg); +extern Size dsm_segment_map_length(dsm_segment *seg); +extern dsm_handle dsm_segment_handle(dsm_segment *seg); + +/* Cleanup hooks. */ +typedef void (*on_dsm_detach_callback) (dsm_segment *, Datum arg); +extern void on_dsm_detach(dsm_segment *seg, + on_dsm_detach_callback function, Datum arg); +extern void cancel_on_dsm_detach(dsm_segment *seg, + on_dsm_detach_callback function, Datum arg); +extern void reset_on_dsm_detach(void); + +#endif /* DSM_H */ diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h new file mode 100644 index 0000000000..6e2a013411 --- /dev/null +++ b/src/include/storage/dsm_impl.h @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------- + * + * dsm_impl.h + * low-level dynamic shared memory primitives + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/dsm_impl.h + * + *------------------------------------------------------------------------- + */ +#ifndef DSM_IMPL_H +#define DSM_IMPL_H + +/* Dynamic shared memory implementations. */ +#define DSM_IMPL_NONE 0 +#define DSM_IMPL_POSIX 1 +#define DSM_IMPL_SYSV 2 +#define DSM_IMPL_WINDOWS 3 +#define DSM_IMPL_MMAP 4 + +/* + * Determine which dynamic shared memory implementations will be supported + * on this platform, and which one will be the default. + */ +#ifdef WIN32 +#define USE_DSM_WINDOWS +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_WINDOWS +#else +#ifdef HAVE_SHM_OPEN +#define USE_DSM_POSIX +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_POSIX +#endif +#define USE_DSM_SYSV +#ifndef DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE +#define DEFAULT_DYNAMIC_SHARED_MEMORY_TYPE DSM_IMPL_SYSV +#endif +#define USE_DSM_MMAP +#endif + +/* GUC. */ +extern int dynamic_shared_memory_type; + +/* + * Directory for on-disk state. + * + * This is used by all implementations for crash recovery and by the mmap + * implementation for storage. + */ +#define PG_DYNSHMEM_DIR "pg_dynshmem" +#define PG_DYNSHMEM_MMAP_FILE_PREFIX "mmap." + +/* A "name" for a dynamic shared memory segment. */ +typedef uint32 dsm_handle; + +/* All the shared-memory operations we know about. */ +typedef enum +{ + DSM_OP_CREATE, + DSM_OP_ATTACH, + DSM_OP_DETACH, + DSM_OP_RESIZE, + DSM_OP_DESTROY +} dsm_op; + +/* Create, attach to, detach from, resize, or destroy a segment. */ +extern bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, + void **impl_private, void **mapped_address, Size *mapped_size, + int elevel); + +/* Some implementations cannot resize segments. Can this one? */ +extern bool dsm_impl_can_resize(void); + +/* Implementation-dependent actions required to keep segment until shudown. */ +extern void dsm_impl_keep_segment(dsm_handle handle, void *impl_private); + +#endif /* DSM_IMPL_H */ diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index bad9f10c62..a6df8fb5a3 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -4,7 +4,7 @@ * Virtual file descriptor definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/fd.h @@ -16,13 +16,13 @@ * calls: * * File {Close, Read, Write, Seek, Tell, Sync} - * {File Name Open, Allocate, Free} File + * {Path Name Open, Allocate, Free} File * * These are NOT JUST RENAMINGS OF THE UNIX ROUTINES. * Use them for all file activity... * * File fd; - * fd = FilePathOpenFile("foo", O_RDONLY, 0600); + * fd = PathNameOpenFile("foo", O_RDONLY, 0600); * * AllocateFile(); * FreeFile(); @@ -33,7 +33,8 @@ * no way for them to share kernel file descriptors with other files. * * Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate - * open directories (DIR*). + * open directories (DIR*), and OpenTransientFile/CloseTransient File for an + * unbuffered file descriptor. */ #ifndef FD_H #define FD_H @@ -66,7 +67,6 @@ extern int max_safe_fds; /* Operations on virtual Files --- equivalent to Unix kernel file ops */ extern File PathNameOpenFile(FileName fileName, int fileFlags, int fileMode); extern File OpenTemporaryFile(bool interXact); -extern void FileSetTransient(File file); extern void FileClose(File file); extern int FilePrefetch(File file, off_t offset, int amount); extern int FileRead(File file, char *buffer, int amount); @@ -80,11 +80,19 @@ extern char *FilePathName(File file); extern FILE *AllocateFile(const char *name, const char *mode); extern int FreeFile(FILE *file); +/* Operations that allow use of pipe streams (popen/pclose) */ +extern FILE *OpenPipeStream(const char *command, const char *mode); +extern int ClosePipeStream(FILE *file); + /* Operations to allow use of the <dirent.h> library routines */ extern DIR *AllocateDir(const char *dirname); extern struct dirent *ReadDir(DIR *dir, const char *dirname); extern int FreeDir(DIR *dir); +/* Operations to allow use of a plain kernel FD, with automatic cleanup */ +extern int OpenTransientFile(FileName fileName, int fileFlags, int fileMode); +extern int CloseTransientFile(int fd); + /* If you've really really gotta have a plain kernel FD, use this */ extern int BasicOpenFile(FileName fileName, int fileFlags, int fileMode); @@ -105,6 +113,7 @@ extern int pg_fsync_no_writethrough(int fd); extern int pg_fsync_writethrough(int fd); extern int pg_fdatasync(int fd); extern int pg_flush_data(int fd, off_t offset, off_t amount); +extern void fsync_fname(char *fname, bool isdir); /* Filename components for OpenTemporaryFile */ #define PG_TEMP_FILES_DIR "pgsql_tmp" diff --git a/src/include/storage/freespace.h b/src/include/storage/freespace.h index e5862abd2e..b2479f8ab4 100644 --- a/src/include/storage/freespace.h +++ b/src/include/storage/freespace.h @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free space in relations * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/freespace.h diff --git a/src/include/storage/fsm_internals.h b/src/include/storage/fsm_internals.h index 543d438bd5..1df46dbbe4 100644 --- a/src/include/storage/fsm_internals.h +++ b/src/include/storage/fsm_internals.h @@ -4,7 +4,7 @@ * internal functions for free space map * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/fsm_internals.h diff --git a/src/include/storage/indexfsm.h b/src/include/storage/indexfsm.h index f90e21cef5..f29aed1a80 100644 --- a/src/include/storage/indexfsm.h +++ b/src/include/storage/indexfsm.h @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding an unused page in index * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/indexfsm.h diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 16025c3dde..52aff5bbe5 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -4,11 +4,11 @@ * POSTGRES inter-process communication definitions. * * This file is misnamed, as it no longer has much of anything directly - * to do with IPC. The functionality here is concerned with managing + * to do with IPC. The functionality here is concerned with managing * exit-time cleanup for either a postmaster or a backend. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/ipc.h @@ -46,14 +46,14 @@ typedef void (*shmem_startup_hook_type) (void); */ #define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \ do { \ - on_shmem_exit(cleanup_function, arg); \ + before_shmem_exit(cleanup_function, arg); \ PG_TRY() #define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg) \ - cancel_shmem_exit(cleanup_function, arg); \ + cancel_before_shmem_exit(cleanup_function, arg); \ PG_CATCH(); \ { \ - cancel_shmem_exit(cleanup_function, arg); \ + cancel_before_shmem_exit(cleanup_function, arg); \ cleanup_function (0, arg); \ PG_RE_THROW(); \ } \ @@ -62,13 +62,14 @@ typedef void (*shmem_startup_hook_type) (void); /* ipc.c */ -extern bool proc_exit_inprogress; +extern PGDLLIMPORT bool proc_exit_inprogress; -extern void proc_exit(int code); +extern void proc_exit(int code) __attribute__((noreturn)); extern void shmem_exit(int code); extern void on_proc_exit(pg_on_exit_callback function, Datum arg); extern void on_shmem_exit(pg_on_exit_callback function, Datum arg); -extern void cancel_shmem_exit(pg_on_exit_callback function, Datum arg); +extern void before_shmem_exit(pg_on_exit_callback function, Datum arg); +extern void cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg); extern void on_exit_reset(void); /* ipci.c */ diff --git a/src/include/storage/item.h b/src/include/storage/item.h index bbc80d2f4d..e74c5cf38a 100644 --- a/src/include/storage/item.h +++ b/src/include/storage/item.h @@ -4,7 +4,7 @@ * POSTGRES disk item definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/item.h diff --git a/src/include/storage/itemid.h b/src/include/storage/itemid.h index a5b45442cd..bf2c4bd826 100644 --- a/src/include/storage/itemid.h +++ b/src/include/storage/itemid.h @@ -4,7 +4,7 @@ * Standard POSTGRES buffer page item identifier definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/itemid.h @@ -31,7 +31,7 @@ typedef struct ItemIdData typedef ItemIdData *ItemId; /* - * lp_flags has these possible states. An UNUSED line pointer is available + * lp_flags has these possible states. An UNUSED line pointer is available * for immediate re-use, the other states are not. */ #define LP_UNUSED 0 /* unused (should always have lp_len=0) */ diff --git a/src/include/storage/itemptr.h b/src/include/storage/itemptr.h index 331812b8ef..78766d0698 100644 --- a/src/include/storage/itemptr.h +++ b/src/include/storage/itemptr.h @@ -4,7 +4,7 @@ * POSTGRES disk item pointer definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/itemptr.h @@ -29,7 +29,7 @@ * tuple header on disk, it's very important not to waste space with * structure padding bytes. The struct is designed to be six bytes long * (it contains three int16 fields) but a few compilers will pad it to - * eight bytes unless coerced. We apply appropriate persuasion where + * eight bytes unless coerced. We apply appropriate persuasion where * possible, and to cope with unpersuadable compilers, we try to use * "SizeOfIptrData" rather than "sizeof(ItemPointerData)" when computing * on-disk sizes. @@ -116,6 +116,9 @@ typedef ItemPointerData *ItemPointer; /* * ItemPointerCopy * Copies the contents of one disk item pointer to another. + * + * Should there ever be padding in an ItemPointer this would need to be handled + * differently as it's used as hash key. */ #define ItemPointerCopy(fromPointer, toPointer) \ ( \ diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h index 1fe07ee43a..30438a98cf 100644 --- a/src/include/storage/large_object.h +++ b/src/include/storage/large_object.h @@ -5,7 +5,7 @@ * zillions of large objects (internal, external, jaquith, inversion). * Now we only support inversion. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/large_object.h @@ -27,6 +27,10 @@ * offset is the current seek offset within the LO * flags contains some flag bits * + * NOTE: in current usage, flag bit IFS_RDLOCK is *always* set, and we don't + * bother to test for it. Permission checks are made at first read or write + * attempt, not during inv_open(), so we have other bits to remember that. + * * NOTE: before 7.1, we also had to store references to the separate table * and index of a specific large object. Now they all live in pg_largeobject * and are accessed via a common relation descriptor. @@ -37,12 +41,14 @@ typedef struct LargeObjectDesc Oid id; /* LO's identifier */ Snapshot snapshot; /* snapshot to use */ SubTransactionId subid; /* owning subtransaction ID */ - uint32 offset; /* current seek pointer */ - int flags; /* locking info, etc */ + uint64 offset; /* current seek pointer */ + int flags; /* see flag bits below */ -/* flag bits: */ -#define IFS_RDLOCK (1 << 0) -#define IFS_WRLOCK (1 << 1) +/* bits in flags: */ +#define IFS_RDLOCK (1 << 0) /* LO was opened for reading */ +#define IFS_WRLOCK (1 << 1) /* LO was opened for writing */ +#define IFS_RD_PERM_OK (1 << 2) /* read permission has been verified */ +#define IFS_WR_PERM_OK (1 << 3) /* write permission has been verified */ } LargeObjectDesc; @@ -60,9 +66,17 @@ typedef struct LargeObjectDesc * Also, it seems to be a smart move to make the page size be a power of 2, * since clients will often be written to send data in power-of-2 blocks. * This avoids unnecessary tuple updates caused by partial-page writes. + * + * NB: Changing LOBLKSIZE requires an initdb. */ #define LOBLKSIZE (BLCKSZ / 4) +/* + * Maximum length in bytes for a large object. To make this larger, we'd + * have to widen pg_largeobject.pageno as well as various internal variables. + */ +#define MAX_LARGE_OBJECT_SIZE ((int64) INT_MAX * LOBLKSIZE) + /* * Function definitions... @@ -74,10 +88,10 @@ extern Oid inv_create(Oid lobjId); extern LargeObjectDesc *inv_open(Oid lobjId, int flags, MemoryContext mcxt); extern void inv_close(LargeObjectDesc *obj_desc); extern int inv_drop(Oid lobjId); -extern int inv_seek(LargeObjectDesc *obj_desc, int offset, int whence); -extern int inv_tell(LargeObjectDesc *obj_desc); +extern int64 inv_seek(LargeObjectDesc *obj_desc, int64 offset, int whence); +extern int64 inv_tell(LargeObjectDesc *obj_desc); extern int inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes); extern int inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes); -extern void inv_truncate(LargeObjectDesc *obj_desc, int len); +extern void inv_truncate(LargeObjectDesc *obj_desc, int64 len); #endif /* LARGE_OBJECT_H */ diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 71fb4868a0..ab722e7566 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -33,8 +33,8 @@ * ResetLatch - Clears the latch, allowing it to be set again * WaitLatch - Waits for the latch to become set * - * WaitLatch includes a provision for timeouts (which should hopefully not - * be necessary once the code is fully latch-ified) and a provision for + * WaitLatch includes a provision for timeouts (which should be avoided + * when possible, as they incur extra overhead) and a provision for * postmaster child processes to wake up immediately on postmaster death. * See unix_latch.c for detailed specifications for the exported functions. * @@ -64,17 +64,18 @@ * will be lifted in future by inserting suitable memory barriers into * SetLatch and ResetLatch. * + * On some platforms, signals will not interrupt the latch wait primitive + * by themselves. Therefore, it is critical that any signal handler that + * is meant to terminate a WaitLatch wait calls SetLatch. + * * Note that use of the process latch (PGPROC.procLatch) is generally better * than an ad-hoc shared latch for signaling auxiliary processes. This is * because generic signal handlers will call SetLatch on the process latch * only, so using any latch other than the process latch effectively precludes - * ever registering a generic handler. Since signals have the potential to - * invalidate the latch timeout on some platforms, resulting in a - * denial-of-service, it is important to verify that all signal handlers - * within all WaitLatch-calling processes call SetLatch. + * use of any generic handler. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/latch.h @@ -111,6 +112,7 @@ typedef struct /* * prototypes for functions in latch.c */ +extern void InitializeLatchSupport(void); extern void InitLatch(volatile Latch *latch); extern void InitSharedLatch(volatile Latch *latch); extern void OwnLatch(volatile Latch *latch); diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h index de340c4973..e9447b7dcc 100644 --- a/src/include/storage/lmgr.h +++ b/src/include/storage/lmgr.h @@ -4,7 +4,7 @@ * POSTGRES lock manager definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lmgr.h @@ -20,6 +20,20 @@ #include "utils/rel.h" +/* XactLockTableWait operations */ +typedef enum XLTW_Oper +{ + XLTW_None, + XLTW_Update, + XLTW_Delete, + XLTW_Lock, + XLTW_LockUpdated, + XLTW_InsertIndex, + XLTW_InsertIndexUnique, + XLTW_FetchUpdated, + XLTW_RecheckExclusionConstr +} XLTW_Oper; + extern void RelationInitLockInfo(Relation relation); /* Lock a relation */ @@ -31,6 +45,7 @@ extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode); extern void LockRelation(Relation relation, LOCKMODE lockmode); extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode); extern void UnlockRelation(Relation relation, LOCKMODE lockmode); +extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode); extern void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); extern void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); @@ -53,9 +68,14 @@ extern void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode); /* Lock an XID (used to wait for a transaction to finish) */ extern void XactLockTableInsert(TransactionId xid); extern void XactLockTableDelete(TransactionId xid); -extern void XactLockTableWait(TransactionId xid); +extern void XactLockTableWait(TransactionId xid, Relation rel, + ItemPointer ctid, XLTW_Oper oper); extern bool ConditionalXactLockTableWait(TransactionId xid); +/* Lock VXIDs, specified by conflicting locktags */ +extern void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode); +extern void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode); + /* Lock a general object (other than a relation) of the current database */ extern void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode); diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 708a27a735..4cc9527284 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -4,7 +4,7 @@ * POSTGRES low-level lock mechanism * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lock.h @@ -43,7 +43,7 @@ extern bool Debug_deadlocks; /* * Top-level transactions are identified by VirtualTransactionIDs comprising * the BackendId of the backend running the xact, plus a locally-assigned - * LocalTransactionId. These are guaranteed unique over the short term, + * LocalTransactionId. These are guaranteed unique over the short term, * but will be reused after a database restart; hence they should never * be stored on disk. * @@ -157,7 +157,7 @@ typedef uint16 LOCKMETHODID; /* * LOCKTAG is the key information needed to look up a LOCK item in the - * lock hashtable. A LOCKTAG value uniquely identifies a lockable object. + * lock hashtable. A LOCKTAG value uniquely identifies a lockable object. * * The LockTagType enum defines the different kinds of objects we can lock. * We can handle up to 256 different LockTagTypes. @@ -210,7 +210,7 @@ typedef struct LOCKTAG /* * These macros define how we map logical IDs of lockable objects into - * the physical fields of LOCKTAG. Use these to set up LOCKTAG values, + * the physical fields of LOCKTAG. Use these to set up LOCKTAG values, * rather than accessing the fields directly. Note multiple eval of target! */ #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \ @@ -322,14 +322,14 @@ typedef struct LOCK * a PROCLOCK struct. * * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the - * proclock hashtable. A PROCLOCKTAG value uniquely identifies the combination + * proclock hashtable. A PROCLOCKTAG value uniquely identifies the combination * of a lockable object and a holder/waiter for that object. (We can use * pointers here because the PROCLOCKTAG need only be unique for the lifespan * of the PROCLOCK, and it will never outlive the lock or the proc.) * * Internally to a backend, it is possible for the same lock to be held * for different purposes: the backend tracks transaction locks separately - * from session locks. However, this is not reflected in the shared-memory + * from session locks. However, this is not reflected in the shared-memory * state: we only track which backend(s) hold the lock. This is OK since a * backend can never block itself. * @@ -340,7 +340,7 @@ typedef struct LOCK * as soon as convenient. * * releaseMask is workspace for LockReleaseAll(): it shows the locks due - * to be released during the current call. This must only be examined or + * to be released during the current call. This must only be examined or * set by the backend owning the PROCLOCK. * * Each PROCLOCK object is linked into lists for both the associated LOCK @@ -373,12 +373,26 @@ typedef struct PROCLOCK /* * Each backend also maintains a local hash table with information about each - * lock it is currently interested in. In particular the local table counts + * lock it is currently interested in. In particular the local table counts * the number of times that lock has been acquired. This allows multiple * requests for the same lock to be executed without additional accesses to * shared memory. We also track the number of lock acquisitions per * ResourceOwner, so that we can release just those locks belonging to a * particular ResourceOwner. + * + * When holding a lock taken "normally", the lock and proclock fields always + * point to the associated objects in shared memory. However, if we acquired + * the lock via the fast-path mechanism, the lock and proclock fields are set + * to NULL, since there probably aren't any such objects in shared memory. + * (If the lock later gets promoted to normal representation, we may eventually + * update our locallock's lock/proclock fields after finding the shared + * objects.) + * + * Caution: a locallock object can be left over from a failed lock acquisition + * attempt. In this case its lock/proclock fields are untrustworthy, since + * the shared lock object is neither held nor awaited, and hence is available + * to be reclaimed. If nLocks > 0 then these pointers must either be valid or + * NULL, but when nLocks == 0 they should be considered garbage. */ typedef struct LOCALLOCKTAG { @@ -404,13 +418,13 @@ typedef struct LOCALLOCK LOCALLOCKTAG tag; /* unique identifier of locallock entry */ /* data */ - LOCK *lock; /* associated LOCK object in shared mem */ - PROCLOCK *proclock; /* associated PROCLOCK object in shmem */ + LOCK *lock; /* associated LOCK object, if any */ + PROCLOCK *proclock; /* associated PROCLOCK object, if any */ uint32 hashcode; /* copy of LOCKTAG's hash value */ int64 nLocks; /* total number of times lock is held */ int numLockOwners; /* # of relevant ResourceOwners */ int maxLockOwners; /* allocated size of array */ - bool holdsStrongLockCount; /* bumped FastPathStrongRelatonLocks? */ + bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */ } LOCALLOCK; @@ -469,8 +483,10 @@ typedef enum #define LockHashPartition(hashcode) \ ((hashcode) % NUM_LOCK_PARTITIONS) #define LockHashPartitionLock(hashcode) \ - ((LWLockId) (FirstLockMgrLock + LockHashPartition(hashcode))) - + (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \ + LockHashPartition(hashcode)].lock) +#define LockHashPartitionLockByIndex(i) \ + (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock) /* * function prototypes @@ -478,6 +494,7 @@ typedef enum extern void InitLocks(void); extern LockMethod GetLocksMethodTable(const LOCK *lock); extern uint32 LockTagHashCode(const LOCKTAG *locktag); +extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2); extern LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, @@ -493,8 +510,10 @@ extern bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock); extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks); extern void LockReleaseSession(LOCKMETHODID lockmethodid); -extern void LockReleaseCurrentOwner(void); -extern void LockReassignCurrentOwner(void); +extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks); +extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks); +extern bool LockHasWaiters(const LOCKTAG *locktag, + LOCKMODE lockmode, bool sessionLock); extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode); extern void AtPrepare_Locks(void); @@ -531,7 +550,7 @@ extern void lock_twophase_standby_recover(TransactionId xid, uint16 info, extern DeadLockState DeadLockCheck(PGPROC *proc); extern PGPROC *GetBlockingAutoVacuumPgproc(void); -extern void DeadLockReport(void); +extern void DeadLockReport(void) __attribute__((noreturn)); extern void RememberSimpleDeadLock(PGPROC *proc1, LOCKMODE lockmode, LOCK *lock, @@ -545,6 +564,7 @@ extern void DumpAllLocks(void); /* Lock a VXID (used to wait for a transaction to finish) */ extern void VirtualXactLockTableInsert(VirtualTransactionId vxid); +extern void VirtualXactLockTableCleanup(void); extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait); #endif /* LOCK_H */ diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index 6634554232..30ec4452f7 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lwlock.h @@ -19,10 +19,137 @@ #ifndef LWLOCK_H #define LWLOCK_H +#include "storage/s_lock.h" + +struct PGPROC; + +/* + * It's occasionally necessary to identify a particular LWLock "by name"; e.g. + * because we wish to report the lock to dtrace. We could store a name or + * other identifying information in the lock itself, but since it's common + * to have many nearly-identical locks (e.g. one per buffer) this would end + * up wasting significant amounts of memory. Instead, each lwlock stores a + * tranche ID which tells us which array it's part of. Based on that, we can + * figure out where the lwlock lies within the array using the data structure + * shown below; the lock is then identified based on the tranche name and + * computed array index. We need the array stride because the array might not + * be an array of lwlocks, but rather some larger data structure that includes + * one or more lwlocks per element. + */ +typedef struct LWLockTranche +{ + const char *name; + void *array_base; + Size array_stride; +} LWLockTranche; + +/* + * Code outside of lwlock.c should not manipulate the contents of this + * structure directly, but we have to declare it here to allow LWLocks to be + * incorporated into other data structures. + */ +typedef struct LWLock +{ + slock_t mutex; /* Protects LWLock and queue of PGPROCs */ + bool releaseOK; /* T if ok to release waiters */ + char exclusive; /* # of exclusive holders (0 or 1) */ + int shared; /* # of shared holders (0..MaxBackends) */ + int tranche; /* tranche ID */ + struct PGPROC *head; /* head of list of waiting PGPROCs */ + struct PGPROC *tail; /* tail of list of waiting PGPROCs */ + /* tail is undefined when head is NULL */ +} LWLock; + +/* + * Prior to PostgreSQL 9.4, every lightweight lock in the system was stored + * in a single array. For convenience and for compatibility with past + * releases, we still have a main array, but it's now also permissible to + * store LWLocks elsewhere in the main shared memory segment or in a dynamic + * shared memory segment. In the main array, we force the array stride to + * be a power of 2, which saves a few cycles in indexing, but more importantly + * also ensures that individual LWLocks don't cross cache line boundaries. + * This reduces cache contention problems, especially on AMD Opterons. + * (Of course, we have to also ensure that the array start address is suitably + * aligned.) + * + * Even on a 32-bit platform, an lwlock will be more than 16 bytes, because + * it contains 2 integers and 2 pointers, plus other stuff. It should fit + * into 32 bytes, though, unless slock_t is really big. On a 64-bit platform, + * it should fit into 32 bytes unless slock_t is larger than 4 bytes. We + * allow for that just in case. + */ +#define LWLOCK_PADDED_SIZE (sizeof(LWLock) <= 32 ? 32 : 64) + +typedef union LWLockPadded +{ + LWLock lock; + char pad[LWLOCK_PADDED_SIZE]; +} LWLockPadded; +extern PGDLLIMPORT LWLockPadded *MainLWLockArray; + +/* + * Some commonly-used locks have predefined positions within MainLWLockArray; + * defining macros here makes it much easier to keep track of these. If you + * add a lock, add it to the end to avoid renumbering the existing locks; + * if you remove a lock, consider leaving a gap in the numbering sequence for + * the benefit of DTrace and other external debugging scripts. + */ +#define BufFreelistLock (&MainLWLockArray[0].lock) +#define ShmemIndexLock (&MainLWLockArray[1].lock) +#define OidGenLock (&MainLWLockArray[2].lock) +#define XidGenLock (&MainLWLockArray[3].lock) +#define ProcArrayLock (&MainLWLockArray[4].lock) +#define SInvalReadLock (&MainLWLockArray[5].lock) +#define SInvalWriteLock (&MainLWLockArray[6].lock) +#define WALBufMappingLock (&MainLWLockArray[7].lock) +#define WALWriteLock (&MainLWLockArray[8].lock) +#define ControlFileLock (&MainLWLockArray[9].lock) +#define CheckpointLock (&MainLWLockArray[10].lock) +#define CLogControlLock (&MainLWLockArray[11].lock) +#define SubtransControlLock (&MainLWLockArray[12].lock) +#define MultiXactGenLock (&MainLWLockArray[13].lock) +#define MultiXactOffsetControlLock (&MainLWLockArray[14].lock) +#define MultiXactMemberControlLock (&MainLWLockArray[15].lock) +#define RelCacheInitLock (&MainLWLockArray[16].lock) +#define CheckpointerCommLock (&MainLWLockArray[17].lock) +#define TwoPhaseStateLock (&MainLWLockArray[18].lock) +#define TablespaceCreateLock (&MainLWLockArray[19].lock) +#define BtreeVacuumLock (&MainLWLockArray[20].lock) +#define AddinShmemInitLock (&MainLWLockArray[21].lock) +#define AutovacuumLock (&MainLWLockArray[22].lock) +#define AutovacuumScheduleLock (&MainLWLockArray[23].lock) +#define SyncScanLock (&MainLWLockArray[24].lock) +#define RelationMappingLock (&MainLWLockArray[25].lock) +#define AsyncCtlLock (&MainLWLockArray[26].lock) +#define AsyncQueueLock (&MainLWLockArray[27].lock) +#define SerializableXactHashLock (&MainLWLockArray[28].lock) +#define SerializableFinishedListLock (&MainLWLockArray[29].lock) +#define SerializablePredicateLockListLock (&MainLWLockArray[30].lock) +#define OldSerXidLock (&MainLWLockArray[31].lock) +#define SyncRepLock (&MainLWLockArray[32].lock) +#define BackgroundWorkerLock (&MainLWLockArray[33].lock) +#define DynamicSharedMemoryControlLock (&MainLWLockArray[34].lock) +#define AutoFileLock (&MainLWLockArray[35].lock) +#define ReplicationSlotAllocationLock (&MainLWLockArray[36].lock) +#define ReplicationSlotControlLock (&MainLWLockArray[37].lock) +#ifdef PGXC +#define BarrierLock (&MainLWLockArray[38].lock) +#define NodeTableLock (&MainLWLockArray[39].lock) +#endif +#ifdef XCP +#define SQueuesLock (&MainLWLockArray[40].lock) +#endif + +#ifdef PGXC +#define NUM_INDIVIDUAL_LWLOCKS 41 +#else +#define NUM_INDIVIDUAL_LWLOCKS 38 +#endif + /* * It's a bit odd to declare NUM_BUFFER_PARTITIONS and NUM_LOCK_PARTITIONS - * here, but we need them to set up enum LWLockId correctly, and having - * this file include lock.h or bufmgr.h would be backwards. + * here, but we need them to figure out offsets within MainLWLockArray, and + * having this file include lock.h or bufmgr.h would be backwards. */ /* Number of partitions of the shared buffer mapping hashtable */ @@ -36,72 +163,14 @@ #define LOG2_NUM_PREDICATELOCK_PARTITIONS 4 #define NUM_PREDICATELOCK_PARTITIONS (1 << LOG2_NUM_PREDICATELOCK_PARTITIONS) -/* - * We have a number of predefined LWLocks, plus a bunch of LWLocks that are - * dynamically assigned (e.g., for shared buffers). The LWLock structures - * live in shared memory (since they contain shared data) and are identified - * by values of this enumerated type. We abuse the notion of an enum somewhat - * by allowing values not listed in the enum declaration to be assigned. - * The extra value MaxDynamicLWLock is there to keep the compiler from - * deciding that the enum can be represented as char or short ... - * - * If you remove a lock, please replace it with a placeholder. This retains - * the lock numbering, which is helpful for DTrace and other external - * debugging scripts. - */ -typedef enum LWLockId -{ - BufFreelistLock, - ShmemIndexLock, - OidGenLock, - XidGenLock, - ProcArrayLock, - SInvalReadLock, - SInvalWriteLock, - WALInsertLock, - WALWriteLock, - ControlFileLock, - CheckpointLock, - CLogControlLock, - SubtransControlLock, - MultiXactGenLock, - MultiXactOffsetControlLock, - MultiXactMemberControlLock, - RelCacheInitLock, - CheckpointerCommLock, - TwoPhaseStateLock, - TablespaceCreateLock, - BtreeVacuumLock, - AddinShmemInitLock, - AutovacuumLock, - AutovacuumScheduleLock, - SyncScanLock, -#ifdef PGXC - BarrierLock, - NodeTableLock, -#endif -#ifdef XCP - SQueuesLock, -#endif - RelationMappingLock, - AsyncCtlLock, - AsyncQueueLock, - SerializableXactHashLock, - SerializableFinishedListLock, - SerializablePredicateLockListLock, - OldSerXidLock, - SyncRepLock, - /* Individual lock IDs end here */ - FirstBufMappingLock, - FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS, - FirstPredicateLockMgrLock = FirstLockMgrLock + NUM_LOCK_PARTITIONS, - - /* must be last except for MaxDynamicLWLock: */ - NumFixedLWLocks = FirstPredicateLockMgrLock + NUM_PREDICATELOCK_PARTITIONS, - - MaxDynamicLWLock = 1000000000 -} LWLockId; - +/* Offsets for various chunks of preallocated lwlocks. */ +#define BUFFER_MAPPING_LWLOCK_OFFSET NUM_INDIVIDUAL_LWLOCKS +#define LOCK_MANAGER_LWLOCK_OFFSET \ + (BUFFER_MAPPING_LWLOCK_OFFSET + NUM_BUFFER_PARTITIONS) +#define PREDICATELOCK_MANAGER_LWLOCK_OFFSET \ + (NUM_INDIVIDUAL_LWLOCKS + NUM_LOCK_PARTITIONS) +#define NUM_FIXED_LWLOCKS \ + (PREDICATELOCK_MANAGER_LWLOCK_OFFSET + NUM_PREDICATELOCK_PARTITIONS) typedef enum LWLockMode { @@ -117,18 +186,51 @@ typedef enum LWLockMode extern bool Trace_lwlocks; #endif -extern LWLockId LWLockAssign(void); -extern void LWLockAcquire(LWLockId lockid, LWLockMode mode); -extern bool LWLockConditionalAcquire(LWLockId lockid, LWLockMode mode); -extern bool LWLockAcquireOrWait(LWLockId lockid, LWLockMode mode); -extern void LWLockRelease(LWLockId lockid); +extern bool LWLockAcquire(LWLock *lock, LWLockMode mode); +extern bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode); +extern bool LWLockAcquireOrWait(LWLock *lock, LWLockMode mode); +extern void LWLockRelease(LWLock *lock); extern void LWLockReleaseAll(void); -extern bool LWLockHeldByMe(LWLockId lockid); +extern bool LWLockHeldByMe(LWLock *lock); + +extern bool LWLockAcquireWithVar(LWLock *lock, uint64 *valptr, uint64 val); +extern bool LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval); +extern void LWLockUpdateVar(LWLock *lock, uint64 *valptr, uint64 value); -extern int NumLWLocks(void); extern Size LWLockShmemSize(void); extern void CreateLWLocks(void); +/* + * The traditional method for obtaining an lwlock for use by an extension is + * to call RequestAddinLWLocks() during postmaster startup; this will reserve + * space for the indicated number of locks in MainLWLockArray. Subsequently, + * a lock can be allocated using LWLockAssign. + */ extern void RequestAddinLWLocks(int n); +extern LWLock *LWLockAssign(void); + +/* + * There is another, more flexible method of obtaining lwlocks. First, call + * LWLockNewTrancheId just once to obtain a tranche ID; this allocates from + * a shared counter. Next, each individual process using the tranche should + * call LWLockRegisterTranche() to associate that tranche ID with appropriate + * metadata. Finally, LWLockInitialize should be called just once per lwlock, + * passing the tranche ID as an argument. + * + * It may seem strange that each process using the tranche must register it + * separately, but dynamic shared memory segments aren't guaranteed to be + * mapped at the same address in all coordinating backends, so storing the + * registration in the main shared memory segment wouldn't work for that case. + */ +extern int LWLockNewTrancheId(void); +extern void LWLockRegisterTranche(int, LWLockTranche *); +extern void LWLockInitialize(LWLock *, int tranche_id); + +/* + * Prior to PostgreSQL 9.4, we used an enum type called LWLockId to refer + * to LWLocks. New code should instead use LWLock *. However, for the + * convenience of third-party code, we include the following typedef. + */ +typedef LWLock *LWLockId; #endif /* LWLOCK_H */ diff --git a/src/include/storage/off.h b/src/include/storage/off.h index 4aa0177d1a..80d2b77d2d 100644 --- a/src/include/storage/off.h +++ b/src/include/storage/off.h @@ -4,7 +4,7 @@ * POSTGRES disk "offset" definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/off.h diff --git a/src/include/storage/pg_sema.h b/src/include/storage/pg_sema.h index 4c9bc9d6bc..c53aa9795b 100644 --- a/src/include/storage/pg_sema.h +++ b/src/include/storage/pg_sema.h @@ -6,11 +6,11 @@ * PostgreSQL requires counting semaphores (the kind that keep track of * multiple unlock operations, and will allow an equal number of subsequent * lock operations before blocking). The underlying implementation is - * not the same on every platform. This file defines the API that must + * not the same on every platform. This file defines the API that must * be provided by each port. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pg_sema.h diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 7b55c20d09..76bba445bd 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -10,11 +10,11 @@ * * To simplify life for the SysV implementation, the ID is assumed to * consist of two unsigned long values (these are key and ID in SysV - * terms). Other platforms may ignore the second value if they need + * terms). Other platforms may ignore the second value if they need * only one ID number. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pg_shmem.h @@ -24,6 +24,8 @@ #ifndef PG_SHMEM_H #define PG_SHMEM_H +#include "storage/dsm_impl.h" + typedef struct PGShmemHeader /* standard header for all Postgres shmem */ { int32 magic; /* magic # to identify Postgres segments */ @@ -31,6 +33,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ pid_t creatorPID; /* PID of creating process */ Size totalsize; /* total size of segment */ Size freeoffset; /* offset to first free space */ + dsm_handle dsm_control; /* ID of dynamic shared memory control seg */ void *index; /* pointer to ShmemIndex table */ #ifndef WIN32 /* Windows doesn't have useful inode#s */ dev_t device; /* device data directory is on */ @@ -38,8 +41,17 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ #endif } PGShmemHeader; +/* GUC variable */ +extern int huge_pages; + +/* Possible values for huge_pages */ +typedef enum +{ + HUGE_PAGES_OFF, + HUGE_PAGES_ON, + HUGE_PAGES_TRY +} HugePagesType; -#ifdef EXEC_BACKEND #ifndef WIN32 extern unsigned long UsedShmemSegID; #else @@ -47,11 +59,12 @@ extern HANDLE UsedShmemSegID; #endif extern void *UsedShmemSegAddr; +#ifdef EXEC_BACKEND extern void PGSharedMemoryReAttach(void); #endif extern PGShmemHeader *PGSharedMemoryCreate(Size size, bool makePrivate, - int port); + int port, PGShmemHeader **shim); extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); extern void PGSharedMemoryDetach(void); diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h index 9e295ca509..c74d251c5f 100644 --- a/src/include/storage/pmsignal.h +++ b/src/include/storage/pmsignal.h @@ -4,7 +4,7 @@ * routines for signaling the postmaster from its child processes * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pmsignal.h @@ -28,6 +28,7 @@ typedef enum PMSIGNAL_ROTATE_LOGFILE, /* send SIGUSR1 to syslogger to rotate logfile */ PMSIGNAL_START_AUTOVAC_LAUNCHER, /* start an autovacuum launcher */ PMSIGNAL_START_AUTOVAC_WORKER, /* start an autovacuum worker */ + PMSIGNAL_BACKGROUND_WORKER_CHANGE, /* background worker state change */ PMSIGNAL_START_WALRECEIVER, /* start a walreceiver */ PMSIGNAL_ADVANCE_STATE_MACHINE, /* advance postmaster's state machine */ diff --git a/src/include/storage/pos.h b/src/include/storage/pos.h index aa4e9a6bca..662a717e3c 100644 --- a/src/include/storage/pos.h +++ b/src/include/storage/pos.h @@ -4,7 +4,7 @@ * POSTGRES "position" definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pos.h @@ -20,7 +20,7 @@ * been changed to just <offset> as the notion of having multiple pages * within a block has been removed. * - * the 'offset' abstraction is somewhat confusing. it is NOT a byte + * the 'offset' abstraction is somewhat confusing. it is NOT a byte * offset within the page; instead, it is an offset into the line * pointer array contained on every page that store (heap or index) * tuples. diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h index 7ec79e077d..8a6bc290bc 100644 --- a/src/include/storage/predicate.h +++ b/src/include/storage/predicate.h @@ -4,7 +4,7 @@ * POSTGRES public predicate locking definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/predicate.h diff --git a/src/include/storage/predicate_internals.h b/src/include/storage/predicate_internals.h index 4ddb3494c5..afbd782a21 100644 --- a/src/include/storage/predicate_internals.h +++ b/src/include/storage/predicate_internals.h @@ -4,7 +4,7 @@ * POSTGRES internal predicate locking definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/predicate_internals.h @@ -128,7 +128,7 @@ typedef struct SERIALIZABLEXACT * The following types are used to provide an ad hoc list for holding * SERIALIZABLEXACT objects. An HTAB is overkill, since there is no need to * access these by key -- there are direct pointers to these objects where - * needed. If a shared memory list is created, these types can probably be + * needed. If a shared memory list is created, these types can probably be * eliminated in favor of using the general solution. */ typedef struct PredXactListElementData @@ -254,10 +254,10 @@ typedef struct SERIALIZABLEXID * be the target of predicate locks. * * Note that the hash function being used doesn't properly respect tag - * length -- it will go to a four byte boundary past the end of the tag. - * If you change this struct, make sure any slack space is initialized, - * so that any random bytes in the middle or at the end are not included - * in the hash. + * length -- if the length of the structure isn't a multiple of four bytes it + * will go to a four byte boundary past the end of the tag. If you change + * this struct, make sure any slack space is initialized, so that any random + * bytes in the middle or at the end are not included in the hash. * * TODO SSI: If we always use the same fields for the same type of value, we * should rename these. Holding off until it's clear there are no exceptions. @@ -272,7 +272,6 @@ typedef struct PREDICATELOCKTARGETTAG uint32 locktag_field2; /* a 32-bit ID field */ uint32 locktag_field3; /* a 32-bit ID field */ uint32 locktag_field4; /* a 32-bit ID field */ - uint32 locktag_field5; /* a 32-bit ID field */ } PREDICATELOCKTARGETTAG; /* @@ -283,12 +282,6 @@ typedef struct PREDICATELOCKTARGETTAG * added when a predicate lock is requested on an object which doesn't * already have one. An entry is removed when the last lock is removed from * its list. - * - * Because a particular target might become obsolete, due to update to a new - * version, before the reading transaction is obsolete, we need some way to - * prevent errors from reuse of a tuple ID. Rather than attempting to clean - * up the targets as the related tuples are pruned or vacuumed, we check the - * xmin on access. This should be far less costly. */ typedef struct PREDICATELOCKTARGET { @@ -318,9 +311,9 @@ typedef struct PREDICATELOCKTAG * The PREDICATELOCK struct represents an individual lock. * * An entry can be created here when the related database object is read, or - * by promotion of multiple finer-grained targets. All entries related to a + * by promotion of multiple finer-grained targets. All entries related to a * serializable transaction are removed when that serializable transaction is - * cleaned up. Entries can also be removed when they are combined into a + * cleaned up. Entries can also be removed when they are combined into a * single coarser-grained lock entry. */ typedef struct PREDICATELOCK @@ -391,29 +384,26 @@ typedef struct PredicateLockData /* * These macros define how we map logical IDs of lockable objects into the - * physical fields of PREDICATELOCKTARGETTAG. Use these to set up values, + * physical fields of PREDICATELOCKTARGETTAG. Use these to set up values, * rather than accessing the fields directly. Note multiple eval of target! */ #define SET_PREDICATELOCKTARGETTAG_RELATION(locktag,dboid,reloid) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ (locktag).locktag_field3 = InvalidBlockNumber, \ - (locktag).locktag_field4 = InvalidOffsetNumber, \ - (locktag).locktag_field5 = InvalidTransactionId) + (locktag).locktag_field4 = InvalidOffsetNumber) #define SET_PREDICATELOCKTARGETTAG_PAGE(locktag,dboid,reloid,blocknum) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ (locktag).locktag_field3 = (blocknum), \ - (locktag).locktag_field4 = InvalidOffsetNumber, \ - (locktag).locktag_field5 = InvalidTransactionId) + (locktag).locktag_field4 = InvalidOffsetNumber) -#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum,xmin) \ +#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ (locktag).locktag_field3 = (blocknum), \ - (locktag).locktag_field4 = (offnum), \ - (locktag).locktag_field5 = (xmin)) + (locktag).locktag_field4 = (offnum)) #define GET_PREDICATELOCKTARGETTAG_DB(locktag) \ ((Oid) (locktag).locktag_field1) @@ -423,8 +413,6 @@ typedef struct PredicateLockData ((BlockNumber) (locktag).locktag_field3) #define GET_PREDICATELOCKTARGETTAG_OFFSET(locktag) \ ((OffsetNumber) (locktag).locktag_field4) -#define GET_PREDICATELOCKTARGETTAG_XMIN(locktag) \ - ((TransactionId) (locktag).locktag_field5) #define GET_PREDICATELOCKTARGETTAG_TYPE(locktag) \ (((locktag).locktag_field4 != InvalidOffsetNumber) ? PREDLOCKTAG_TUPLE : \ (((locktag).locktag_field3 != InvalidBlockNumber) ? PREDLOCKTAG_PAGE : \ @@ -462,6 +450,7 @@ typedef struct TwoPhasePredicateXactRecord typedef struct TwoPhasePredicateLockRecord { PREDICATELOCKTARGETTAG target; + uint32 filler; /* to avoid length change in back-patched fix */ } TwoPhasePredicateLockRecord; typedef struct TwoPhasePredicateRecord @@ -486,5 +475,4 @@ typedef struct TwoPhasePredicateRecord */ extern PredicateLockData *GetPredicateLockStatusData(void); - #endif /* PREDICATE_INTERNALS_H */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 8d861a6cfd..51275f99e8 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/proc.h @@ -19,15 +19,14 @@ #ifndef _PROC_H_ #define _PROC_H_ -#include "access/xlog.h" -#include "datatype/timestamp.h" +#include "access/xlogdefs.h" #include "storage/latch.h" #include "storage/lock.h" #include "storage/pg_sema.h" /* * Each backend advertises up to PGPROC_MAX_CACHED_SUBXIDS TransactionIds - * for non-aborted subtransactions of its current top transaction. These + * for non-aborted subtransactions of its current top transaction. These * have to be treated as running XIDs by other backends. * * We also keep track of whether the cache overflowed (ie, the transaction has @@ -47,10 +46,13 @@ struct XidCache #define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ #define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ #define PROC_IN_ANALYZE 0x04 /* currently running analyze */ -#define PROC_VACUUM_FOR_WRAPAROUND 0x08 /* set by autovac only */ +#define PROC_VACUUM_FOR_WRAPAROUND 0x08 /* set by autovac only */ +#define PROC_IN_LOGICAL_DECODING 0x10 /* currently doing logical + * decoding */ /* flags reset at EOXact */ -#define PROC_VACUUM_STATE_MASK (0x0E) +#define PROC_VACUUM_STATE_MASK \ + (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND) /* * We allow a small number of "weak" relation locks (AccesShareLock, @@ -64,7 +66,7 @@ struct XidCache * Each backend has a PGPROC struct in shared memory. There is also a list of * currently-unused PGPROC structs that will be reallocated to new backends. * - * links: list link for any list the PGPROC is in. When waiting for a lock, + * links: list link for any list the PGPROC is in. When waiting for a lock, * the PGPROC is linked into that lock's waitProcs queue. A recycled PGPROC * is linked into ProcGlobal's freeProcs list. * @@ -147,8 +149,8 @@ struct PGPROC struct XidCache subxids; /* cache for subtransaction XIDs */ - /* Per-backend LWLock. Protects fields below. */ - LWLockId backendLock; /* protects the fields below */ + /* Per-backend LWLock. Protects fields below. */ + LWLock *backendLock; /* protects the fields below */ /* Lock manager data, recording fast-path locks taken by this backend. */ uint64 fpLockBits; /* lock modes held for each fast-path slot */ @@ -166,7 +168,7 @@ extern PGDLLIMPORT struct PGXACT *MyPgXact; /* * Prior to PostgreSQL 9.2, the fields below were stored as part of the - * PGPROC. However, benchmarking revealed that packing these particular + * PGPROC. However, benchmarking revealed that packing these particular * members into a separate array as tightly as possible sped up GetSnapshotData * considerably on systems with many CPU cores, by reducing the number of * cache lines needing to be fetched. Thus, think very carefully before adding @@ -185,7 +187,8 @@ typedef struct PGXACT uint8 vacuumFlags; /* vacuum-related flags, see above */ bool overflowed; - bool inCommit; /* true if within commit critical section */ + bool delayChkpt; /* true if this proc delays checkpoint start; + * previously called InCommit */ uint8 nxids; } PGXACT; @@ -205,6 +208,8 @@ typedef struct PROC_HDR PGPROC *freeProcs; /* Head of list of autovacuum's free PGPROC structures */ PGPROC *autovacFreeProcs; + /* Head of list of bgworker free PGPROC structures */ + PGPROC *bgworkerFreeProcs; /* WALWriter process's latch */ Latch *walwriterLatch; /* Checkpointer process's latch */ @@ -242,10 +247,9 @@ extern PGPROC *PreparedXactProcs; /* configurable options */ extern int DeadlockTimeout; extern int StatementTimeout; +extern int LockTimeout; extern bool log_lock_waits; -extern volatile bool cancel_from_timeout; - /* * Function Prototypes @@ -268,19 +272,11 @@ extern void ProcQueueInit(PROC_QUEUE *queue); extern int ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable); extern PGPROC *ProcWakeup(PGPROC *proc, int waitStatus); extern void ProcLockWakeup(LockMethod lockMethodTable, LOCK *lock); +extern void CheckDeadLock(void); extern bool IsWaitingForLock(void); extern void LockErrorCleanup(void); extern void ProcWaitForSignal(void); extern void ProcSendSignal(int pid); -extern bool enable_sig_alarm(int delayms, bool is_statement_timeout); -extern bool disable_sig_alarm(bool is_statement_timeout); -extern void handle_sig_alarm(SIGNAL_ARGS); - -extern bool enable_standby_sig_alarm(TimestampTz now, - TimestampTz fin_time, bool deadlock_only); -extern bool disable_standby_sig_alarm(void); -extern void handle_standby_sig_alarm(SIGNAL_ARGS); - #endif /* PROC_H */ diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 6bf0d0cc18..9bfc8f68df 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -21,6 +21,7 @@ #define PROCARRAY_H #include "storage/standby.h" +#include "utils/relcache.h" #include "utils/snapshot.h" @@ -47,6 +48,7 @@ extern void SetGlobalSnapshotData(TransactionId xmin, TransactionId xmax, int xc extern void UnsetGlobalSnapshotData(void); extern void ReloadConnInfoOnBackends(void); #endif /* PGXC */ +extern void ProcArrayInitRecovery(TransactionId initializedUptoXID); extern void ProcArrayApplyRecoveryInfo(RunningTransactions running); extern void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids); @@ -70,11 +72,12 @@ extern RunningTransactions GetRunningTransactionData(void); extern bool TransactionIdIsInProgress(TransactionId xid); extern bool TransactionIdIsActive(TransactionId xid); -extern TransactionId GetOldestXmin(bool allDbs, bool ignoreVacuum); +extern TransactionId GetOldestXmin(Relation rel, bool ignoreVacuum); extern TransactionId GetOldestActiveTransactionId(void); +extern TransactionId GetOldestSafeDecodingTransactionId(void); -extern int GetTransactionsInCommit(TransactionId **xids_p); -extern bool HaveTransactionsInCommit(TransactionId *xids, int nxids); +extern VirtualTransactionId *GetVirtualXIDsDelayingChkpt(int *nvxids); +extern bool HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids); extern PGPROC *BackendPidGetProc(int pid); extern int BackendXidGetPid(TransactionId xid); @@ -100,4 +103,11 @@ extern void XidCacheRemoveRunningXids(TransactionId xid, extern void GetGlobalSessionInfo(int pid, Oid *coordId, int *coordPid); extern int GetFirstBackendId(int *numBackends, int *backends); #endif /* XCP */ + +extern void ProcArraySetReplicationSlotXmin(TransactionId xmin, + TransactionId catalog_xmin, bool already_locked); + +extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin, + TransactionId *catalog_xmin); + #endif /* PROCARRAY_H */ diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h index c0127d4f25..8c94bc10fd 100644 --- a/src/include/storage/procsignal.h +++ b/src/include/storage/procsignal.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/procsignal.h @@ -71,5 +71,6 @@ extern int SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId); extern void procsignal_sigusr1_handler(SIGNAL_ARGS); +extern PGDLLIMPORT bool set_latch_on_sigusr1; #endif /* PROCSIGNAL_H */ diff --git a/src/include/storage/reinit.h b/src/include/storage/reinit.h index 627ea06803..4049d7f15d 100644 --- a/src/include/storage/reinit.h +++ b/src/include/storage/reinit.h @@ -4,7 +4,7 @@ * Reinitialization of unlogged relations * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/fd.h diff --git a/src/include/storage/relfilenode.h b/src/include/storage/relfilenode.h index f6f015ea05..c75a5b727b 100644 --- a/src/include/storage/relfilenode.h +++ b/src/include/storage/relfilenode.h @@ -4,7 +4,7 @@ * Physical access information for relations. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/relfilenode.h @@ -14,31 +14,10 @@ #ifndef RELFILENODE_H #define RELFILENODE_H +#include "common/relpath.h" #include "storage/backendid.h" /* - * The physical storage of a relation consists of one or more forks. The - * main fork is always created, but in addition to that there can be - * additional forks for storing various metadata. ForkNumber is used when - * we need to refer to a specific fork in a relation. - */ -typedef enum ForkNumber -{ - InvalidForkNumber = -1, - MAIN_FORKNUM = 0, - FSM_FORKNUM, - VISIBILITYMAP_FORKNUM, - INIT_FORKNUM - - /* - * NOTE: if you add a new fork, change MAX_FORKNUM below and update the - * forkNames array in catalog.c - */ -} ForkNumber; - -#define MAX_FORKNUM INIT_FORKNUM - -/* * RelFileNode must provide all that we need to know to physically access * a relation, with the exception of the backend ID, which can be provided * separately. Note, however, that a "physical" relation is comprised of @@ -48,14 +27,15 @@ typedef enum ForkNumber * spcNode identifies the tablespace of the relation. It corresponds to * pg_tablespace.oid. * - * dbNode identifies the database of the relation. It is zero for + * dbNode identifies the database of the relation. It is zero for * "shared" relations (those common to all databases of a cluster). * Nonzero dbNode values correspond to pg_database.oid. * * relNode identifies the specific relation. relNode corresponds to * pg_class.relfilenode (NOT pg_class.oid, because we need to be able * to assign new physical files to relations in some situations). - * Notice that relNode is only unique within a particular database. + * Notice that relNode is only unique within a database in a particular + * tablespace. * * Note: spcNode must be GLOBALTABLESPACE_OID if and only if dbNode is * zero. We support shared relations only in the "global" tablespace. @@ -69,6 +49,10 @@ typedef enum ForkNumber * Note: in pg_class, relfilenode can be zero to denote that the relation * is a "mapped" relation, whose current true filenode number is available * from relmapper.c. Again, this case is NOT allowed in RelFileNodes. + * + * Note: various places use RelFileNode in hashtable keys. Therefore, + * there *must not* be any unused padding bytes in this struct. That + * should be safe as long as all the fields are of type Oid. */ typedef struct RelFileNode { @@ -79,7 +63,11 @@ typedef struct RelFileNode /* * Augmenting a relfilenode with the backend ID provides all the information - * we need to locate the physical storage. + * we need to locate the physical storage. The backend ID is InvalidBackendId + * for regular relations (those accessible to more than one backend), or the + * owning backend's ID for backend-local relations. Backend-local relations + * are always transient and removed in case of a database crash; they are + * never WAL-logged or fsync'd. */ typedef struct RelFileNodeBackend { @@ -87,14 +75,20 @@ typedef struct RelFileNodeBackend BackendId backend; } RelFileNodeBackend; +#ifdef XCP #define RelFileNodeBackendIsTemp(rnode) \ (!OidIsValid(MyCoordId) && ((rnode).backend != InvalidBackendId)) +#else +#define RelFileNodeBackendIsTemp(rnode) \ + ((rnode).backend != InvalidBackendId) +#endif /* * Note: RelFileNodeEquals and RelFileNodeBackendEquals compare relNode first * since that is most likely to be different in two unequal RelFileNodes. It * is probably redundant to compare spcNode if the other fields are found equal, - * but do it anyway to be sure. + * but do it anyway to be sure. Likewise for checking the backend ID in + * RelFileNodeBackendEquals. */ #define RelFileNodeEquals(node1, node2) \ ((node1).relNode == (node2).relNode && \ diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index d4a783f63d..ba4dfe12d8 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -12,10 +12,11 @@ * void S_INIT_LOCK(slock_t *lock) * Initialize a spinlock (to the unlocked state). * - * void S_LOCK(slock_t *lock) + * int S_LOCK(slock_t *lock) * Acquire a spinlock, waiting if necessary. * Time out and abort() if unable to acquire the lock in a * "reasonable" amount of time --- typically ~ 1 minute. + * Should return number of "delays"; see s_lock.c * * void S_UNLOCK(slock_t *lock) * Unlock a previously acquired lock. @@ -83,7 +84,7 @@ * when using the SysV semaphore code. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/s_lock.h @@ -93,11 +94,8 @@ #ifndef S_LOCK_H #define S_LOCK_H -#include "storage/pg_sema.h" - #ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ - #if defined(__GNUC__) || defined(__INTEL_COMPILER) /************************************************************************* * All the gcc inlines @@ -144,6 +142,12 @@ tas(volatile slock_t *lock) * Use a non-locking test before asserting the bus lock. Note that the * extra test appears to be a small loss on some x86 platforms and a small * win on others; it's by no means clear that we should keep it. + * + * When this was last tested, we didn't have separate TAS() and TAS_SPIN() + * macros. Nowadays it probably would be better to do a non-locking test + * in TAS_SPIN() but not in TAS(), like on x86_64, but no-one's done the + * testing to verify that. Without some empirical evidence, better to + * leave it alone. */ __asm__ __volatile__( " cmpb $0,%1 \n" @@ -199,16 +203,22 @@ typedef unsigned char slock_t; #define TAS(lock) tas(lock) +/* + * On Intel EM64T, it's a win to use a non-locking test before the xchg proper, + * but only when spinning. + * + * See also Implementing Scalable Atomic Locks for Multi-Core Intel(tm) EM64T + * and IA32, by Michael Chynoweth and Mary R. Lee. As of this writing, it is + * available at: + * http://software.intel.com/en-us/articles/implementing-scalable-atomic-locks-for-multi-core-intel-em64t-and-ia32-architectures + */ +#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock)) + static __inline__ int tas(volatile slock_t *lock) { register slock_t _res = 1; - /* - * On Opteron, using a non-locking test before the locking instruction - * is a huge loss. On EM64T, it appears to be a wash or small loss, - * so we needn't bother to try to distinguish the sub-architectures. - */ __asm__ __volatile__( " lock \n" " xchgb %0,%1 \n" @@ -335,6 +345,29 @@ tas(volatile slock_t *lock) #endif /* __arm__ */ +/* + * On ARM64, we use __sync_lock_test_and_set(int *, int) if available. + */ +#if defined(__aarch64__) || defined(__aarch64) +#ifdef HAVE_GCC_INT_ATOMICS +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#endif /* HAVE_GCC_INT_ATOMICS */ +#endif /* __aarch64__ */ + + /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET @@ -515,31 +548,6 @@ tas(volatile slock_t *lock) #endif /* __vax__ */ - -#if defined(__ns32k__) /* National Semiconductor 32K */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; - -#define TAS(lock) tas(lock) - -static __inline__ int -tas(volatile slock_t *lock) -{ - register int _res; - - __asm__ __volatile__( - " sbitb 0, %1 \n" - " sfsd %0 \n" -: "=r"(_res), "+m"(*lock) -: -: "memory"); - return _res; -} - -#endif /* __ns32k__ */ - - #if defined(__alpha) || defined(__alpha__) /* Alpha */ /* * Correct multi-processor locking methods are explained in section 5.5.3 @@ -825,50 +833,6 @@ typedef unsigned int slock_t; #endif /* HPUX on IA64, non gcc */ - -#if defined(__sgi) /* SGI compiler */ -/* - * SGI IRIX 5 - * slock_t is defined as a unsigned long. We use the standard SGI - * mutex API. - * - * The following comment is left for historical reasons, but is probably - * not a good idea since the mutex ABI is supported. - * - * This stuff may be supplemented in the future with Masato Kataoka's MIPS-II - * assembly from his NECEWS SVR4 port, but we probably ought to retain this - * for the R3000 chips out there. - */ -#define HAS_TEST_AND_SET - -typedef unsigned long slock_t; - -#include "mutex.h" -#define TAS(lock) (test_and_set(lock,1)) -#define S_UNLOCK(lock) (test_then_and(lock,0)) -#define S_INIT_LOCK(lock) (test_then_and(lock,0)) -#define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0) -#endif /* __sgi */ - - -#if defined(sinix) /* Sinix */ -/* - * SINIX / Reliant UNIX - * slock_t is defined as a struct abilock_t, which has a single unsigned long - * member. (Basically same as SGI) - */ -#define HAS_TEST_AND_SET - -#include "abi_mutex.h" -typedef abilock_t slock_t; - -#define TAS(lock) (!acquire_lock(lock)) -#define S_UNLOCK(lock) release_lock(lock) -#define S_INIT_LOCK(lock) init_lock(lock) -#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED) -#endif /* sinix */ - - #if defined(_AIX) /* AIX */ /* * AIX (POWER) @@ -886,14 +850,6 @@ typedef int slock_t; /* These are in s_lock.c */ - -#if defined(sun3) /* Sun3 */ -#define HAS_TEST_AND_SET - -typedef unsigned char slock_t; -#endif - - #if defined(__SUNPRO_C) && (defined(__i386) || defined(__x86_64__) || defined(__sparc__) || defined(__sparc)) #define HAS_TEST_AND_SET @@ -956,7 +912,7 @@ spin_delay(void) * to fall foul of kernel limits on number of semaphores, so don't use this * unless you must! The subroutines appear in spin.c. */ -typedef PGSemaphoreData slock_t; +typedef int slock_t; extern bool s_lock_free_sema(volatile slock_t *lock); extern void s_unlock_sema(volatile slock_t *lock); @@ -978,10 +934,7 @@ extern int tas_sema(volatile slock_t *lock); #if !defined(S_LOCK) #define S_LOCK(lock) \ - do { \ - if (TAS(lock)) \ - s_lock((lock), __FILE__, __LINE__); \ - } while (0) + (TAS(lock) ? s_lock((lock), __FILE__, __LINE__) : 0) #endif /* S_LOCK */ #if !defined(S_LOCK_FREE) @@ -1015,7 +968,7 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or /* * Platform-independent out-of-line support routines */ -extern void s_lock(volatile slock_t *lock, const char *file, int line); +extern int s_lock(volatile slock_t *lock, const char *file, int line); /* Support for dynamic adjustment of spins_per_delay */ #define DEFAULT_SPINS_PER_DELAY 100 diff --git a/src/include/storage/shm_mq.h b/src/include/storage/shm_mq.h new file mode 100644 index 0000000000..5bae3807af --- /dev/null +++ b/src/include/storage/shm_mq.h @@ -0,0 +1,70 @@ +/*------------------------------------------------------------------------- + * + * shm_mq.h + * single-reader, single-writer shared memory message queue + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/shm_mq.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHM_MQ_H +#define SHM_MQ_H + +#include "postmaster/bgworker.h" +#include "storage/dsm.h" +#include "storage/proc.h" + +/* The queue itself, in shared memory. */ +struct shm_mq; +typedef struct shm_mq shm_mq; + +/* Backend-private state. */ +struct shm_mq_handle; +typedef struct shm_mq_handle shm_mq_handle; + +/* Possible results of a send or receive operation. */ +typedef enum +{ + SHM_MQ_SUCCESS, /* Sent or received a message. */ + SHM_MQ_WOULD_BLOCK, /* Not completed; retry later. */ + SHM_MQ_DETACHED /* Other process has detached queue. */ +} shm_mq_result; + +/* + * Primitives to create a queue and set the sender and receiver. + * + * Both the sender and the receiver must be set before any messages are read + * or written, but they need not be set by the same process. Each must be + * set exactly once. + */ +extern shm_mq *shm_mq_create(void *address, Size size); +extern void shm_mq_set_receiver(shm_mq *mq, PGPROC *); +extern void shm_mq_set_sender(shm_mq *mq, PGPROC *); + +/* Accessor methods for sender and receiver. */ +extern PGPROC *shm_mq_get_receiver(shm_mq *); +extern PGPROC *shm_mq_get_sender(shm_mq *); + +/* Set up backend-local queue state. */ +extern shm_mq_handle *shm_mq_attach(shm_mq *mq, dsm_segment *seg, + BackgroundWorkerHandle *handle); + +/* Break connection. */ +extern void shm_mq_detach(shm_mq *); + +/* Send or receive messages. */ +extern shm_mq_result shm_mq_send(shm_mq_handle *mqh, + Size nbytes, void *data, bool nowait); +extern shm_mq_result shm_mq_receive(shm_mq_handle *mqh, + Size *nbytesp, void **datap, bool nowait); + +/* Wait for our counterparty to attach to the queue. */ +extern shm_mq_result shm_mq_wait_for_attach(shm_mq_handle *mqh); + +/* Smallest possible queue. */ +extern PGDLLIMPORT const Size shm_mq_minimum_size; + +#endif /* SHM_MQ_H */ diff --git a/src/include/storage/shm_toc.h b/src/include/storage/shm_toc.h new file mode 100644 index 0000000000..6f0804aeef --- /dev/null +++ b/src/include/storage/shm_toc.h @@ -0,0 +1,57 @@ +/*------------------------------------------------------------------------- + * + * shm_toc.h + * shared memory segment table of contents + * + * This is intended to provide a simple way to divide a chunk of shared + * memory (probably dynamic shared memory allocated via dsm_create) into + * a number of regions and keep track of the addreses of those regions or + * key data structures within those regions. This is not intended to + * scale to a large number of keys and will perform poorly if used that + * way; if you need a large number of pointers, store them within some + * other data structure within the segment and only put the pointer to + * the data structure itself in the table of contents. + * + * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/shm_toc.h + * + *------------------------------------------------------------------------- + */ +#ifndef SHM_TOC_H +#define SHM_TOC_H + +#include "storage/shmem.h" + +struct shm_toc; +typedef struct shm_toc shm_toc; + +extern shm_toc *shm_toc_create(uint64 magic, void *address, Size nbytes); +extern shm_toc *shm_toc_attach(uint64 magic, void *address); +extern void *shm_toc_allocate(shm_toc *toc, Size nbytes); +extern Size shm_toc_freespace(shm_toc *toc); +extern void shm_toc_insert(shm_toc *toc, uint64 key, void *address); +extern void *shm_toc_lookup(shm_toc *toc, uint64 key); + +/* + * Tools for estimating how large a chunk of shared memory will be needed + * to store a TOC and its dependent objects. + */ +typedef struct +{ + Size space_for_chunks; + Size number_of_keys; +} shm_toc_estimator; + +#define shm_toc_initialize_estimator(e) \ + ((e)->space_for_chunks = 0, (e)->number_of_keys = 0) +#define shm_toc_estimate_chunk(e, sz) \ + ((e)->space_for_chunks = add_size((e)->space_for_chunks, \ + BUFFERALIGN((sz)))) +#define shm_toc_estimate_keys(e, cnt) \ + ((e)->number_of_keys = add_size((e)->number_of_keys, (cnt))) + +extern Size shm_toc_estimate(shm_toc_estimator *); + +#endif /* SHM_TOC_H */ diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index 94f5a1286d..745eb7e576 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -11,7 +11,7 @@ * at the same address. This means shared memory pointers can be passed * around directly between different processes. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/shmem.h diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h index bcf2c8111d..812ea95e9b 100644 --- a/src/include/storage/sinval.h +++ b/src/include/storage/sinval.h @@ -4,7 +4,7 @@ * POSTGRES shared cache invalidation communication definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/sinval.h @@ -24,6 +24,7 @@ * * invalidate a relcache entry for a specific logical relation * * invalidate an smgr cache entry for a specific physical relation * * invalidate the mapped-relation mapping for a given database + * * invalidate any saved snapshot that might be used to scan a given relation * More types could be added if needed. The message type is identified by * the first "int8" field of the message struct. Zero or positive means a * specific-catcache inval message (and also serves as the catcache ID field). @@ -33,8 +34,8 @@ * updates and deletions in system catalogs (see CacheInvalidateHeapTuple). * An update can generate two inval events, one for the old tuple and one for * the new, but this is reduced to one event if the tuple's hash key doesn't - * change. Note that the inval events themselves don't actually say whether - * the tuple is being inserted or deleted. Also, since we transmit only a + * change. Note that the inval events themselves don't actually say whether + * the tuple is being inserted or deleted. Also, since we transmit only a * hash key, there is a small risk of unnecessary invalidations due to chance * matches of hash keys. * @@ -43,11 +44,11 @@ * catcache inval messages must be generated for each of its caches, since * the hash keys will generally be different. * - * Catcache and relcache invalidations are transactional, and so are sent - * to other backends upon commit. Internally to the generating backend, - * they are also processed at CommandCounterIncrement so that later commands - * in the same transaction see the new state. The generating backend also - * has to process them at abort, to flush out any cache state it's loaded + * Catcache, relcache, and snapshot invalidations are transactional, and so + * are sent to other backends upon commit. Internally to the generating + * backend, they are also processed at CommandCounterIncrement so that later + * commands in the same transaction see the new state. The generating backend + * also has to process them at abort, to flush out any cache state it's loaded * from no-longer-valid entries. * * smgr and relation mapping invalidations are non-transactional: they are @@ -98,6 +99,15 @@ typedef struct Oid dbId; /* database ID, or 0 for shared catalogs */ } SharedInvalRelmapMsg; +#define SHAREDINVALSNAPSHOT_ID (-5) + +typedef struct +{ + int8 id; /* type field --- must be first */ + Oid dbId; /* database ID, or 0 if a shared relation */ + Oid relId; /* relation ID */ +} SharedInvalSnapshotMsg; + typedef union { int8 id; /* type field --- must be first */ @@ -106,6 +116,7 @@ typedef union SharedInvalRelcacheMsg rc; SharedInvalSmgrMsg sm; SharedInvalRelmapMsg rm; + SharedInvalSnapshotMsg sn; } SharedInvalidationMessage; @@ -136,4 +147,6 @@ extern void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid); +extern void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg); + #endif /* SINVAL_H */ diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h index 722cc00d59..72f532e4af 100644 --- a/src/include/storage/sinvaladt.h +++ b/src/include/storage/sinvaladt.h @@ -4,7 +4,7 @@ * POSTGRES shared cache invalidation data manager. * * The shared cache invalidation manager is responsible for transmitting - * invalidation messages between backends. Any message sent by any backend + * invalidation messages between backends. Any message sent by any backend * must be delivered to all already-running backends before it can be * forgotten. (If we run out of space, we instead deliver a "RESET" * message to backends that have fallen too far behind.) @@ -12,7 +12,7 @@ * The struct type SharedInvalidationMessage, defining the contents of * a single message, is defined in sinval.h. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/sinvaladt.h @@ -22,7 +22,7 @@ #ifndef SINVALADT_H #define SINVALADT_H -#include "storage/proc.h" +#include "storage/lock.h" #include "storage/sinval.h" /* @@ -32,6 +32,7 @@ extern Size SInvalShmemSize(void); extern void CreateSharedInvalidationState(void); extern void SharedInvalBackendInit(bool sendOnly); extern PGPROC *BackendIdGetProc(int backendID); +extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin); extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n); extern int SIGetDataEntries(SharedInvalidationMessage *data, int datasize); diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 828317c76f..1e8166551a 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/smgr.h @@ -34,10 +34,13 @@ * * An SMgrRelation may have an "owner", which is just a pointer to it from * somewhere else; smgr.c will clear this pointer if the SMgrRelation is - * closed. We use this to avoid dangling pointers from relcache to smgr + * closed. We use this to avoid dangling pointers from relcache to smgr * without having to make the smgr explicitly aware of relcache. There * can't be more than one "owner" pointer per SMgrRelation, but that's * all we need. + * + * SMgrRelations that do not have an "owner" are considered to be transient, + * and are deleted at end of transaction. */ typedef struct SMgrRelationData { @@ -50,7 +53,7 @@ typedef struct SMgrRelationData /* * These next three fields are not actually used or manipulated by smgr, * except that they are reset to InvalidBlockNumber upon a cache flush - * event (in particular, upon truncation of the relation). Higher levels + * event (in particular, upon truncation of the relation). Higher levels * store cached state here so that it will be reset when truncation * happens. In all three cases, InvalidBlockNumber means "unknown". */ @@ -62,13 +65,15 @@ typedef struct SMgrRelationData /* * Fields below here are intended to be private to smgr.c and its - * submodules. Do not touch them from elsewhere. + * submodules. Do not touch them from elsewhere. */ int smgr_which; /* storage manager selector */ - bool smgr_transient; /* T if files are to be closed at EOXact */ /* for md.c; NULL for forks that are not open */ struct _MdfdVec *md_fd[MAX_FORKNUM + 1]; + + /* if unowned, list link in list of all unowned SMgrRelations */ + struct SMgrRelationData *next_unowned_reln; } SMgrRelationData; typedef SMgrRelationData *SMgrRelation; @@ -84,14 +89,15 @@ typedef SMgrRelationData *SMgrRelation; extern void smgrinit(void); extern SMgrRelation smgropen(RelFileNode rnode, BackendId backend); -extern void smgrsettransient(SMgrRelation reln); extern bool smgrexists(SMgrRelation reln, ForkNumber forknum); extern void smgrsetowner(SMgrRelation *owner, SMgrRelation reln); +extern void smgrclearowner(SMgrRelation *owner, SMgrRelation reln); extern void smgrclose(SMgrRelation reln); extern void smgrcloseall(void); extern void smgrclosenode(RelFileNodeBackend rnode); extern void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern void smgrdounlink(SMgrRelation reln, bool isRedo); +extern void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo); extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); @@ -108,6 +114,7 @@ extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum); extern void smgrpreckpt(void); extern void smgrsync(void); extern void smgrpostckpt(void); +extern void AtEOXact_SMgr(void); /* internals: move me elsewhere -- ay 7/94 */ @@ -135,10 +142,9 @@ extern void mdsync(void); extern void mdpostckpt(void); extern void SetForwardFsyncRequests(void); -extern void RememberFsyncRequest(RelFileNodeBackend rnode, ForkNumber forknum, +extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno); -extern void ForgetRelationFsyncRequests(RelFileNodeBackend rnode, - ForkNumber forknum); +extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum); extern void ForgetDatabaseFsyncRequests(Oid dbid); /* smgrtype.c */ diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h index 3f6cacfb0e..b5fd964c0f 100644 --- a/src/include/storage/spin.h +++ b/src/include/storage/spin.h @@ -46,7 +46,7 @@ * be again. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/spin.h @@ -57,6 +57,9 @@ #define SPIN_H #include "storage/s_lock.h" +#ifndef HAVE_SPINLOCKS +#include "storage/pg_sema.h" +#endif #define SpinLockInit(lock) S_INIT_LOCK(lock) @@ -69,5 +72,11 @@ extern int SpinlockSemas(void); +extern Size SpinlockSemaSize(void); + +#ifndef HAVE_SPINLOCKS +extern void SpinlockSemaInit(PGSemaphore); +extern PGSemaphore SpinlockSemaArray; +#endif #endif /* SPIN_H */ diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h index ed3b66b35d..89ab704699 100644 --- a/src/include/storage/standby.h +++ b/src/include/storage/standby.h @@ -4,7 +4,7 @@ * Definitions for hot standby mode. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/standby.h @@ -33,8 +33,9 @@ extern void ResolveRecoveryConflictWithTablespace(Oid tsid); extern void ResolveRecoveryConflictWithDatabase(Oid dbid); extern void ResolveRecoveryConflictWithBufferPin(void); -extern void SendRecoveryConflictWithBufferPin(ProcSignalReason reason); extern void CheckRecoveryConflictDeadlock(void); +extern void StandbyDeadLockHandler(void); +extern void StandbyTimeoutHandler(void); /* * Standby Rmgr (RM_STANDBY_ID) @@ -67,6 +68,7 @@ typedef struct xl_standby_locks typedef struct xl_running_xacts { int xcnt; /* # of xact ids in xids[] */ + int subxcnt; /* # of subxact ids in xids[] */ bool subxid_overflow; /* snapshot overflowed, subxids missing */ TransactionId nextXid; /* copy of ShmemVariableCache->nextXid */ TransactionId oldestRunningXid; /* *not* oldestXmin */ @@ -97,6 +99,7 @@ extern void standby_desc(StringInfo buf, uint8 xl_info, char *rec); typedef struct RunningTransactionsData { int xcnt; /* # of xact ids in xids[] */ + int subxcnt; /* # of subxact ids in xids[] */ bool subxid_overflow; /* snapshot overflowed, subxids missing */ TransactionId nextXid; /* copy of ShmemVariableCache->nextXid */ TransactionId oldestRunningXid; /* *not* oldestXmin */ @@ -110,6 +113,6 @@ typedef RunningTransactionsData *RunningTransactions; extern void LogAccessExclusiveLock(Oid dbOid, Oid relOid); extern void LogAccessExclusiveLockPrepare(void); -extern void LogStandbySnapshot(TransactionId *nextXid); +extern XLogRecPtr LogStandbySnapshot(void); #endif /* STANDBY_H */ diff --git a/src/include/tcop/dest.h b/src/include/tcop/dest.h index cdeb8b4810..0aa71cb5b4 100644 --- a/src/include/tcop/dest.h +++ b/src/include/tcop/dest.h @@ -29,14 +29,14 @@ * * CreateDestReceiver returns a receiver object appropriate to the specified * destination. The executor, as well as utility statements that can return - * tuples, are passed the resulting DestReceiver* pointer. Each executor run + * tuples, are passed the resulting DestReceiver* pointer. Each executor run * or utility execution calls the receiver's rStartup method, then the * receiveSlot method (zero or more times), then the rShutdown method. * The same receiver object may be re-used multiple times; eventually it is * destroyed by calling its rDestroy method. * * In some cases, receiver objects require additional parameters that must - * be passed to them after calling CreateDestReceiver. Since the set of + * be passed to them after calling CreateDestReceiver. Since the set of * parameters varies for different receiver types, this is not handled by * this module, but by direct calls from the calling code to receiver type * specific functions. @@ -45,10 +45,10 @@ * allocated object (for destination types that require no local state), * in which case rDestroy is a no-op. Alternatively it can be a palloc'd * object that has DestReceiver as its first field and contains additional - * fields (see printtup.c for an example). These additional fields are then + * fields (see printtup.c for an example). These additional fields are then * accessible to the DestReceiver functions by casting the DestReceiver* - * pointer passed to them. The palloc'd object is pfree'd by the rDestroy - * method. Note that the caller of CreateDestReceiver should take care to + * pointer passed to them. The palloc'd object is pfree'd by the rDestroy + * method. Note that the caller of CreateDestReceiver should take care to * do so in a memory context that is long-lived enough for the receiver * object not to disappear while still needed. * @@ -62,7 +62,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/dest.h @@ -84,7 +84,7 @@ * destination. Someday this will probably need to be improved. * * Note: only the values DestNone, DestDebug, DestRemote are legal for the - * global variable whereToSendOutput. The other values may be used + * global variable whereToSendOutput. The other values may be used * as the destination for individual commands. * ---------------- */ @@ -98,11 +98,11 @@ typedef enum DestTuplestore, /* results sent to Tuplestore */ DestIntoRel, /* results sent to relation (SELECT INTO) */ DestCopyOut, /* results sent to COPY TO code */ - DestSQLFunction /* results sent to SQL-language func mgr */ + DestSQLFunction, /* results sent to SQL-language func mgr */ #ifdef XCP - , - DestProducer /* results sent to a SharedQueue */ + DestProducer, /* results sent to a SharedQueue */ #endif + DestTransientRel /* results sent to transient relation */ } CommandDest; /* ---------------- diff --git a/src/include/tcop/fastpath.h b/src/include/tcop/fastpath.h index 1b94cb5d46..fdbc937e2f 100644 --- a/src/include/tcop/fastpath.h +++ b/src/include/tcop/fastpath.h @@ -3,7 +3,7 @@ * fastpath.h * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/fastpath.h diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h index d91c2a76a0..151d260a1b 100644 --- a/src/include/tcop/pquery.h +++ b/src/include/tcop/pquery.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/pquery.h @@ -33,7 +33,7 @@ extern List *FetchPortalTargetList(Portal portal); extern List *FetchStatementTargetList(Node *stmt); extern void PortalStart(Portal portal, ParamListInfo params, - int eflags, bool use_active_snapshot); + int eflags, Snapshot snapshot); extern void PortalSetResultFormat(Portal portal, int nFormats, int16 *formats); diff --git a/src/include/tcop/tcopdebug.h b/src/include/tcop/tcopdebug.h index 663cb52a1d..63e45667bb 100644 --- a/src/include/tcop/tcopdebug.h +++ b/src/include/tcop/tcopdebug.h @@ -4,7 +4,7 @@ * #defines governing debugging behaviour in the traffic cop * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/tcopdebug.h @@ -24,7 +24,7 @@ /* ---------------- * TCOP_SHOWSTATS controls whether or not buffer and - * access method statistics are shown for each query. -cim 2/9/89 + * access method statistics are shown for each query. -cim 2/9/89 * ---------------- */ #undef TCOP_SHOWSTATS diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 964dd19c2c..60f75325db 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -4,7 +4,7 @@ * prototypes for postgres.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/tcopprot.h @@ -19,8 +19,9 @@ #ifndef TCOPPROT_H #define TCOPPROT_H -#include "executor/execdesc.h" +#include "nodes/params.h" #include "nodes/parsenodes.h" +#include "nodes/plannodes.h" #include "storage/procsignal.h" #include "utils/guc.h" @@ -61,16 +62,18 @@ extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); extern void assign_max_stack_depth(int newval, void *extra); extern void die(SIGNAL_ARGS); -extern void quickdie(SIGNAL_ARGS); +extern void quickdie(SIGNAL_ARGS) __attribute__((noreturn)); extern void StatementCancelHandler(SIGNAL_ARGS); -extern void FloatExceptionHandler(SIGNAL_ARGS); +extern void FloatExceptionHandler(SIGNAL_ARGS) __attribute__((noreturn)); extern void RecoveryConflictInterrupt(ProcSignalReason reason); /* called from SIGUSR1 * handler */ extern void prepare_for_client_read(void); extern void client_read_ended(void); -extern const char *process_postgres_switches(int argc, char *argv[], - GucContext ctx); -extern int PostgresMain(int argc, char *argv[], const char *username); +extern void process_postgres_switches(int argc, char *argv[], + GucContext ctx, const char **dbname); +extern void PostgresMain(int argc, char *argv[], + const char *dbname, + const char *username) __attribute__((noreturn)); extern long get_stack_depth_rlimit(void); extern void ResetUsage(void); extern void ShowUsage(const char *title); diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h index 71554f8342..3bc9ba26ef 100644 --- a/src/include/tcop/utility.h +++ b/src/include/tcop/utility.h @@ -4,7 +4,7 @@ * prototypes for utility.c. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/utility.h @@ -16,10 +16,17 @@ #include "tcop/tcopprot.h" +typedef enum +{ + PROCESS_UTILITY_TOPLEVEL, /* toplevel interactive command */ + PROCESS_UTILITY_QUERY, /* a complete query, but not toplevel */ + PROCESS_UTILITY_SUBCOMMAND /* a portion of a query */ +} ProcessUtilityContext; /* Hook for plugins to get control in ProcessUtility() */ typedef void (*ProcessUtility_hook_type) (Node *parsetree, - const char *queryString, ParamListInfo params, bool isTopLevel, + const char *queryString, ProcessUtilityContext context, + ParamListInfo params, DestReceiver *dest, #ifdef PGXC bool sentToRemote, @@ -28,14 +35,14 @@ typedef void (*ProcessUtility_hook_type) (Node *parsetree, extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook; extern void ProcessUtility(Node *parsetree, const char *queryString, - ParamListInfo params, bool isTopLevel, + ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, #ifdef PGXC bool sentToRemote, #endif /* PGXC */ char *completionTag); extern void standard_ProcessUtility(Node *parsetree, const char *queryString, - ParamListInfo params, bool isTopLevel, + ProcessUtilityContext context, ParamListInfo params, DestReceiver *dest, #ifdef PGXC bool sentToRemote, @@ -54,8 +61,6 @@ extern LogStmtLevel GetCommandLogLevel(Node *parsetree); extern bool CommandIsReadOnly(Node *parsetree); -extern void CheckRelationOwnership(RangeVar *rel, bool noCatalogs); - #ifdef PGXC extern bool pgxc_lock_for_utility_stmt(Node *parsetree); #endif diff --git a/src/include/tsearch/dicts/regis.h b/src/include/tsearch/dicts/regis.h index 13dc5c28a1..face373b76 100644 --- a/src/include/tsearch/dicts/regis.h +++ b/src/include/tsearch/dicts/regis.h @@ -4,7 +4,7 @@ * * Declarations for fast regex subset, used by ISpell * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/tsearch/dicts/regis.h * diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h index 9f82c85663..4367f25de6 100644 --- a/src/include/tsearch/dicts/spell.h +++ b/src/include/tsearch/dicts/spell.h @@ -4,7 +4,7 @@ * * Declarations for ISpell dictionary * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/tsearch/dicts/spell.h * diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h index 9a94ab70a9..4c30df4818 100644 --- a/src/include/tsearch/ts_cache.h +++ b/src/include/tsearch/ts_cache.h @@ -3,7 +3,7 @@ * ts_cache.h * Tsearch related object caches. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tsearch/ts_cache.h diff --git a/src/include/tsearch/ts_locale.h b/src/include/tsearch/ts_locale.h index d10403d3f0..72c9de8cf8 100644 --- a/src/include/tsearch/ts_locale.h +++ b/src/include/tsearch/ts_locale.h @@ -3,7 +3,7 @@ * ts_locale.h * locale compatibility layer for tsearch * - * Copyright (c) 1998-2012, PostgreSQL Global Development Group + * Copyright (c) 1998-2014, PostgreSQL Global Development Group * * src/include/tsearch/ts_locale.h * diff --git a/src/include/tsearch/ts_public.h b/src/include/tsearch/ts_public.h index d5c18f2cf0..61520beced 100644 --- a/src/include/tsearch/ts_public.h +++ b/src/include/tsearch/ts_public.h @@ -4,7 +4,7 @@ * Public interface to various tsearch modules, such as * parsers and dictionaries. * - * Copyright (c) 1998-2012, PostgreSQL Global Development Group + * Copyright (c) 1998-2014, PostgreSQL Global Development Group * * src/include/tsearch/ts_public.h * @@ -49,14 +49,14 @@ typedef struct typedef struct { HeadlineWordEntry *words; - int4 lenwords; - int4 curwords; + int32 lenwords; + int32 curwords; char *startsel; char *stopsel; char *fragdelim; - int2 startsellen; - int2 stopsellen; - int2 fragdelimlen; + int16 startsellen; + int16 stopsellen; + int16 fragdelimlen; } HeadlineParsedText; /* diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index 3adc3369f9..df4a57825e 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -3,7 +3,7 @@ * ts_type.h * Definitions for the tsvector and tsquery types * - * Copyright (c) 1998-2012, PostgreSQL Global Development Group + * Copyright (c) 1998-2014, PostgreSQL Global Development Group * * src/include/tsearch/ts_type.h * @@ -13,6 +13,7 @@ #define _PG_TSTYPE_H_ #include "fmgr.h" +#include "utils/memutils.h" #include "utils/pg_crc.h" @@ -21,7 +22,7 @@ * * Structure of tsvector datatype: * 1) standard varlena header - * 2) int4 size - number of lexemes (WordEntry array entries) + * 2) int32 size - number of lexemes (WordEntry array entries) * 3) Array of WordEntry - one per lexeme; must be sorted according to * tsCompareString() (ie, memcmp of lexeme strings). * WordEntry->pos gives the number of bytes from end of WordEntry @@ -232,18 +233,20 @@ typedef union typedef struct { int32 vl_len_; /* varlena header (do not touch directly!) */ - int4 size; /* number of QueryItems */ + int32 size; /* number of QueryItems */ char data[1]; /* data starts here */ } TSQueryData; typedef TSQueryData *TSQuery; -#define HDRSIZETQ ( VARHDRSZ + sizeof(int4) ) +#define HDRSIZETQ ( VARHDRSZ + sizeof(int32) ) /* Computes the size of header and all QueryItems. size is the number of * QueryItems, and lenofoperand is the total length of all operands */ #define COMPUTESIZE(size, lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) ) +#define TSQUERY_TOO_BIG(size, lenofoperand) \ + ((size) > (MaxAllocSize - HDRSIZETQ - (lenofoperand)) / sizeof(QueryItem)) /* Returns a pointer to the first QueryItem in a TSQuery */ #define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ )) diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h index 1db4c4f78b..2ffb3fb429 100644 --- a/src/include/tsearch/ts_utils.h +++ b/src/include/tsearch/ts_utils.h @@ -3,7 +3,7 @@ * ts_utils.h * helper utilities for tsearch * - * Copyright (c) 1998-2012, PostgreSQL Global Development Group + * Copyright (c) 1998-2014, PostgreSQL Global Development Group * * src/include/tsearch/ts_utils.h * @@ -42,7 +42,7 @@ typedef struct TSQueryParserStateData *TSQueryParserState; typedef void (*PushFunction) (Datum opaque, TSQueryParserState state, char *token, int tokenlen, - int2 tokenweights, /* bitmap as described + int16 tokenweights, /* bitmap as described * in QueryOperand * struct */ bool prefix); @@ -53,7 +53,7 @@ extern TSQuery parse_tsquery(char *buf, /* Functions for use by PushFunction implementations */ extern void pushValue(TSQueryParserState state, - char *strval, int lenval, int2 weight, bool prefix); + char *strval, int lenval, int16 weight, bool prefix); extern void pushStop(TSQueryParserState state); extern void pushOperator(TSQueryParserState state, int8 oper); @@ -83,12 +83,12 @@ typedef struct typedef struct { ParsedWord *words; - int4 lenwords; - int4 curwords; - int4 pos; + int32 lenwords; + int32 curwords; + int32 pos; } ParsedText; -extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int4 buflen); +extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int32 buflen); /* * headline framework, flow in common to generate: @@ -98,7 +98,7 @@ extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int4 buflen); */ extern void hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, - char *buf, int4 buflen); + char *buf, int32 buflen); extern text *generateHeadline(HeadlineParsedText *prs); /* @@ -149,6 +149,7 @@ extern Datum gin_cmp_tslexeme(PG_FUNCTION_ARGS); extern Datum gin_cmp_prefix(PG_FUNCTION_ARGS); extern Datum gin_extract_tsquery(PG_FUNCTION_ARGS); extern Datum gin_tsquery_consistent(PG_FUNCTION_ARGS); +extern Datum gin_tsquery_triconsistent(PG_FUNCTION_ARGS); extern Datum gin_extract_tsvector_2args(PG_FUNCTION_ARGS); extern Datum gin_extract_tsquery_5args(PG_FUNCTION_ARGS); extern Datum gin_tsquery_consistent_6args(PG_FUNCTION_ARGS); @@ -164,14 +165,14 @@ extern Datum gin_tsquery_consistent_6args(PG_FUNCTION_ARGS); /* * TSQuery Utilities */ -extern QueryItem *clean_NOT(QueryItem *ptr, int4 *len); -extern QueryItem *clean_fakeval(QueryItem *ptr, int4 *len); +extern QueryItem *clean_NOT(QueryItem *ptr, int32 *len); +extern QueryItem *clean_fakeval(QueryItem *ptr, int32 *len); typedef struct QTNode { QueryItem *valnode; uint32 flags; - int4 nchild; + int32 nchild; char *word; uint32 sign; struct QTNode **child; diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 6de39b21cf..9430baa4a0 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -4,7 +4,7 @@ * Definition of (and support for) access control list data structures. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/acl.h @@ -81,11 +81,11 @@ typedef struct AclItem /* * Definitions for convenient access to Acl (array of AclItem). * These are standard PostgreSQL arrays, but are restricted to have one - * dimension and no nulls. We also ignore the lower bound when reading, + * dimension and no nulls. We also ignore the lower bound when reading, * and set it to one when writing. * * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all - * other array types). Therefore, be careful to detoast them with the + * other array types). Therefore, be careful to detoast them with the * macros provided, unless you know for certain that a particular array * can't have been toasted. */ @@ -195,6 +195,7 @@ typedef enum AclObjectKind ACL_KIND_TSCONFIGURATION, /* pg_ts_config */ ACL_KIND_FDW, /* pg_foreign_data_wrapper */ ACL_KIND_FOREIGN_SERVER, /* pg_foreign_server */ + ACL_KIND_EVENT_TRIGGER, /* pg_event_trigger */ ACL_KIND_EXTENSION, /* pg_extension */ MAX_ACL_KIND /* MUST BE LAST */ } AclObjectKind; @@ -302,6 +303,8 @@ extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, extern void aclcheck_error_col(AclResult aclerr, AclObjectKind objectkind, const char *objectname, const char *colname); +extern void aclcheck_error_type(AclResult aclerr, Oid typeOid); + /* ownercheck routines just return true (owner) or false (not) */ extern bool pg_class_ownercheck(Oid class_oid, Oid roleid); extern bool pg_type_ownercheck(Oid type_oid, Oid roleid); @@ -320,6 +323,7 @@ extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid); extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid); extern bool pg_foreign_data_wrapper_ownercheck(Oid srv_oid, Oid roleid); extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid); +extern bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid); extern bool pg_extension_ownercheck(Oid ext_oid, Oid roleid); extern bool has_createrole_privilege(Oid roleid); diff --git a/src/include/utils/array.h b/src/include/utils/array.h index 1da20fefda..9bbfaae85e 100644 --- a/src/include/utils/array.h +++ b/src/include/utils/array.h @@ -46,7 +46,7 @@ * only work with varlena arrays. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/array.h @@ -204,6 +204,7 @@ extern Datum array_dims(PG_FUNCTION_ARGS); extern Datum array_lower(PG_FUNCTION_ARGS); extern Datum array_upper(PG_FUNCTION_ARGS); extern Datum array_length(PG_FUNCTION_ARGS); +extern Datum array_cardinality(PG_FUNCTION_ARGS); extern Datum array_larger(PG_FUNCTION_ARGS); extern Datum array_smaller(PG_FUNCTION_ARGS); extern Datum generate_subscripts(PG_FUNCTION_ARGS); @@ -211,6 +212,8 @@ extern Datum generate_subscripts_nodir(PG_FUNCTION_ARGS); extern Datum array_fill(PG_FUNCTION_ARGS); extern Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS); extern Datum array_unnest(PG_FUNCTION_ARGS); +extern Datum array_remove(PG_FUNCTION_ARGS); +extern Datum array_replace(PG_FUNCTION_ARGS); extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx, int arraytyplen, int elmlen, bool elmbyval, char elmalign, diff --git a/src/include/utils/ascii.h b/src/include/utils/ascii.h index 6911155784..827801d271 100644 --- a/src/include/utils/ascii.h +++ b/src/include/utils/ascii.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------- * ascii.h * - * Portions Copyright (c) 1999-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2014, PostgreSQL Global Development Group * * src/include/utils/ascii.h * diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h index c45af02997..5d68582024 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -3,15 +3,15 @@ * attoptcache.h * Attribute options cache. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/attoptcache.h * *------------------------------------------------------------------------- */ -#ifndef SPCCACHE_H -#define SPCCACHE_H +#ifndef ATTOPTCACHE_H +#define ATTOPTCACHE_H /* * Attribute options. @@ -25,4 +25,4 @@ typedef struct AttributeOpts AttributeOpts *get_attribute_options(Oid spcid, int attnum); -#endif /* SPCCACHE_H */ +#endif /* ATTOPTCACHE_H */ diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 87b3a1403a..b36b5af08f 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/builtins.h @@ -129,6 +129,10 @@ extern Datum boolle(PG_FUNCTION_ARGS); extern Datum boolge(PG_FUNCTION_ARGS); extern Datum booland_statefunc(PG_FUNCTION_ARGS); extern Datum boolor_statefunc(PG_FUNCTION_ARGS); +extern Datum bool_accum(PG_FUNCTION_ARGS); +extern Datum bool_accum_inv(PG_FUNCTION_ARGS); +extern Datum bool_alltrue(PG_FUNCTION_ARGS); +extern Datum bool_anytrue(PG_FUNCTION_ARGS); extern bool parse_bool(const char *value, bool *result); extern bool parse_bool_with_len(const char *value, size_t len, bool *result); @@ -151,7 +155,10 @@ extern Datum char_text(PG_FUNCTION_ARGS); /* domains.c */ extern Datum domain_in(PG_FUNCTION_ARGS); extern Datum domain_recv(PG_FUNCTION_ARGS); -extern void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt); +extern void domain_check(Datum value, bool isnull, Oid domainType, + void **extra, MemoryContext mcxt); +extern int errdatatype(Oid datatypeOid); +extern int errdomainconstraint(Oid datatypeOid, const char *conname); /* encode.c */ extern Datum binary_encode(PG_FUNCTION_ARGS); @@ -264,7 +271,7 @@ extern Datum int2shl(PG_FUNCTION_ARGS); extern Datum int2shr(PG_FUNCTION_ARGS); extern Datum generate_series_int4(PG_FUNCTION_ARGS); extern Datum generate_series_step_int4(PG_FUNCTION_ARGS); -extern int2vector *buildint2vector(const int2 *int2s, int n); +extern int2vector *buildint2vector(const int16 *int2s, int n); /* name.c */ extern Datum namein(PG_FUNCTION_ARGS); @@ -319,7 +326,7 @@ extern Datum btnamecmp(PG_FUNCTION_ARGS); extern Datum bttextcmp(PG_FUNCTION_ARGS); /* - * Per-opclass sort support functions for new btrees. Like the + * Per-opclass sort support functions for new btrees. Like the * functions above, these are stored in pg_amproc; most are defined in * access/nbtree/nbtcompare.c */ @@ -471,6 +478,7 @@ extern Datum pg_size_pretty_numeric(PG_FUNCTION_ARGS); extern Datum pg_table_size(PG_FUNCTION_ARGS); extern Datum pg_indexes_size(PG_FUNCTION_ARGS); extern Datum pg_relation_filenode(PG_FUNCTION_ARGS); +extern Datum pg_filenode_relation(PG_FUNCTION_ARGS); extern Datum pg_relation_filepath(PG_FUNCTION_ARGS); /* genfile.c */ @@ -496,6 +504,8 @@ extern Datum pg_sleep(PG_FUNCTION_ARGS); extern Datum pg_get_keywords(PG_FUNCTION_ARGS); extern Datum pg_typeof(PG_FUNCTION_ARGS); extern Datum pg_collation_for(PG_FUNCTION_ARGS); +extern Datum pg_relation_is_updatable(PG_FUNCTION_ARGS); +extern Datum pg_column_is_updatable(PG_FUNCTION_ARGS); /* oid.c */ extern Datum oidin(PG_FUNCTION_ARGS); @@ -523,6 +533,21 @@ extern Datum oidvectorgt(PG_FUNCTION_ARGS); extern oidvector *buildoidvector(const Oid *oids, int n); extern Oid oidparse(Node *node); +/* orderedsetaggs.c */ +extern Datum ordered_set_transition(PG_FUNCTION_ARGS); +extern Datum ordered_set_transition_multi(PG_FUNCTION_ARGS); +extern Datum percentile_disc_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_final(PG_FUNCTION_ARGS); +extern Datum percentile_disc_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_float8_multi_final(PG_FUNCTION_ARGS); +extern Datum percentile_cont_interval_multi_final(PG_FUNCTION_ARGS); +extern Datum mode_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_percent_rank_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_cume_dist_final(PG_FUNCTION_ARGS); +extern Datum hypothetical_dense_rank_final(PG_FUNCTION_ARGS); + /* pseudotypes.c */ extern Datum cstring_in(PG_FUNCTION_ARGS); extern Datum cstring_out(PG_FUNCTION_ARGS); @@ -550,6 +575,8 @@ extern Datum pgxc_lock_for_backup (PG_FUNCTION_ARGS); #endif extern Datum trigger_in(PG_FUNCTION_ARGS); extern Datum trigger_out(PG_FUNCTION_ARGS); +extern Datum event_trigger_in(PG_FUNCTION_ARGS); +extern Datum event_trigger_out(PG_FUNCTION_ARGS); extern Datum language_handler_in(PG_FUNCTION_ARGS); extern Datum language_handler_out(PG_FUNCTION_ARGS); extern Datum fdw_handler_in(PG_FUNCTION_ARGS); @@ -586,10 +613,14 @@ extern Datum regexp_split_to_table(PG_FUNCTION_ARGS); extern Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS); extern Datum regexp_split_to_array(PG_FUNCTION_ARGS); extern Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS); +extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive, + Oid collation, bool *exact); /* regproc.c */ extern Datum regprocin(PG_FUNCTION_ARGS); extern Datum regprocout(PG_FUNCTION_ARGS); +extern Datum to_regproc(PG_FUNCTION_ARGS); +extern Datum to_regprocedure(PG_FUNCTION_ARGS); extern Datum regprocrecv(PG_FUNCTION_ARGS); extern Datum regprocsend(PG_FUNCTION_ARGS); extern Datum regprocedurein(PG_FUNCTION_ARGS); @@ -600,6 +631,8 @@ extern Datum regoperin(PG_FUNCTION_ARGS); extern Datum regoperout(PG_FUNCTION_ARGS); extern Datum regoperrecv(PG_FUNCTION_ARGS); extern Datum regopersend(PG_FUNCTION_ARGS); +extern Datum to_regoper(PG_FUNCTION_ARGS); +extern Datum to_regoperator(PG_FUNCTION_ARGS); extern Datum regoperatorin(PG_FUNCTION_ARGS); extern Datum regoperatorout(PG_FUNCTION_ARGS); extern Datum regoperatorrecv(PG_FUNCTION_ARGS); @@ -608,10 +641,12 @@ extern Datum regclassin(PG_FUNCTION_ARGS); extern Datum regclassout(PG_FUNCTION_ARGS); extern Datum regclassrecv(PG_FUNCTION_ARGS); extern Datum regclasssend(PG_FUNCTION_ARGS); +extern Datum to_regclass(PG_FUNCTION_ARGS); extern Datum regtypein(PG_FUNCTION_ARGS); extern Datum regtypeout(PG_FUNCTION_ARGS); extern Datum regtyperecv(PG_FUNCTION_ARGS); extern Datum regtypesend(PG_FUNCTION_ARGS); +extern Datum to_regtype(PG_FUNCTION_ARGS); extern Datum regconfigin(PG_FUNCTION_ARGS); extern Datum regconfigout(PG_FUNCTION_ARGS); extern Datum regconfigrecv(PG_FUNCTION_ARGS); @@ -623,7 +658,9 @@ extern Datum regdictionarysend(PG_FUNCTION_ARGS); extern Datum text_regclass(PG_FUNCTION_ARGS); extern List *stringToQualifiedNameList(const char *string); extern char *format_procedure(Oid procedure_oid); +extern char *format_procedure_qualified(Oid procedure_oid); extern char *format_operator(Oid operator_oid); +extern char *format_operator_qualified(Oid operator_oid); /* rowtypes.c */ extern Datum record_in(PG_FUNCTION_ARGS); @@ -637,6 +674,13 @@ extern Datum record_gt(PG_FUNCTION_ARGS); extern Datum record_le(PG_FUNCTION_ARGS); extern Datum record_ge(PG_FUNCTION_ARGS); extern Datum btrecordcmp(PG_FUNCTION_ARGS); +extern Datum record_image_eq(PG_FUNCTION_ARGS); +extern Datum record_image_ne(PG_FUNCTION_ARGS); +extern Datum record_image_lt(PG_FUNCTION_ARGS); +extern Datum record_image_gt(PG_FUNCTION_ARGS); +extern Datum record_image_le(PG_FUNCTION_ARGS); +extern Datum record_image_ge(PG_FUNCTION_ARGS); +extern Datum btrecordimagecmp(PG_FUNCTION_ARGS); /* ruleutils.c */ extern bool quote_all_identifiers; @@ -664,6 +708,7 @@ extern Datum pg_get_functiondef(PG_FUNCTION_ARGS); extern Datum pg_get_function_arguments(PG_FUNCTION_ARGS); extern Datum pg_get_function_identity_arguments(PG_FUNCTION_ARGS); extern Datum pg_get_function_result(PG_FUNCTION_ARGS); +extern Datum pg_get_function_arg_default(PG_FUNCTION_ARGS); extern char *deparse_expression(Node *expr, List *dpcontext, bool forceprefix, bool showimplicit); #ifdef PGXC @@ -673,11 +718,13 @@ extern void deparse_query(Query *query, StringInfo buf, List *parentnamespace); #endif extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for_planstate(Node *planstate, List *ancestors, - List *rtable); + List *rtable, List *rtable_names); #ifdef PGXC extern List *deparse_context_for_plan(Node *plan, List *ancestors, List *rtable); #endif +extern List *select_rtable_names_for_explain(List *rtable, + Bitmapset *rels_used); extern const char *quote_identifier(const char *ident); extern char *quote_qualified_identifier(const char *qualifier, const char *ident); @@ -779,6 +826,8 @@ extern int varstr_cmp(char *arg1, int len1, char *arg2, int len2, Oid collid); extern List *textToQualifiedNameList(text *textval); extern bool SplitIdentifierString(char *rawstring, char separator, List **namelist); +extern bool SplitDirectoriesString(char *rawstring, char separator, + List **namelist); extern Datum replace_text(PG_FUNCTION_ARGS); extern text *replace_text_regexp(text *src_text, void *regexp, text *replace_text, bool glob); @@ -895,6 +944,7 @@ extern Datum network_sub(PG_FUNCTION_ARGS); extern Datum network_subeq(PG_FUNCTION_ARGS); extern Datum network_sup(PG_FUNCTION_ARGS); extern Datum network_supeq(PG_FUNCTION_ARGS); +extern Datum network_overlap(PG_FUNCTION_ARGS); extern Datum network_network(PG_FUNCTION_ARGS); extern Datum network_netmask(PG_FUNCTION_ARGS); extern Datum network_hostmask(PG_FUNCTION_ARGS); @@ -993,17 +1043,22 @@ extern Datum float4_numeric(PG_FUNCTION_ARGS); extern Datum numeric_float4(PG_FUNCTION_ARGS); extern Datum numeric_accum(PG_FUNCTION_ARGS); extern Datum numeric_avg_accum(PG_FUNCTION_ARGS); +extern Datum numeric_accum_inv(PG_FUNCTION_ARGS); extern Datum int2_accum(PG_FUNCTION_ARGS); extern Datum int4_accum(PG_FUNCTION_ARGS); extern Datum int8_accum(PG_FUNCTION_ARGS); #ifdef PGXC extern Datum numeric_collect(PG_FUNCTION_ARGS); #endif +extern Datum int2_accum_inv(PG_FUNCTION_ARGS); +extern Datum int4_accum_inv(PG_FUNCTION_ARGS); +extern Datum int8_accum_inv(PG_FUNCTION_ARGS); extern Datum int8_avg_accum(PG_FUNCTION_ARGS); #ifdef PGXC extern Datum numeric_avg_collect(PG_FUNCTION_ARGS); #endif extern Datum numeric_avg(PG_FUNCTION_ARGS); +extern Datum numeric_sum(PG_FUNCTION_ARGS); extern Datum numeric_var_pop(PG_FUNCTION_ARGS); extern Datum numeric_var_samp(PG_FUNCTION_ARGS); extern Datum numeric_stddev_pop(PG_FUNCTION_ARGS); @@ -1019,7 +1074,10 @@ extern Datum int4_avg_accum(PG_FUNCTION_ARGS); #ifdef PGXC extern Datum int8_avg_collect(PG_FUNCTION_ARGS); #endif +extern Datum int2_avg_accum_inv(PG_FUNCTION_ARGS); +extern Datum int4_avg_accum_inv(PG_FUNCTION_ARGS); extern Datum int8_avg(PG_FUNCTION_ARGS); +extern Datum int2int4_sum(PG_FUNCTION_ARGS); extern Datum width_bucket_numeric(PG_FUNCTION_ARGS); extern Datum hash_numeric(PG_FUNCTION_ARGS); @@ -1057,6 +1115,7 @@ extern Datum pg_encoding_max_length_sql(PG_FUNCTION_ARGS); /* format_type.c */ extern Datum format_type(PG_FUNCTION_ARGS); extern char *format_type_be(Oid type_oid); +extern char *format_type_be_qualified(Oid type_oid); extern char *format_type_with_typemod(Oid type_oid, int32 typemod); extern Datum oidvectortypes(PG_FUNCTION_ARGS); extern int32 type_maximum_size(Oid type_oid, int32 typemod); @@ -1164,16 +1223,24 @@ extern Datum ginarrayextract(PG_FUNCTION_ARGS); extern Datum ginarrayextract_2args(PG_FUNCTION_ARGS); extern Datum ginqueryarrayextract(PG_FUNCTION_ARGS); extern Datum ginarrayconsistent(PG_FUNCTION_ARGS); +extern Datum ginarraytriconsistent(PG_FUNCTION_ARGS); /* access/transam/twophase.c */ extern Datum pg_prepared_xact(PG_FUNCTION_ARGS); +/* access/transam/multixact.c */ +extern Datum pg_get_multixact_members(PG_FUNCTION_ARGS); + /* catalogs/dependency.c */ extern Datum pg_describe_object(PG_FUNCTION_ARGS); +extern Datum pg_identify_object(PG_FUNCTION_ARGS); /* commands/constraint.c */ extern Datum unique_key_recheck(PG_FUNCTION_ARGS); +/* commands/event_trigger.c */ +extern Datum pg_event_trigger_dropped_objects(PG_FUNCTION_ARGS); + /* commands/extension.c */ extern Datum pg_available_extensions(PG_FUNCTION_ARGS); extern Datum pg_available_extension_versions(PG_FUNCTION_ARGS); diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h index e999b32dee..38b40cb4c5 100644 --- a/src/include/utils/bytea.h +++ b/src/include/utils/bytea.h @@ -4,7 +4,7 @@ * Declarations for BYTEA data type support. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/bytea.h diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index d91700a07e..697516b81b 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -10,7 +10,7 @@ * guarantee that there can only be one matching row for a key combination. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/catcache.h @@ -22,7 +22,7 @@ #include "access/htup.h" #include "access/skey.h" -#include "lib/dllist.h" +#include "lib/ilist.h" #include "utils/relcache.h" /* @@ -37,7 +37,7 @@ typedef struct catcache { int id; /* cache identifier --- see syscache.h */ - struct catcache *cc_next; /* link to next catcache */ + slist_node cc_next; /* list link */ const char *cc_relname; /* name of relation the tuples come from */ Oid cc_reloid; /* OID of relation the tuples come from */ Oid cc_indexoid; /* OID of index matching cache keys */ @@ -51,7 +51,7 @@ typedef struct catcache ScanKeyData cc_skey[CATCACHE_MAXKEYS]; /* precomputed key info for * heap scans */ bool cc_isname[CATCACHE_MAXKEYS]; /* flag "name" key columns */ - Dllist cc_lists; /* list of CatCList structs */ + dlist_head cc_lists; /* list of CatCList structs */ #ifdef CATCACHE_STATS long cc_searches; /* total # searches against this cache */ long cc_hits; /* # of matches against existing entry */ @@ -66,8 +66,8 @@ typedef struct catcache long cc_lsearches; /* total # list-searches */ long cc_lhits; /* # of matches against existing lists */ #endif - Dllist cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */ -} CatCache; /* VARIABLE LENGTH STRUCT */ + dlist_head *cc_bucket; /* hash buckets */ +} CatCache; typedef struct catctup @@ -77,14 +77,14 @@ typedef struct catctup CatCache *my_cache; /* link to owning catcache */ /* - * Each tuple in a cache is a member of a Dllist that stores the elements - * of its hash bucket. We keep each Dllist in LRU order to speed repeated + * Each tuple in a cache is a member of a dlist that stores the elements + * of its hash bucket. We keep each dlist in LRU order to speed repeated * lookups. */ - Dlelem cache_elem; /* list member of per-bucket list */ + dlist_node cache_elem; /* list member of per-bucket list */ /* - * The tuple may also be a member of at most one CatCList. (If a single + * The tuple may also be a member of at most one CatCList. (If a single * catcache is list-searched with varying numbers of keys, we may have to * make multiple entries for the same tuple because of this restriction. * Currently, that's not expected to be common, so we accept the potential @@ -101,7 +101,7 @@ typedef struct catctup * * A negative cache entry is an assertion that there is no tuple matching * a particular key. This is just as useful as a normal entry so far as - * avoiding catalog searches is concerned. Management of positive and + * avoiding catalog searches is concerned. Management of positive and * negative entries is identical. */ int refcount; /* number of active references */ @@ -120,7 +120,7 @@ typedef struct catclist /* * A CatCList describes the result of a partial search, ie, a search using - * only the first K key columns of an N-key cache. We form the keys used + * only the first K key columns of an N-key cache. We form the keys used * into a tuple (with other attributes NULL) to represent the stored key * set. The CatCList object contains links to cache entries for all the * table rows satisfying the partial key. (Note: none of these will be @@ -139,7 +139,7 @@ typedef struct catclist * might not be true during bootstrap or recovery operations. (namespace.c * is able to save some cycles when it is true.) */ - Dlelem cache_elem; /* list member of per-catcache list */ + dlist_node cache_elem; /* list member of per-catcache list */ int refcount; /* number of active references */ bool dead; /* dead but not yet removed? */ bool ordered; /* members listed in index order? */ @@ -153,7 +153,7 @@ typedef struct catclist typedef struct catcacheheader { - CatCache *ch_caches; /* head of list of CatCache structs */ + slist_head ch_caches; /* head of list of CatCache structs */ int ch_ntup; /* # of tuples in all caches */ } CatCacheHeader; diff --git a/src/include/utils/combocid.h b/src/include/utils/combocid.h index c273f2c557..9e482ff3b2 100644 --- a/src/include/utils/combocid.h +++ b/src/include/utils/combocid.h @@ -4,7 +4,7 @@ * Combo command ID support routines * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/combocid.h diff --git a/src/include/utils/date.h b/src/include/utils/date.h index 8cdd9bc84f..622aa19490 100644 --- a/src/include/utils/date.h +++ b/src/include/utils/date.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * date.h - * Definitions for the SQL92 "date" and "time" types. + * Definitions for the SQL "date" and "time" types. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/date.h @@ -97,6 +97,7 @@ extern Datum date_in(PG_FUNCTION_ARGS); extern Datum date_out(PG_FUNCTION_ARGS); extern Datum date_recv(PG_FUNCTION_ARGS); extern Datum date_send(PG_FUNCTION_ARGS); +extern Datum make_date(PG_FUNCTION_ARGS); extern Datum date_eq(PG_FUNCTION_ARGS); extern Datum date_ne(PG_FUNCTION_ARGS); extern Datum date_lt(PG_FUNCTION_ARGS); @@ -154,6 +155,7 @@ extern Datum time_recv(PG_FUNCTION_ARGS); extern Datum time_send(PG_FUNCTION_ARGS); extern Datum timetypmodin(PG_FUNCTION_ARGS); extern Datum timetypmodout(PG_FUNCTION_ARGS); +extern Datum make_time(PG_FUNCTION_ARGS); extern Datum time_transform(PG_FUNCTION_ARGS); extern Datum time_scale(PG_FUNCTION_ARGS); extern Datum time_eq(PG_FUNCTION_ARGS); diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index d73cc8dcfe..2e69503f96 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -6,7 +6,7 @@ * including abstime, reltime, date, and time. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/datetime.h @@ -188,12 +188,17 @@ struct tzEntry; #define DTK_DATE_M (DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY)) #define DTK_TIME_M (DTK_M(HOUR) | DTK_M(MINUTE) | DTK_ALL_SECS_M) -#define MAXDATELEN 63 /* maximum possible length of an input date - * string (not counting tr. null) */ -#define MAXDATEFIELDS 25 /* maximum possible number of fields in a date - * string */ -#define TOKMAXLEN 10 /* only this many chars are stored in - * datetktbl */ +/* + * Working buffer size for input and output of interval, timestamp, etc. + * Inputs that need more working space will be rejected early. Longer outputs + * will overrun buffers, so this must suffice for all possible output. As of + * this writing, interval_out() needs the most space at ~90 bytes. + */ +#define MAXDATELEN 128 +/* maximum possible number of fields in a date string */ +#define MAXDATEFIELDS 25 +/* only this many chars are stored in datetktbl */ +#define TOKMAXLEN 10 /* keep this struct small; it gets used a lot */ typedef struct @@ -247,6 +252,8 @@ do { \ * Include check for leap year. */ +extern const char *const months[]; /* months (3-char abbreviations) */ +extern const char *const days[]; /* days (full names) */ extern const int day_tab[2][13]; #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) @@ -254,7 +261,7 @@ extern const int day_tab[2][13]; /* * Datetime input parsing routines (ParseDateTime, DecodeDateTime, etc) - * return zero or a positive value on success. On failure, they return + * return zero or a positive value on success. On failure, they return * one of these negative code values. DateTimeParseError may be used to * produce a correct ereport. */ @@ -276,6 +283,7 @@ extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, extern int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm, fsec_t *fsec, int *tzp); +extern int DecodeTimezone(char *str, int *tzp); extern int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm, fsec_t *fsec, int *tzp); @@ -285,7 +293,7 @@ extern int DecodeISO8601Interval(char *str, int *dtype, struct pg_tm * tm, fsec_t *fsec); extern void DateTimeParseError(int dterr, const char *str, - const char *datatype); + const char *datatype) __attribute__((noreturn)); extern int DetermineTimeZoneOffset(struct pg_tm * tm, pg_tz *tzp); @@ -294,6 +302,9 @@ extern void EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz extern void EncodeDateTime(struct pg_tm * tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str); extern void EncodeInterval(struct pg_tm * tm, fsec_t fsec, int style, char *str); +extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, + struct pg_tm * tm); + extern int DecodeSpecial(int field, char *lowtoken, int *val); extern int DecodeUnits(int field, char *lowtoken, int *val); diff --git a/src/include/utils/datum.h b/src/include/utils/datum.h index 657bb8e0d8..6b0ff1bea0 100644 --- a/src/include/utils/datum.h +++ b/src/include/utils/datum.h @@ -8,7 +8,7 @@ * of the Datum. (We do it this way because in most situations the caller * can look up the info just once and use it for many per-datum operations.) * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/datum.h diff --git a/src/include/utils/dynahash.h b/src/include/utils/dynahash.h index ede88c29e0..eca039d16a 100644 --- a/src/include/utils/dynahash.h +++ b/src/include/utils/dynahash.h @@ -4,7 +4,7 @@ * POSTGRES dynahash.h file definitions * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/dynahash.h diff --git a/src/include/utils/dynamic_loader.h b/src/include/utils/dynamic_loader.h index 4e9185b090..828397b721 100644 --- a/src/include/utils/dynamic_loader.h +++ b/src/include/utils/dynamic_loader.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/dynamic_loader.h diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 1bbfd2b958..92073be0ca 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -4,7 +4,7 @@ * POSTGRES error reporting/logging definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/elog.h @@ -89,22 +89,45 @@ * ... other errxxx() fields as needed ...)); * * The error level is required, and so is a primary error message (errmsg - * or errmsg_internal). All else is optional. errcode() defaults to + * or errmsg_internal). All else is optional. errcode() defaults to * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is * NOTICE or below. * * ereport_domain() allows a message domain to be specified, for modules that - * wish to use a different message catalog from the backend's. To avoid having + * wish to use a different message catalog from the backend's. To avoid having * one copy of the default text domain per .o file, we define it as NULL here * and have errstart insert the default text domain. Modules can either use * ereport_domain() directly, or preferably they can override the TEXTDOMAIN * macro. + * + * If elevel >= ERROR, the call will not return; we try to inform the compiler + * of that via pg_unreachable(). However, no useful optimization effect is + * obtained unless the compiler sees elevel as a compile-time constant, else + * we're just adding code bloat. So, if __builtin_constant_p is available, + * use that to cause the second if() to vanish completely for non-constant + * cases. We avoid using a local variable because it's not necessary and + * prevents gcc from making the unreachability deduction at optlevel -O0. *---------- */ +#ifdef HAVE__BUILTIN_CONSTANT_P +#define ereport_domain(elevel, domain, rest) \ + do { \ + if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ + errfinish rest; \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ + pg_unreachable(); \ + } while(0) +#else /* !HAVE__BUILTIN_CONSTANT_P */ #define ereport_domain(elevel, domain, rest) \ - (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \ - (errfinish rest) : (void) 0) + do { \ + const int elevel_ = (elevel); \ + if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ + errfinish rest; \ + if (elevel_ >= ERROR) \ + pg_unreachable(); \ + } while(0) +#endif /* HAVE__BUILTIN_CONSTANT_P */ #define ereport(elevel, rest) \ ereport_domain(elevel, TEXTDOMAIN, rest) @@ -159,6 +182,14 @@ errdetail_log(const char *fmt,...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); extern int +errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) +/* This extension allows gcc to check the format string for consistency with + the supplied arguments. */ +__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 4))) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 4))); + +extern int errdetail_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) /* This extension allows gcc to check the format string for consistency with @@ -172,8 +203,19 @@ errhint(const char *fmt,...) the supplied arguments. */ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); +/* + * errcontext() is typically called in error context callback functions, not + * within an ereport() invocation. The callback function can be in a different + * module than the ereport() call, so the message domain passed in errstart() + * is not usually the correct domain for translating the context message. + * set_errcontext_domain() first sets the domain to be used, and + * errcontext_msg() passes the actual message. + */ +#define errcontext set_errcontext_domain(TEXTDOMAIN), errcontext_msg + +extern int set_errcontext_domain(const char *domain); extern int -errcontext(const char *fmt,...) +errcontext_msg(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); @@ -186,6 +228,8 @@ extern int errposition(int cursorpos); extern int internalerrposition(int cursorpos); extern int internalerrquery(const char *query); +extern int err_generic_string(int field, const char *str); + extern int geterrcode(void); extern int geterrposition(void); extern int getinternalerrposition(void); @@ -196,7 +240,37 @@ extern int getinternalerrposition(void); * elog(ERROR, "portal \"%s\" not found", stmt->portalname); *---------- */ -#define elog elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish +#ifdef HAVE__VA_ARGS +/* + * If we have variadic macros, we can give the compiler a hint about the + * call not returning when elevel >= ERROR. See comments for ereport(). + * Note that historically elog() has called elog_start (which saves errno) + * before evaluating "elevel", so we preserve that behavior here. + */ +#ifdef HAVE__BUILTIN_CONSTANT_P +#define elog(elevel, ...) \ + do { \ + elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ + elog_finish(elevel, __VA_ARGS__); \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ + pg_unreachable(); \ + } while(0) +#else /* !HAVE__BUILTIN_CONSTANT_P */ +#define elog(elevel, ...) \ + do { \ + int elevel_; \ + elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ + elevel_ = (elevel); \ + elog_finish(elevel_, __VA_ARGS__); \ + if (elevel_ >= ERROR) \ + pg_unreachable(); \ + } while(0) +#endif /* HAVE__BUILTIN_CONSTANT_P */ +#else /* !HAVE__VA_ARGS */ +#define elog \ + elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), \ + elog_finish +#endif /* HAVE__VA_ARGS */ extern void elog_start(const char *filename, int lineno, const char *funcname); extern void @@ -283,14 +357,14 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack; /* * gcc understands __attribute__((noreturn)); for other compilers, insert - * a useless exit() call so that the compiler gets the point. + * pg_unreachable() so that the compiler gets the point. */ #ifdef __GNUC__ #define PG_RE_THROW() \ pg_re_throw() #else #define PG_RE_THROW() \ - (pg_re_throw(), exit(1)) + (pg_re_throw(), pg_unreachable()) #endif extern PGDLLIMPORT sigjmp_buf *PG_exception_stack; @@ -315,16 +389,25 @@ typedef struct ErrorData int lineno; /* __LINE__ of ereport() call */ const char *funcname; /* __func__ of ereport() call */ const char *domain; /* message domain */ + const char *context_domain; /* message domain for context message */ int sqlerrcode; /* encoded ERRSTATE */ char *message; /* primary error message */ char *detail; /* detail error message */ char *detail_log; /* detail error message for server log only */ char *hint; /* hint message */ char *context; /* context message */ + char *schema_name; /* name of schema */ + char *table_name; /* name of table */ + char *column_name; /* name of column */ + char *datatype_name; /* name of datatype */ + char *constraint_name; /* name of constraint */ int cursorpos; /* cursor index into query string */ int internalpos; /* cursor index into internalquery */ char *internalquery; /* text of internally-generated query */ int saved_errno; /* errno at entry */ + + /* context containing associated non-constant strings */ + struct MemoryContextData *assoc_context; } ErrorData; extern void EmitErrorReport(void); @@ -334,6 +417,8 @@ extern void FlushErrorState(void); extern void ReThrowError(ErrorData *edata) __attribute__((noreturn)); extern void pg_re_throw(void) __attribute__((noreturn)); +extern char *GetErrorContextStack(void); + /* Hook for intercepting messages before they are sent to the server log */ typedef void (*emit_log_hook_type) (ErrorData *edata); extern PGDLLIMPORT emit_log_hook_type emit_log_hook; @@ -351,6 +436,7 @@ typedef enum extern int Log_error_verbosity; extern char *Log_line_prefix; extern int Log_destination; +extern char *Log_destination_string; /* Log destination bitmap */ #define LOG_DESTINATION_STDERR 1 diff --git a/src/include/utils/evtcache.h b/src/include/utils/evtcache.h new file mode 100644 index 0000000000..c4c284fca0 --- /dev/null +++ b/src/include/utils/evtcache.h @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * + * evtcache.c + * Special-purpose cache for event trigger data. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/utils/cache/evtcache.c + * + *------------------------------------------------------------------------- + */ +#ifndef EVTCACHE_H +#define EVTCACHE_H + +#include "nodes/pg_list.h" + +typedef enum +{ + EVT_DDLCommandStart, + EVT_DDLCommandEnd, + EVT_SQLDrop +} EventTriggerEvent; + +typedef struct +{ + Oid fnoid; /* function to be called */ + char enabled; /* as SESSION_REPLICATION_ROLE_* */ + int ntags; /* number of command tags */ + char **tag; /* command tags in SORTED order */ +} EventTriggerCacheItem; + +extern List *EventCacheLookup(EventTriggerEvent event); + +#endif /* EVTCACHE_H */ diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h index 6d20cfddb3..ca009aecfd 100644 --- a/src/include/utils/fmgrtab.h +++ b/src/include/utils/fmgrtab.h @@ -3,7 +3,7 @@ * fmgrtab.h * The function manager's table of internal functions. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/fmgrtab.h diff --git a/src/include/utils/formatting.h b/src/include/utils/formatting.h index ce571957fe..8569c3d3e2 100644 --- a/src/include/utils/formatting.h +++ b/src/include/utils/formatting.h @@ -4,7 +4,7 @@ * src/include/utils/formatting.h * * - * Portions Copyright (c) 1999-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2014, PostgreSQL Global Development Group * * The PostgreSQL routines for a DateTime/int/float/numeric formatting, * inspire with Oracle TO_CHAR() / TO_DATE() / TO_NUMBER() routines. @@ -24,6 +24,10 @@ extern char *str_tolower(const char *buff, size_t nbytes, Oid collid); extern char *str_toupper(const char *buff, size_t nbytes, Oid collid); extern char *str_initcap(const char *buff, size_t nbytes, Oid collid); +extern char *asc_tolower(const char *buff, size_t nbytes); +extern char *asc_toupper(const char *buff, size_t nbytes); +extern char *asc_initcap(const char *buff, size_t nbytes); + extern Datum timestamp_to_char(PG_FUNCTION_ARGS); extern Datum timestamptz_to_char(PG_FUNCTION_ARGS); extern Datum interval_to_char(PG_FUNCTION_ARGS); diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index f2cb0a9290..60b5d01929 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -3,7 +3,7 @@ * geo_decls.h - Declarations for various 2D constructs. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/geo_decls.h @@ -88,19 +88,12 @@ typedef struct /*--------------------------------------------------------------------- * LINE - Specified by its general equation (Ax+By+C=0). - * If there is a y-intercept, it is C, which - * incidentally gives a freebie point on the line - * (if B=0, then C is the x-intercept). - * Slope m is precalculated to save time; if - * the line is not vertical, m == A. *-------------------------------------------------------------------*/ typedef struct { double A, B, C; - - double m; } LINE; diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 94a8a174ac..d2699b40d7 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Copyright (c) 2000-2012, PostgreSQL Global Development Group + * Copyright (c) 2000-2014, PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. * * src/include/utils/guc.h @@ -45,7 +45,7 @@ * configuration file, or by client request in the connection startup * packet (e.g., from libpq's PGOPTIONS variable). Furthermore, an * already-started backend will ignore changes to such an option in the - * configuration file. The idea is that these options are fixed for a + * configuration file. The idea is that these options are fixed for a * given backend once it's started, but they can vary across backends. * * SUSET options can be set at postmaster startup, with the SIGHUP @@ -77,11 +77,15 @@ typedef enum * dividing line between "interactive" and "non-interactive" sources for * error reporting purposes. * - * PGC_S_TEST is used when testing values to be stored as per-database or - * per-user defaults ("doit" will always be false, so this never gets stored - * as the actual source of any value). This is an interactive case, but - * it needs its own source value because some assign hooks need to make - * different validity checks in this case. + * PGC_S_TEST is used when testing values to be used later ("doit" will always + * be false, so this never gets stored as the actual source of any value). + * For example, ALTER DATABASE/ROLE tests proposed per-database or per-user + * defaults this way, and CREATE FUNCTION tests proposed function SET clauses + * this way. This is an interactive case, but it needs its own source value + * because some assign hooks need to make different validity checks in this + * case. In particular, references to nonexistent database objects generally + * shouldn't throw hard errors in this case, at most NOTICEs, since the + * objects might exist by the time the setting is used for real. * * NB: see GucSource_Names in guc.c if you change this. */ @@ -92,6 +96,7 @@ typedef enum PGC_S_ENV_VAR, /* postmaster environment variable */ PGC_S_FILE, /* postgresql.conf */ PGC_S_ARGV, /* postmaster command line */ + PGC_S_GLOBAL, /* global in-database setting */ PGC_S_DATABASE, /* per-database setting */ PGC_S_USER, /* per-user setting */ PGC_S_DATABASE_USER, /* per-user-and-database setting */ @@ -121,6 +126,11 @@ extern bool ParseConfigFile(const char *config_file, const char *calling_file, extern bool ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, ConfigVariable **head_p, ConfigVariable **tail_p); +extern bool ParseConfigDirectory(const char *includedir, + const char *calling_file, + int depth, int elevel, + ConfigVariable **head_p, + ConfigVariable **tail_p); extern void FreeConfigVariables(ConfigVariable *list); /* @@ -325,6 +335,7 @@ extern bool parse_real(const char *value, double *result); extern int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel); +extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt); extern char *GetConfigOptionByName(const char *name, const char **varname); extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow); extern int GetNumConfigOptions(void); @@ -337,7 +348,7 @@ extern TupleDesc GetPGVariableResultDesc(const char *name); extern char *RewriteBeginQuery(char *query_string, const char *name, List *args); #endif -extern void ExecSetVariableStmt(VariableSetStmt *stmt); +extern void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel); extern char *ExtractSetVariableArgs(VariableSetStmt *stmt); extern void ProcessGUCArray(ArrayType *array, diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 6c89c6643b..00bf3c4a4a 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -5,7 +5,7 @@ * * See src/backend/utils/misc/README for design notes. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/utils/guc_tables.h * @@ -88,6 +88,7 @@ enum config_group CLIENT_CONN, CLIENT_CONN_STATEMENT, CLIENT_CONN_LOCALE, + CLIENT_CONN_PRELOAD, CLIENT_CONN_OTHER, LOCK_MANAGEMENT, COMPAT_OPTIONS, @@ -269,5 +270,4 @@ extern const char *config_enum_lookup_by_value(struct config_enum * record, int extern bool config_enum_lookup_by_name(struct config_enum * record, const char *value, int *retval); - #endif /* GUC_TABLES_H */ diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h index b569a4edad..2cf4825d47 100644 --- a/src/include/utils/help_config.h +++ b/src/include/utils/help_config.h @@ -3,7 +3,7 @@ * help_config.h * Interface to the --help-config option of main.c * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * * src/include/utils/help_config.h * @@ -12,6 +12,6 @@ #ifndef HELP_CONFIG_H #define HELP_CONFIG_H 1 -extern int GucInfoMain(void); +extern void GucInfoMain(void) __attribute__((noreturn)); #endif diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h index fe6df325e9..77974a193b 100644 --- a/src/include/utils/hsearch.h +++ b/src/include/utils/hsearch.h @@ -4,7 +4,7 @@ * exported definitions for utils/hash/dynahash.c; see notes therein * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/hsearch.h @@ -30,7 +30,7 @@ typedef int (*HashCompareFunc) (const void *key1, const void *key2, Size keysize); /* - * Key copying functions must have this signature. The return value is not + * Key copying functions must have this signature. The return value is not * used. (The definition is set up to allow memcpy() and strncpy() to be * used directly.) */ @@ -128,6 +128,8 @@ extern uint32 get_hash_value(HTAB *hashp, const void *keyPtr); extern void *hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr); +extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry, + const void *newKeyPtr); extern long hash_get_num_entries(HTAB *hashp); extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp); extern void *hash_seq_search(HASH_SEQ_STATUS *status); diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h index 8e71584a31..8905a307f8 100644 --- a/src/include/utils/inet.h +++ b/src/include/utils/inet.h @@ -4,7 +4,7 @@ * Declarations for operations on INET datatypes. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/inet.h @@ -40,7 +40,7 @@ typedef struct /* * Both INET and CIDR addresses are represented within Postgres as varlena * objects, ie, there is a varlena header in front of the struct type - * depicted above. This struct depicts what we actually have in memory + * depicted above. This struct depicts what we actually have in memory * in "uncompressed" cases. Note that since the maximum data size is only * 18 bytes, INET/CIDR will invariably be stored into tuples using the * 1-byte-header varlena format. However, we have to be prepared to cope @@ -53,6 +53,38 @@ typedef struct inet_struct inet_data; } inet; +/* + * Access macros. We use VARDATA_ANY so that we can process short-header + * varlena values without detoasting them. This requires a trick: + * VARDATA_ANY assumes the varlena header is already filled in, which is + * not the case when constructing a new value (until SET_INET_VARSIZE is + * called, which we typically can't do till the end). Therefore, we + * always initialize the newly-allocated value to zeroes (using palloc0). + * A zero length word will look like the not-1-byte case to VARDATA_ANY, + * and so we correctly construct an uncompressed value. + * + * Note that ip_addrsize(), ip_maxbits(), and SET_INET_VARSIZE() require + * the family field to be set correctly. + */ +#define ip_family(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->family) + +#define ip_bits(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->bits) + +#define ip_addr(inetptr) \ + (((inet_struct *) VARDATA_ANY(inetptr))->ipaddr) + +#define ip_addrsize(inetptr) \ + (ip_family(inetptr) == PGSQL_AF_INET ? 4 : 16) + +#define ip_maxbits(inetptr) \ + (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128) + +#define SET_INET_VARSIZE(dst) \ + SET_VARSIZE(dst, VARHDRSZ + offsetof(inet_struct, ipaddr) + \ + ip_addrsize(dst)) + /* * This is the internal storage format for MAC addresses: @@ -82,4 +114,27 @@ typedef struct macaddr #define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n)) #define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x) +/* + * Support functions in network.c + */ +extern int bitncmp(const unsigned char *l, const unsigned char *r, int n); +extern int bitncommon(const unsigned char *l, const unsigned char *r, int n); + +/* + * GiST support functions in network_gist.c + */ +extern Datum inet_gist_consistent(PG_FUNCTION_ARGS); +extern Datum inet_gist_union(PG_FUNCTION_ARGS); +extern Datum inet_gist_compress(PG_FUNCTION_ARGS); +extern Datum inet_gist_decompress(PG_FUNCTION_ARGS); +extern Datum inet_gist_penalty(PG_FUNCTION_ARGS); +extern Datum inet_gist_picksplit(PG_FUNCTION_ARGS); +extern Datum inet_gist_same(PG_FUNCTION_ARGS); + +/* + * Estimation functions in network_selfuncs.c + */ +extern Datum networksel(PG_FUNCTION_ARGS); +extern Datum networkjoinsel(PG_FUNCTION_ARGS); + #endif /* INET_H */ diff --git a/src/include/utils/int8.h b/src/include/utils/int8.h index d01552b4b7..0e4b949946 100644 --- a/src/include/utils/int8.h +++ b/src/include/utils/int8.h @@ -4,7 +4,7 @@ * Declarations for operations on 64-bit integers. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/int8.h @@ -74,8 +74,10 @@ extern Datum int8div(PG_FUNCTION_ARGS); extern Datum int8abs(PG_FUNCTION_ARGS); extern Datum int8mod(PG_FUNCTION_ARGS); extern Datum int8inc(PG_FUNCTION_ARGS); +extern Datum int8dec(PG_FUNCTION_ARGS); extern Datum int8inc_any(PG_FUNCTION_ARGS); extern Datum int8inc_float8_float8(PG_FUNCTION_ARGS); +extern Datum int8dec_any(PG_FUNCTION_ARGS); extern Datum int8larger(PG_FUNCTION_ARGS); extern Datum int8smaller(PG_FUNCTION_ARGS); diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h index c8815e52eb..6156e0219d 100644 --- a/src/include/utils/inval.h +++ b/src/include/utils/inval.h @@ -4,7 +4,7 @@ * POSTGRES cache invalidation dispatcher definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/inval.h @@ -15,6 +15,7 @@ #define INVAL_H #include "access/htup.h" +#include "storage/relfilenode.h" #include "utils/relcache.h" @@ -63,7 +64,5 @@ extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue); -extern void inval_twophase_postcommit(TransactionId xid, uint16 info, - void *recdata, uint32 len); - +extern void InvalidateSystemCaches(void); #endif /* INVAL_H */ diff --git a/src/include/utils/json.h b/src/include/utils/json.h index 0f38147acb..82cc48b711 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -3,7 +3,7 @@ * json.h * Declarations for JSON data type support. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/json.h @@ -17,6 +17,7 @@ #include "fmgr.h" #include "lib/stringinfo.h" +/* functions in json.c */ extern Datum json_in(PG_FUNCTION_ARGS); extern Datum json_out(PG_FUNCTION_ARGS); extern Datum json_recv(PG_FUNCTION_ARGS); @@ -25,6 +26,59 @@ extern Datum array_to_json(PG_FUNCTION_ARGS); extern Datum array_to_json_pretty(PG_FUNCTION_ARGS); extern Datum row_to_json(PG_FUNCTION_ARGS); extern Datum row_to_json_pretty(PG_FUNCTION_ARGS); +extern Datum to_json(PG_FUNCTION_ARGS); + +extern Datum json_agg_transfn(PG_FUNCTION_ARGS); +extern Datum json_agg_finalfn(PG_FUNCTION_ARGS); + +extern Datum json_object_agg_finalfn(PG_FUNCTION_ARGS); +extern Datum json_object_agg_transfn(PG_FUNCTION_ARGS); + +extern Datum json_build_object(PG_FUNCTION_ARGS); +extern Datum json_build_object_noargs(PG_FUNCTION_ARGS); +extern Datum json_build_array(PG_FUNCTION_ARGS); +extern Datum json_build_array_noargs(PG_FUNCTION_ARGS); + +extern Datum json_object(PG_FUNCTION_ARGS); +extern Datum json_object_two_arg(PG_FUNCTION_ARGS); + extern void escape_json(StringInfo buf, const char *str); +extern Datum json_typeof(PG_FUNCTION_ARGS); + +/* functions in jsonfuncs.c */ +extern Datum json_object_field(PG_FUNCTION_ARGS); +extern Datum json_object_field_text(PG_FUNCTION_ARGS); +extern Datum json_array_element(PG_FUNCTION_ARGS); +extern Datum json_array_element_text(PG_FUNCTION_ARGS); +extern Datum json_extract_path(PG_FUNCTION_ARGS); +extern Datum json_extract_path_text(PG_FUNCTION_ARGS); +extern Datum json_object_keys(PG_FUNCTION_ARGS); +extern Datum json_array_length(PG_FUNCTION_ARGS); +extern Datum json_each(PG_FUNCTION_ARGS); +extern Datum json_each_text(PG_FUNCTION_ARGS); +extern Datum json_array_elements(PG_FUNCTION_ARGS); +extern Datum json_array_elements_text(PG_FUNCTION_ARGS); +extern Datum json_populate_record(PG_FUNCTION_ARGS); +extern Datum json_populate_recordset(PG_FUNCTION_ARGS); +extern Datum json_to_record(PG_FUNCTION_ARGS); +extern Datum json_to_recordset(PG_FUNCTION_ARGS); + +extern Datum jsonb_object_field(PG_FUNCTION_ARGS); +extern Datum jsonb_object_field_text(PG_FUNCTION_ARGS); +extern Datum jsonb_array_element(PG_FUNCTION_ARGS); +extern Datum jsonb_array_element_text(PG_FUNCTION_ARGS); +extern Datum jsonb_extract_path(PG_FUNCTION_ARGS); +extern Datum jsonb_extract_path_text(PG_FUNCTION_ARGS); +extern Datum jsonb_object_keys(PG_FUNCTION_ARGS); +extern Datum jsonb_array_length(PG_FUNCTION_ARGS); +extern Datum jsonb_each(PG_FUNCTION_ARGS); +extern Datum jsonb_each_text(PG_FUNCTION_ARGS); +extern Datum jsonb_array_elements_text(PG_FUNCTION_ARGS); +extern Datum jsonb_array_elements(PG_FUNCTION_ARGS); +extern Datum jsonb_populate_record(PG_FUNCTION_ARGS); +extern Datum jsonb_populate_recordset(PG_FUNCTION_ARGS); +extern Datum jsonb_to_record(PG_FUNCTION_ARGS); +extern Datum jsonb_to_recordset(PG_FUNCTION_ARGS); + #endif /* JSON_H */ diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h new file mode 100644 index 0000000000..df057121a1 --- /dev/null +++ b/src/include/utils/jsonapi.h @@ -0,0 +1,120 @@ +/*------------------------------------------------------------------------- + * + * jsonapi.h + * Declarations for JSON API support. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/jsonapi.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONAPI_H +#define JSONAPI_H + +#include "lib/stringinfo.h" + +typedef enum +{ + JSON_TOKEN_INVALID, + JSON_TOKEN_STRING, + JSON_TOKEN_NUMBER, + JSON_TOKEN_OBJECT_START, + JSON_TOKEN_OBJECT_END, + JSON_TOKEN_ARRAY_START, + JSON_TOKEN_ARRAY_END, + JSON_TOKEN_COMMA, + JSON_TOKEN_COLON, + JSON_TOKEN_TRUE, + JSON_TOKEN_FALSE, + JSON_TOKEN_NULL, + JSON_TOKEN_END +} JsonTokenType; + + +/* + * All the fields in this structure should be treated as read-only. + * + * If strval is not null, then it should contain the de-escaped value + * of the lexeme if it's a string. Otherwise most of these field names + * should be self-explanatory. + * + * line_number and line_start are principally for use by the parser's + * error reporting routines. + * token_terminator and prev_token_terminator point to the character + * AFTER the end of the token, i.e. where there would be a nul byte + * if we were using nul-terminated strings. + */ +typedef struct JsonLexContext +{ + char *input; + int input_length; + char *token_start; + char *token_terminator; + char *prev_token_terminator; + JsonTokenType token_type; + int lex_level; + int line_number; + char *line_start; + StringInfo strval; +} JsonLexContext; + +typedef void (*json_struct_action) (void *state); +typedef void (*json_ofield_action) (void *state, char *fname, bool isnull); +typedef void (*json_aelem_action) (void *state, bool isnull); +typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); + + +/* + * Semantic Action structure for use in parsing json. + * Any of these actions can be NULL, in which case nothing is done at that + * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts + * to doing a pure parse with no side-effects, and is therefore exactly + * what the json input routines do. + * + * The 'fname' and 'token' strings passed to these actions are palloc'd. + * They are not free'd or used further by the parser, so the action function + * is free to do what it wishes with them. + */ +typedef struct JsonSemAction +{ + void *semstate; + json_struct_action object_start; + json_struct_action object_end; + json_struct_action array_start; + json_struct_action array_end; + json_ofield_action object_field_start; + json_ofield_action object_field_end; + json_aelem_action array_element_start; + json_aelem_action array_element_end; + json_scalar_action scalar; +} JsonSemAction; + +/* + * parse_json will parse the string in the lex calling the + * action functions in sem at the appropriate points. It is + * up to them to keep what state they need in semstate. If they + * need access to the state of the lexer, then its pointer + * should be passed to them as a member of whatever semstate + * points to. If the action pointers are NULL the parser + * does nothing and just continues. + */ +extern void pg_parse_json(JsonLexContext *lex, JsonSemAction *sem); + +/* + * constructors for JsonLexContext, with or without strval element. + * If supplied, the strval element will contain a de-escaped version of + * the lexeme. However, doing this imposes a performance penalty, so + * it should be avoided if the de-escaped lexeme is not required. + * + * If you already have the json as a text* value, use the first of these + * functions, otherwise use makeJsonLexContextCstringLen(). + */ +extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); +extern JsonLexContext *makeJsonLexContextCstringLen(char *json, + int len, + bool need_escapes); + +#endif /* JSONAPI_H */ diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h new file mode 100644 index 0000000000..5f2594b11f --- /dev/null +++ b/src/include/utils/jsonb.h @@ -0,0 +1,369 @@ +/*------------------------------------------------------------------------- + * + * jsonb.h + * Declarations for jsonb data type support. + * + * Copyright (c) 1996-2014, PostgreSQL Global Development Group + * + * src/include/utils/jsonb.h + * + *------------------------------------------------------------------------- + */ +#ifndef __JSONB_H__ +#define __JSONB_H__ + +#include "lib/stringinfo.h" +#include "utils/array.h" +#include "utils/numeric.h" + +/* Tokens used when sequentially processing a jsonb value */ +typedef enum +{ + WJB_DONE, + WJB_KEY, + WJB_VALUE, + WJB_ELEM, + WJB_BEGIN_ARRAY, + WJB_END_ARRAY, + WJB_BEGIN_OBJECT, + WJB_END_OBJECT +} JsonbIteratorToken; + +/* Strategy numbers for GIN index opclasses */ +#define JsonbContainsStrategyNumber 7 +#define JsonbExistsStrategyNumber 9 +#define JsonbExistsAnyStrategyNumber 10 +#define JsonbExistsAllStrategyNumber 11 + +/* + * In the standard jsonb_ops GIN opclass for jsonb, we choose to index both + * keys and values. The storage format is text. The first byte of the text + * string distinguishes whether this is a key (always a string), null value, + * boolean value, numeric value, or string value. However, array elements + * that are strings are marked as though they were keys; this imprecision + * supports the definition of the "exists" operator, which treats array + * elements like keys. The remainder of the text string is empty for a null + * value, "t" or "f" for a boolean value, a normalized print representation of + * a numeric value, or the text of a string value. However, if the length of + * this text representation would exceed JGIN_MAXLENGTH bytes, we instead hash + * the text representation and store an 8-hex-digit representation of the + * uint32 hash value, marking the prefix byte with an additional bit to + * distinguish that this has happened. Hashing long strings saves space and + * ensures that we won't overrun the maximum entry length for a GIN index. + * (But JGIN_MAXLENGTH is quite a bit shorter than GIN's limit. It's chosen + * to ensure that the on-disk text datum will have a short varlena header.) + * Note that when any hashed item appears in a query, we must recheck index + * matches against the heap tuple; currently, this costs nothing because we + * must always recheck for other reasons. + */ +#define JGINFLAG_KEY 0x01 /* key (or string array element) */ +#define JGINFLAG_NULL 0x02 /* null value */ +#define JGINFLAG_BOOL 0x03 /* boolean value */ +#define JGINFLAG_NUM 0x04 /* numeric value */ +#define JGINFLAG_STR 0x05 /* string value (if not an array element) */ +#define JGINFLAG_HASHED 0x10 /* OR'd into flag if value was hashed */ +#define JGIN_MAXLENGTH 125 /* max length of text part before hashing */ + +/* Convenience macros */ +#define DatumGetJsonb(d) ((Jsonb *) PG_DETOAST_DATUM(d)) +#define JsonbGetDatum(p) PointerGetDatum(p) +#define PG_GETARG_JSONB(x) DatumGetJsonb(PG_GETARG_DATUM(x)) +#define PG_RETURN_JSONB(x) PG_RETURN_POINTER(x) + +typedef struct JsonbPair JsonbPair; +typedef struct JsonbValue JsonbValue; + +/* + * Jsonbs are varlena objects, so must meet the varlena convention that the + * first int32 of the object contains the total object size in bytes. Be sure + * to use VARSIZE() and SET_VARSIZE() to access it, though! + * + * Jsonb is the on-disk representation, in contrast to the in-memory JsonbValue + * representation. Often, JsonbValues are just shims through which a Jsonb + * buffer is accessed, but they can also be deep copied and passed around. + * + * Jsonb is a tree structure. Each node in the tree consists of a JEntry + * header, and a variable-length content. The JEntry header indicates what + * kind of a node it is, e.g. a string or an array, and the offset and length + * of its variable-length portion within the container. + * + * The JEntry and the content of a node are not stored physically together. + * Instead, the container array or object has an array that holds the JEntrys + * of all the child nodes, followed by their variable-length portions. + * + * The root node is an exception; it has no parent array or object that could + * hold its JEntry. Hence, no JEntry header is stored for the root node. It + * is implicitly known that the root node must be an array or an object, + * so we can get away without the type indicator as long as we can distinguish + * the two. For that purpose, both an array and an object begins with a uint32 + * header field, which contains an JB_FOBJECT or JB_FARRAY flag. When a naked + * scalar value needs to be stored as a Jsonb value, what we actually store is + * an array with one element, with the flags in the array's header field set + * to JB_FSCALAR | JB_FARRAY. + * + * To encode the length and offset of the variable-length portion of each + * node in a compact way, the JEntry stores only the end offset within the + * variable-length portion of the container node. For the first JEntry in the + * container's JEntry array, that equals to the length of the node data. For + * convenience, the JENTRY_ISFIRST flag is set. The begin offset and length + * of the rest of the entries can be calculated using the end offset of the + * previous JEntry in the array. + * + * Overall, the Jsonb struct requires 4-bytes alignment. Within the struct, + * the variable-length portion of some node types is aligned to a 4-byte + * boundary, while others are not. When alignment is needed, the padding is + * in the beginning of the node that requires it. For example, if a numeric + * node is stored after a string node, so that the numeric node begins at + * offset 3, the variable-length portion of the numeric node will begin with + * one padding byte. + */ + +/* + * Jentry format. + * + * The least significant 28 bits store the end offset of the entry (see + * JBE_ENDPOS, JBE_OFF, JBE_LEN macros below). The next three bits + * are used to store the type of the entry. The most significant bit + * is set on the first entry in an array of JEntrys. + */ +typedef uint32 JEntry; + +#define JENTRY_POSMASK 0x0FFFFFFF +#define JENTRY_TYPEMASK 0x70000000 + +/* values stored in the type bits */ +#define JENTRY_ISSTRING 0x00000000 +#define JENTRY_ISNUMERIC 0x10000000 +#define JENTRY_ISBOOL_FALSE 0x20000000 +#define JENTRY_ISBOOL_TRUE 0x30000000 +#define JENTRY_ISNULL 0x40000000 +#define JENTRY_ISCONTAINER 0x50000000 /* array or object */ + +/* Note possible multiple evaluations */ +#define JBE_ISFIRST(je_) (((je_) & JENTRY_ISFIRST) != 0) +#define JBE_ISSTRING(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISSTRING) +#define JBE_ISNUMERIC(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNUMERIC) +#define JBE_ISCONTAINER(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISCONTAINER) +#define JBE_ISNULL(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISNULL) +#define JBE_ISBOOL_TRUE(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_TRUE) +#define JBE_ISBOOL_FALSE(je_) (((je_) & JENTRY_TYPEMASK) == JENTRY_ISBOOL_FALSE) +#define JBE_ISBOOL(je_) (JBE_ISBOOL_TRUE(je_) || JBE_ISBOOL_FALSE(je_)) + +/* + * Macros for getting the offset and length of an element. Note multiple + * evaluations and access to prior array element. + */ +#define JBE_ENDPOS(je_) ((je_) & JENTRY_POSMASK) +#define JBE_OFF(ja, i) ((i) == 0 ? 0 : JBE_ENDPOS((ja)[i - 1])) +#define JBE_LEN(ja, i) ((i) == 0 ? JBE_ENDPOS((ja)[i]) \ + : JBE_ENDPOS((ja)[i]) - JBE_ENDPOS((ja)[i - 1])) + +/* + * A jsonb array or object node, within a Jsonb Datum. + * + * An array has one child for each element. An object has two children for + * each key/value pair. + */ +typedef struct JsonbContainer +{ + uint32 header; /* number of elements or key/value pairs, and + * flags */ + JEntry children[1]; /* variable length */ + + /* the data for each child node follows. */ +} JsonbContainer; + +/* flags for the header-field in JsonbContainer */ +#define JB_CMASK 0x0FFFFFFF +#define JB_FSCALAR 0x10000000 +#define JB_FOBJECT 0x20000000 +#define JB_FARRAY 0x40000000 + +/* The top-level on-disk format for a jsonb datum. */ +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + JsonbContainer root; +} Jsonb; + +/* convenience macros for accessing the root container in a Jsonb datum */ +#define JB_ROOT_COUNT(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_CMASK) +#define JB_ROOT_IS_SCALAR(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FSCALAR) +#define JB_ROOT_IS_OBJECT(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FOBJECT) +#define JB_ROOT_IS_ARRAY(jbp_) ( *(uint32*) VARDATA(jbp_) & JB_FARRAY) + + +/* + * JsonbValue: In-memory representation of Jsonb. This is a convenient + * deserialized representation, that can easily support using the "val" + * union across underlying types during manipulation. The Jsonb on-disk + * representation has various alignment considerations. + */ +struct JsonbValue +{ + enum + { + /* Scalar types */ + jbvNull = 0x0, + jbvString, + jbvNumeric, + jbvBool, + /* Composite types */ + jbvArray = 0x10, + jbvObject, + /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */ + jbvBinary + } type; /* Influences sort order */ + + union + { + Numeric numeric; + bool boolean; + struct + { + int len; + char *val; /* Not necessarily null-terminated */ + } string; /* String primitive type */ + + struct + { + int nElems; + JsonbValue *elems; + bool rawScalar; /* Top-level "raw scalar" array? */ + } array; /* Array container type */ + + struct + { + int nPairs; /* 1 pair, 2 elements */ + JsonbPair *pairs; + } object; /* Associative container type */ + + struct + { + int len; + JsonbContainer *data; + } binary; /* Array or object, in on-disk format */ + } val; +}; + +#define IsAJsonbScalar(jsonbval) ((jsonbval)->type >= jbvNull && \ + (jsonbval)->type <= jbvBool) + +/* + * Pair within an Object. + * + * Pairs with duplicate keys are de-duplicated. We store the order for the + * benefit of doing so in a well-defined way with respect to the original + * observed order (which is "last observed wins"). This is only used briefly + * when originally constructing a Jsonb. + */ +struct JsonbPair +{ + JsonbValue key; /* Must be a jbvString */ + JsonbValue value; /* May be of any type */ + uint32 order; /* preserves order of pairs with equal keys */ +}; + +/* Conversion state used when parsing Jsonb from text, or for type coercion */ +typedef struct JsonbParseState +{ + JsonbValue contVal; + Size size; + struct JsonbParseState *next; +} JsonbParseState; + +/* + * JsonbIterator holds details of the type for each iteration. It also stores a + * Jsonb varlena buffer, which can be directly accessed in some contexts. + */ +typedef enum +{ + JBI_ARRAY_START, + JBI_ARRAY_ELEM, + JBI_OBJECT_START, + JBI_OBJECT_KEY, + JBI_OBJECT_VALUE +} JsonbIterState; + +typedef struct JsonbIterator +{ + /* Container being iterated */ + JsonbContainer *container; + uint32 nElems; /* Number of elements in children array (will be + * nPairs for objects) */ + bool isScalar; /* Pseudo-array scalar value? */ + JEntry *children; + + /* Current item in buffer (up to nElems, but must * 2 for objects) */ + int i; + + /* + * Data proper. This points just past end of children array. + * We use the JBE_OFF() macro on the Jentrys to find offsets of each + * child in this area. + */ + char *dataProper; + + /* Private state */ + JsonbIterState state; + + struct JsonbIterator *parent; +} JsonbIterator; + +/* I/O routines */ +extern Datum jsonb_in(PG_FUNCTION_ARGS); +extern Datum jsonb_out(PG_FUNCTION_ARGS); +extern Datum jsonb_recv(PG_FUNCTION_ARGS); +extern Datum jsonb_send(PG_FUNCTION_ARGS); +extern Datum jsonb_typeof(PG_FUNCTION_ARGS); + +/* Indexing-related ops */ +extern Datum jsonb_exists(PG_FUNCTION_ARGS); +extern Datum jsonb_exists_any(PG_FUNCTION_ARGS); +extern Datum jsonb_exists_all(PG_FUNCTION_ARGS); +extern Datum jsonb_contains(PG_FUNCTION_ARGS); +extern Datum jsonb_contained(PG_FUNCTION_ARGS); +extern Datum jsonb_ne(PG_FUNCTION_ARGS); +extern Datum jsonb_lt(PG_FUNCTION_ARGS); +extern Datum jsonb_gt(PG_FUNCTION_ARGS); +extern Datum jsonb_le(PG_FUNCTION_ARGS); +extern Datum jsonb_ge(PG_FUNCTION_ARGS); +extern Datum jsonb_eq(PG_FUNCTION_ARGS); +extern Datum jsonb_cmp(PG_FUNCTION_ARGS); +extern Datum jsonb_hash(PG_FUNCTION_ARGS); + +/* GIN support functions for jsonb_ops */ +extern Datum gin_compare_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb_query(PG_FUNCTION_ARGS); +extern Datum gin_consistent_jsonb(PG_FUNCTION_ARGS); +extern Datum gin_triconsistent_jsonb(PG_FUNCTION_ARGS); + +/* GIN support functions for jsonb_path_ops */ +extern Datum gin_extract_jsonb_path(PG_FUNCTION_ARGS); +extern Datum gin_extract_jsonb_query_path(PG_FUNCTION_ARGS); +extern Datum gin_consistent_jsonb_path(PG_FUNCTION_ARGS); +extern Datum gin_triconsistent_jsonb_path(PG_FUNCTION_ARGS); + +/* Support functions */ +extern int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b); +extern JsonbValue *findJsonbValueFromContainer(JsonbContainer *sheader, + uint32 flags, + JsonbValue *key); +extern JsonbValue *getIthJsonbValueFromContainer(JsonbContainer *sheader, + uint32 i); +extern JsonbValue *pushJsonbValue(JsonbParseState **pstate, + JsonbIteratorToken seq, JsonbValue *scalarVal); +extern JsonbIterator *JsonbIteratorInit(JsonbContainer *container); +extern JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, + bool skipNested); +extern Jsonb *JsonbValueToJsonb(JsonbValue *val); +extern bool JsonbDeepContains(JsonbIterator **val, + JsonbIterator **mContained); +extern void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash); + +/* jsonb.c support function */ +extern char *JsonbToCString(StringInfo out, JsonbContainer *in, + int estimated_len); + +#endif /* __JSONB_H__ */ diff --git a/src/include/utils/logtape.h b/src/include/utils/logtape.h index 430c485900..f663da66ee 100644 --- a/src/include/utils/logtape.h +++ b/src/include/utils/logtape.h @@ -5,7 +5,7 @@ * * See logtape.c for explanations. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/logtape.h diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index 471c2492b9..e75fdf60a5 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -8,7 +8,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/lsyscache.h @@ -18,7 +18,9 @@ #ifndef LSYSCACHE_H #define LSYSCACHE_H +#include "access/attnum.h" #include "access/htup.h" +#include "nodes/pg_list.h" /* Result list element for get_op_btree_interpretation */ typedef struct OpBtreeInterpretation @@ -98,6 +100,7 @@ extern Oid get_func_namespace(Oid funcid); extern Oid get_func_rettype(Oid funcid); extern int get_func_nargs(Oid funcid); extern Oid get_func_signature(Oid funcid, Oid **argtypes, int *nargs); +extern Oid get_func_variadictype(Oid funcid); extern bool get_func_retset(Oid funcid); extern bool func_strict(Oid funcid); extern char func_volatile(Oid funcid); diff --git a/src/include/utils/memdebug.h b/src/include/utils/memdebug.h new file mode 100644 index 0000000000..eec72a489a --- /dev/null +++ b/src/include/utils/memdebug.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * memdebug.h + * Memory debugging support. + * + * Currently, this file either wraps <valgrind/memcheck.h> or substitutes + * empty definitions for Valgrind client request macros we use. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/memdebug.h + * + *------------------------------------------------------------------------- + */ +#ifndef MEMDEBUG_H +#define MEMDEBUG_H + +#ifdef USE_VALGRIND +#include <valgrind/memcheck.h> +#else +#define VALGRIND_CHECK_MEM_IS_DEFINED(addr, size) do {} while (0) +#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed) do {} while (0) +#define VALGRIND_DESTROY_MEMPOOL(context) do {} while (0) +#define VALGRIND_MAKE_MEM_DEFINED(addr, size) do {} while (0) +#define VALGRIND_MAKE_MEM_NOACCESS(addr, size) do {} while (0) +#define VALGRIND_MAKE_MEM_UNDEFINED(addr, size) do {} while (0) +#define VALGRIND_MEMPOOL_ALLOC(context, addr, size) do {} while (0) +#define VALGRIND_MEMPOOL_FREE(context, addr) do {} while (0) +#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size) do {} while (0) +#endif + +#endif /* MEMDEBUG_H */ diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 06c8afdd0a..59d0aecfbb 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -7,7 +7,7 @@ * of the API of the memory management subsystem. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/memutils.h @@ -21,32 +21,36 @@ /* - * MaxAllocSize - * Quasi-arbitrary limit on size of allocations. + * MaxAllocSize, MaxAllocHugeSize + * Quasi-arbitrary limits on size of allocations. * * Note: - * There is no guarantee that allocations smaller than MaxAllocSize - * will succeed. Allocation requests larger than MaxAllocSize will - * be summarily denied. + * There is no guarantee that smaller allocations will succeed, but + * larger requests will be summarily denied. * - * XXX This is deliberately chosen to correspond to the limiting size - * of varlena objects under TOAST. See VARSIZE_4B() and related macros - * in postgres.h. Many datatypes assume that any allocatable size can - * be represented in a varlena header. - * - * XXX Also, various places in aset.c assume they can compute twice an - * allocation's size without overflow, so beware of raising this. + * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size + * of varlena objects under TOAST. See VARSIZE_4B() and related macros in + * postgres.h. Many datatypes assume that any allocatable size can be + * represented in a varlena header. This limit also permits a caller to use + * an "int" variable for an index into or length of an allocation. Callers + * careful to avoid these hazards can access the higher limit with + * MemoryContextAllocHuge(). Both limits permit code to assume that it may + * compute twice an allocation's size without overflow. */ #define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ #define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize) +#define MaxAllocHugeSize ((Size) -1 >> 1) /* SIZE_MAX / 2 */ + +#define AllocHugeSizeIsValid(size) ((Size) (size) <= MaxAllocHugeSize) + /* * All chunks allocated by any memory context manager are required to be * preceded by a StandardChunkHeader at a spacing of STANDARDCHUNKHEADERSIZE. * A currently-allocated chunk must contain a backpointer to its owning - * context as well as the allocated size of the chunk. The backpointer is - * used by pfree() and repalloc() to find the context to call. The allocated + * context as well as the allocated size of the chunk. The backpointer is + * used by pfree() and repalloc() to find the context to call. The allocated * size is not absolutely essential, but it's expected to be needed by any * reasonable implementation. */ diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h index a839e65e7e..981516e13c 100644 --- a/src/include/utils/nabstime.h +++ b/src/include/utils/nabstime.h @@ -4,7 +4,7 @@ * Definitions for the "new" abstime code. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/nabstime.h diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h index 3fc3ad57b1..d298718f7d 100644 --- a/src/include/utils/numeric.h +++ b/src/include/utils/numeric.h @@ -5,7 +5,7 @@ * * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane. * - * Copyright (c) 1998-2012, PostgreSQL Global Development Group + * Copyright (c) 1998-2014, PostgreSQL Global Development Group * * src/include/utils/numeric.h * @@ -58,5 +58,6 @@ typedef struct NumericData *Numeric; extern bool numeric_is_nan(Numeric num); int32 numeric_maximum_size(int32 typmod); extern char *numeric_out_sci(Numeric num, int scale); +extern char *numeric_normalize(Numeric num); #endif /* _PG_NUMERIC_H_ */ diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 973f306997..999bfbe75f 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -6,9 +6,9 @@ * This file contains the basic memory allocation interface that is * needed by almost every backend module. It is included directly by * postgres.h, so the definitions here are automatically available - * everywhere. Keep it lean! + * everywhere. Keep it lean! * - * Memory allocation occurs within "contexts". Every chunk obtained from + * Memory allocation occurs within "contexts". Every chunk obtained from * palloc()/MemoryContextAlloc() is allocated within a specific context. * The entire contents of a context can be freed easily and quickly by * resetting or deleting the context --- this is both faster and less @@ -18,7 +18,7 @@ * everything that should be freed. See utils/mmgr/README for more info. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/palloc.h @@ -29,7 +29,7 @@ #define PALLOC_H /* - * Type MemoryContextData is declared in nodes/memnodes.h. Most users + * Type MemoryContextData is declared in nodes/memnodes.h. Most users * of memory allocation should just treat it as an abstract type, so we * do not provide the struct contents here. */ @@ -37,8 +37,8 @@ typedef struct MemoryContextData *MemoryContext; /* * CurrentMemoryContext is the default allocation context for palloc(). - * We declare it here so that palloc() can be a macro. Avoid accessing it - * directly! Instead, use MemoryContextSwitchTo() to change the setting. + * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() + * to change the setting. */ extern PGDLLIMPORT MemoryContext CurrentMemoryContext; @@ -49,9 +49,10 @@ extern void *MemoryContextAlloc(MemoryContext context, Size size); extern void *MemoryContextAllocZero(MemoryContext context, Size size); extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); -#define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) - -#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz)) +extern void *palloc(Size size); +extern void *palloc0(Size size); +extern void *repalloc(void *pointer, Size size); +extern void pfree(void *pointer); /* * The result of palloc() is always word-aligned, so we can skip testing @@ -66,21 +67,27 @@ extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ MemoryContextAllocZero(CurrentMemoryContext, sz) ) -extern void pfree(void *pointer); - -extern void *repalloc(void *pointer, Size size); +/* Higher-limit allocators. */ +extern void *MemoryContextAllocHuge(MemoryContext context, Size size); +extern void *repalloc_huge(void *pointer, Size size); /* * MemoryContextSwitchTo can't be a macro in standard C compilers. * But we can make it an inline function if the compiler supports it. + * See STATIC_IF_INLINE in c.h. * - * This file has to be includable by some non-backend code such as - * pg_resetxlog, so don't expose the CurrentMemoryContext reference - * if FRONTEND is defined. + * Although this header file is nominally backend-only, certain frontend + * programs like pg_controldata include it via postgres.h. For some compilers + * it's necessary to hide the inline definition of MemoryContextSwitchTo in + * this scenario; hence the #ifndef FRONTEND. */ -#if defined(USE_INLINE) && !defined(FRONTEND) -static inline MemoryContext +#ifndef FRONTEND +#ifndef PG_USE_INLINE +extern MemoryContext MemoryContextSwitchTo(MemoryContext context); +#endif /* !PG_USE_INLINE */ +#if defined(PG_USE_INLINE) || defined(MCXT_INCLUDE_DEFINITIONS) +STATIC_IF_INLINE MemoryContext MemoryContextSwitchTo(MemoryContext context) { MemoryContext old = CurrentMemoryContext; @@ -88,25 +95,23 @@ MemoryContextSwitchTo(MemoryContext context) CurrentMemoryContext = context; return old; } -#else - -extern MemoryContext MemoryContextSwitchTo(MemoryContext context); -#endif /* USE_INLINE && !FRONTEND */ +#endif /* PG_USE_INLINE || MCXT_INCLUDE_DEFINITIONS */ +#endif /* FRONTEND */ /* * These are like standard strdup() except the copied string is * allocated in a context, not with malloc(). */ extern char *MemoryContextStrdup(MemoryContext context, const char *string); - -#define pstrdup(str) MemoryContextStrdup(CurrentMemoryContext, (str)) - +extern char *pstrdup(const char *in); extern char *pnstrdup(const char *in, Size len); -#if defined(WIN32) || defined(__CYGWIN__) -extern void *pgport_palloc(Size sz); -extern char *pgport_pstrdup(const char *str); -extern void pgport_pfree(void *pointer); -#endif +/* sprintf into a palloc'd buffer --- these are in psprintf.c */ +extern char * +psprintf(const char *fmt,...) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); +extern size_t +pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) +__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0))); #endif /* PALLOC_H */ diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h index 0652c0ad3b..375c405da5 100644 --- a/src/include/utils/pg_crc.h +++ b/src/include/utils/pg_crc.h @@ -14,7 +14,7 @@ * code for possible future use. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_crc.h @@ -72,7 +72,7 @@ extern CRCDLLIMPORT const uint32 pg_crc32_table[]; /* * crc0 represents the LSBs of the 64-bit value, crc1 the MSBs. Note that * with crc0 placed first, the output of 32-bit and 64-bit implementations - * will be bit-compatible only on little-endian architectures. If it were + * will be bit-compatible only on little-endian architectures. If it were * important to make the two possible implementations bit-compatible on * all machines, we could do a configure test to decide how to order the * two fields, but it seems not worth the trouble. diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h index 43052aa898..a487ee414b 100644 --- a/src/include/utils/pg_crc_tables.h +++ b/src/include/utils/pg_crc_tables.h @@ -18,7 +18,7 @@ * code for possible future use. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_crc_tables.h diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index 3c38aa2729..2b6f7b8049 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -4,7 +4,7 @@ * * src/include/utils/pg_locale.h * - * Copyright (c) 2002-2012, PostgreSQL Global Development Group + * Copyright (c) 2002-2014, PostgreSQL Global Development Group * *----------------------------------------------------------------------- */ diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h new file mode 100644 index 0000000000..7dd932d01b --- /dev/null +++ b/src/include/utils/pg_lsn.h @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * + * pg_lsn.h + * Declarations for operations on log sequence numbers (LSNs) of + * PostgreSQL. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/pg_lsn.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_LSN_H +#define PG_LSN_H + +#include "fmgr.h" +#include "access/xlogdefs.h" + +extern Datum pg_lsn_in(PG_FUNCTION_ARGS); +extern Datum pg_lsn_out(PG_FUNCTION_ARGS); +extern Datum pg_lsn_recv(PG_FUNCTION_ARGS); +extern Datum pg_lsn_send(PG_FUNCTION_ARGS); + +extern Datum pg_lsn_eq(PG_FUNCTION_ARGS); +extern Datum pg_lsn_ne(PG_FUNCTION_ARGS); +extern Datum pg_lsn_lt(PG_FUNCTION_ARGS); +extern Datum pg_lsn_gt(PG_FUNCTION_ARGS); +extern Datum pg_lsn_le(PG_FUNCTION_ARGS); +extern Datum pg_lsn_ge(PG_FUNCTION_ARGS); +extern Datum pg_lsn_cmp(PG_FUNCTION_ARGS); +extern Datum pg_lsn_hash(PG_FUNCTION_ARGS); + +extern Datum pg_lsn_mi(PG_FUNCTION_ARGS); + +#define DatumGetLSN(X) ((XLogRecPtr) DatumGetInt64(X)) +#define LSNGetDatum(X) (Int64GetDatum((int64) (X))) + +#define PG_GETARG_LSN(n) DatumGetLSN(PG_GETARG_DATUM(n)) +#define PG_RETURN_LSN(x) return LSNGetDatum(x) + +#endif /* PG_LSN_H */ diff --git a/src/include/utils/pg_rusage.h b/src/include/utils/pg_rusage.h index 5b2aef9689..9bfea8fa92 100644 --- a/src/include/utils/pg_rusage.h +++ b/src/include/utils/pg_rusage.h @@ -4,7 +4,7 @@ * header file for resource usage measurement support routines * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_rusage.h diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index efe2a8e3ec..4c4c1b6a6a 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -10,7 +10,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/plancache.h @@ -35,7 +35,7 @@ * the analyzed-and-rewritten query tree, and rebuild it when next needed. * * An actual execution plan, represented by CachedPlan, is derived from the - * CachedPlanSource when we need to execute the query. The plan could be + * CachedPlanSource when we need to execute the query. The plan could be * either generic (usable with any set of plan parameters) or custom (for a * specific set of parameters). plancache.c contains the logic that decides * which way to do it for any particular execution. If we are using a generic @@ -65,8 +65,16 @@ * context that holds the rewritten query tree and associated data. This * allows the query tree to be discarded easily when it is invalidated. * + * Some callers wish to use the CachedPlan API even with one-shot queries + * that have no reason to be saved at all. We therefore support a "oneshot" + * variant that does no data copying or invalidation checking. In this case + * there are no separate memory contexts: the CachedPlanSource struct and + * all subsidiary data live in the caller's CurrentMemoryContext, and there + * is no way to free memory short of clearing that entire context. A oneshot + * plan is always treated as unsaved. + * * Note: the string referenced by commandTag is not subsidiary storage; - * it is assumed to be a compile-time-constant string. As with portals, + * it is assumed to be a compile-time-constant string. As with portals, * commandTag shall be NULL if and only if the original query string (before * rewriting) was an empty string. */ @@ -74,7 +82,7 @@ typedef struct CachedPlanSource { int magic; /* should equal CACHEDPLANSOURCE_MAGIC */ Node *raw_parse_tree; /* output of raw_parser() */ - char *query_string; /* source text of query */ + const char *query_string; /* source text of query */ const char *commandTag; /* command tag (a constant!), or NULL */ Oid *param_types; /* array of parameter type OIDs, or NULL */ int num_params; /* length of param_types array */ @@ -83,16 +91,18 @@ typedef struct CachedPlanSource int cursor_options; /* cursor options used for planning */ bool fixed_result; /* disallow change in result tupdesc? */ TupleDesc resultDesc; /* result type; NULL = doesn't return tuples */ - struct OverrideSearchPath *search_path; /* saved search_path */ MemoryContext context; /* memory context holding all above */ /* These fields describe the current analyzed-and-rewritten query tree: */ List *query_list; /* list of Query nodes, or NIL if not valid */ List *relationOids; /* OIDs of relations the queries depend on */ List *invalItems; /* other dependencies, as PlanInvalItems */ + struct OverrideSearchPath *search_path; /* search_path used for + * parsing and planning */ MemoryContext query_context; /* context holding the above, or NULL */ /* If we have a generic plan, this is a reference-counted link to it: */ struct CachedPlan *gplan; /* generic plan, or NULL if not valid */ /* Some state flags: */ + bool is_oneshot; /* is it a "oneshot" plan? */ bool is_complete; /* has CompleteCachedPlan been done? */ bool is_saved; /* has CachedPlanSource been "saved"? */ bool is_valid; /* is the query_list currently valid? */ @@ -112,15 +122,18 @@ typedef struct CachedPlanSource * CachedPlan represents an execution plan derived from a CachedPlanSource. * The reference count includes both the link from the parent CachedPlanSource * (if any), and any active plan executions, so the plan can be discarded - * exactly when refcount goes to zero. Both the struct itself and the + * exactly when refcount goes to zero. Both the struct itself and the * subsidiary data live in the context denoted by the context field. - * This makes it easy to free a no-longer-needed cached plan. + * This makes it easy to free a no-longer-needed cached plan. (However, + * if is_oneshot is true, the context does not belong solely to the CachedPlan + * so no freeing is possible.) */ typedef struct CachedPlan { int magic; /* should equal CACHEDPLAN_MAGIC */ List *stmt_list; /* list of statement nodes (PlannedStmts and * bare utility statements) */ + bool is_oneshot; /* is it a "oneshot" plan? */ bool is_saved; /* is CachedPlan in a long-lived context? */ bool is_valid; /* is the stmt_list currently valid? */ TransactionId saved_xmin; /* if valid, replan when TransactionXmin @@ -140,6 +153,9 @@ extern CachedPlanSource *CreateCachedPlan(Node *raw_parse_tree, const char *stmt_name, #endif const char *commandTag); +extern CachedPlanSource *CreateOneShotCachedPlan(Node *raw_parse_tree, + const char *query_string, + const char *commandTag); extern void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h index 5c883ace6b..b095521431 100644 --- a/src/include/utils/portal.h +++ b/src/include/utils/portal.h @@ -41,7 +41,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/portal.h @@ -53,6 +53,7 @@ #include "datatype/timestamp.h" #include "executor/execdesc.h" +#include "utils/plancache.h" #include "utils/resowner.h" /* @@ -62,8 +63,8 @@ * single result from the user's viewpoint. However, the rule rewriter * may expand the single source query to zero or many actual queries.) * - * PORTAL_ONE_SELECT: the portal contains one single SELECT query. We run - * the Executor incrementally as results are demanded. This strategy also + * PORTAL_ONE_SELECT: the portal contains one single SELECT query. We run + * the Executor incrementally as results are demanded. This strategy also * supports holdable cursors (the Executor results can be dumped into a * tuplestore for access after transaction completion). * @@ -77,7 +78,7 @@ * all the auxiliary queries.) * * PORTAL_ONE_MOD_WITH: the portal contains one single SELECT query, but - * it has data-modifying CTEs. This is currently treated the same as the + * it has data-modifying CTEs. This is currently treated the same as the * PORTAL_ONE_RETURNING case because of the possibility of needing to fire * triggers. It may act more like PORTAL_ONE_SELECT in future. * @@ -238,5 +239,6 @@ extern void addProducingPortal(Portal portal); extern void removeProducingPortal(Portal portal); extern bool portalIsProducing(Portal portal); #endif +extern bool ThereAreNoReadyPortals(void); #endif /* PORTAL_H */ diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h index ad72df57dd..b1d17b9b17 100644 --- a/src/include/utils/rangetypes.h +++ b/src/include/utils/rangetypes.h @@ -4,7 +4,7 @@ * Declarations for Postgres range types. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/rangetypes.h @@ -75,6 +75,19 @@ typedef struct #define PG_GETARG_RANGE_COPY(n) DatumGetRangeTypeCopy(PG_GETARG_DATUM(n)) #define PG_RETURN_RANGE(x) return RangeTypeGetDatum(x) +/* Operator strategy numbers used in the GiST and SP-GiST range opclasses */ +/* Numbers are chosen to match up operator names with existing usages */ +#define RANGESTRAT_BEFORE 1 +#define RANGESTRAT_OVERLEFT 2 +#define RANGESTRAT_OVERLAPS 3 +#define RANGESTRAT_OVERRIGHT 4 +#define RANGESTRAT_AFTER 5 +#define RANGESTRAT_ADJACENT 6 +#define RANGESTRAT_CONTAINS 7 +#define RANGESTRAT_CONTAINED_BY 8 +#define RANGESTRAT_CONTAINS_ELEM 16 +#define RANGESTRAT_EQ 18 + /* * prototypes for functions defined in rangetypes.c */ @@ -104,6 +117,8 @@ extern Datum range_upper_inf(PG_FUNCTION_ARGS); extern Datum range_contains_elem(PG_FUNCTION_ARGS); extern Datum elem_contained_by_range(PG_FUNCTION_ARGS); +extern bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val); + /* range, range -> bool */ extern Datum range_eq(PG_FUNCTION_ARGS); extern Datum range_ne(PG_FUNCTION_ARGS); @@ -116,6 +131,28 @@ extern Datum range_overlaps(PG_FUNCTION_ARGS); extern Datum range_overleft(PG_FUNCTION_ARGS); extern Datum range_overright(PG_FUNCTION_ARGS); +/* internal versions of the above */ +extern bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); +extern bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, + RangeType *r2); + /* range, range -> range */ extern Datum range_minus(PG_FUNCTION_ARGS); extern Datum range_union(PG_FUNCTION_ARGS); @@ -133,6 +170,7 @@ extern Datum hash_range(PG_FUNCTION_ARGS); /* ANALYZE support */ extern Datum range_typanalyze(PG_FUNCTION_ARGS); +extern Datum rangesel(PG_FUNCTION_ARGS); /* Canonical functions */ extern Datum int4range_canonical(PG_FUNCTION_ARGS); @@ -163,6 +201,8 @@ extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2); extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2); +extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1, + RangeBound bound2); extern RangeType *make_empty_range(TypeCacheEntry *typcache); /* GiST support (in rangetypes_gist.c) */ diff --git a/src/include/utils/rbtree.h b/src/include/utils/rbtree.h index d6453a6c31..0c94151ce5 100644 --- a/src/include/utils/rbtree.h +++ b/src/include/utils/rbtree.h @@ -3,7 +3,7 @@ * rbtree.h * interface for PostgreSQL generic Red-Black binary tree package * - * Copyright (c) 2009-2012, PostgreSQL Global Development Group + * Copyright (c) 2009-2014, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/utils/rbtree.h diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index d7d68e92ab..4fd2165db7 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -9,7 +9,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -59,8 +59,8 @@ typedef LockInfoData *LockInfo; /* - * Cached lookup information for the index access method functions defined - * by the pg_am row associated with an index relation. + * Cached lookup information for the frequently used index access method + * functions, defined by the pg_am row associated with an index relation. */ typedef struct RelationAmInfo { @@ -72,13 +72,7 @@ typedef struct RelationAmInfo FmgrInfo amendscan; FmgrInfo ammarkpos; FmgrInfo amrestrpos; - FmgrInfo ambuild; - FmgrInfo ambuildempty; - FmgrInfo ambulkdelete; - FmgrInfo amvacuumcleanup; FmgrInfo amcanreturn; - FmgrInfo amcostestimate; - FmgrInfo amoptions; } RelationAmInfo; @@ -93,6 +87,7 @@ typedef struct RelationData struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */ int rd_refcnt; /* reference count */ BackendId rd_backend; /* owning backend id, if temporary relation */ + bool rd_islocaltemp; /* rel is a temp rel of this session */ bool rd_isnailed; /* rel is nailed in cache */ bool rd_isvalid; /* relcache entry is valid */ char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, 1 = @@ -101,11 +96,15 @@ typedef struct RelationData /* * rd_createSubid is the ID of the highest subtransaction the rel has * survived into; or zero if the rel was not created in the current top - * transaction. This should be relied on only for optimization purposes; - * it is possible for new-ness to be "forgotten" (eg, after CLUSTER). - * Likewise, rd_newRelfilenodeSubid is the ID of the highest - * subtransaction the relfilenode change has survived into, or zero if not - * changed in the current transaction (or we have forgotten changing it). + * transaction. This can be now be relied on, whereas previously it could + * be "forgotten" in earlier releases. Likewise, rd_newRelfilenodeSubid is + * the ID of the highest subtransaction the relfilenode change has + * survived into, or zero if not changed in the current transaction (or we + * have forgotten changing it). rd_newRelfilenodeSubid can be forgotten + * when a relation has multiple new relfilenodes within a single + * transaction, with one of them occuring in a subsequently aborted + * subtransaction, e.g. BEGIN; TRUNCATE t; SAVEPOINT save; TRUNCATE t; + * ROLLBACK TO save; -- rd_newRelfilenode is now forgotten */ SubTransactionId rd_createSubid; /* rel was created in current xact */ SubTransactionId rd_newRelfilenodeSubid; /* new relfilenode assigned in @@ -114,14 +113,21 @@ typedef struct RelationData Form_pg_class rd_rel; /* RELATION tuple */ TupleDesc rd_att; /* tuple descriptor */ Oid rd_id; /* relation's object id */ - List *rd_indexlist; /* list of OIDs of indexes on relation */ - Bitmapset *rd_indexattr; /* identifies columns used in indexes */ - Oid rd_oidindex; /* OID of unique index on OID, if any */ LockInfoData rd_lockInfo; /* lock mgr's info for locking relation */ RuleLock *rd_rules; /* rewrite rules */ MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */ TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */ + /* data managed by RelationGetIndexList: */ + List *rd_indexlist; /* list of OIDs of indexes on relation */ + Oid rd_oidindex; /* OID of unique index on OID, if any */ + Oid rd_replidindex; /* OID of replica identity index, if any */ + + /* data managed by RelationGetIndexAttrBitmap: */ + Bitmapset *rd_indexattr; /* identifies columns used in indexes */ + Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ + Bitmapset *rd_idattr; /* included in replica identity index */ + /* * rd_options is set whenever rd_rel is loaded into the relcache entry. * Note that you can NOT look into rd_rel for this data. NULL means "use @@ -146,7 +152,7 @@ typedef struct RelationData * Note: rd_amcache is available for index AMs to cache private data about * an index. This must be just a cache since it may get reset at any time * (in particular, it will get reset by a relcache inval message for the - * index). If used, it must point to a single memory chunk palloc'd in + * index). If used, it must point to a single memory chunk palloc'd in * rd_indexcxt. A relcache reset will include freeing that chunk and * setting rd_amcache = NULL. */ @@ -166,6 +172,17 @@ typedef struct RelationData Oid *rd_indcollation; /* OIDs of index collations */ /* + * foreign-table support + * + * rd_fdwroutine must point to a single memory chunk palloc'd in + * CacheMemoryContext. It will be freed and reset to NULL on a relcache + * reset. + */ + + /* use "struct" here to avoid needing to include fdwapi.h: */ + struct FdwRoutine *rd_fdwroutine; /* cached function pointers, or NULL */ + + /* * Hack for CLUSTER, rewriting ALTER TABLE, etc: when writing a new * version of a table, we need to make any toast pointers inserted into it * have the existing toast table's OID, not the OID of the transient toast @@ -202,6 +219,9 @@ typedef struct AutoVacOpts int freeze_min_age; int freeze_max_age; int freeze_table_age; + int multixact_freeze_min_age; + int multixact_freeze_max_age; + int multixact_freeze_table_age; float8 vacuum_scale_factor; float8 analyze_scale_factor; } AutoVacOpts; @@ -212,6 +232,9 @@ typedef struct StdRdOptions int fillfactor; /* page fill factor in percent (0..100) */ AutoVacOpts autovacuum; /* autovacuum-related options */ bool security_barrier; /* for views */ + int check_option_offset; /* for views */ + bool user_catalog_table; /* use as an additional catalog + * relation */ } StdRdOptions; #define HEAP_MIN_FILLFACTOR 10 @@ -248,6 +271,48 @@ typedef struct StdRdOptions ((StdRdOptions *) (relation)->rd_options)->security_barrier : false) /* + * RelationHasCheckOption + * Returns true if the relation is a view defined with either the local + * or the cascaded check option. + */ +#define RelationHasCheckOption(relation) \ + ((relation)->rd_options && \ + ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0) + +/* + * RelationHasLocalCheckOption + * Returns true if the relation is a view defined with the local check + * option. + */ +#define RelationHasLocalCheckOption(relation) \ + ((relation)->rd_options && \ + ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0 ? \ + strcmp((char *) (relation)->rd_options + \ + ((StdRdOptions *) (relation)->rd_options)->check_option_offset, \ + "local") == 0 : false) + +/* + * RelationHasCascadedCheckOption + * Returns true if the relation is a view defined with the cascaded check + * option. + */ +#define RelationHasCascadedCheckOption(relation) \ + ((relation)->rd_options && \ + ((StdRdOptions *) (relation)->rd_options)->check_option_offset != 0 ? \ + strcmp((char *) (relation)->rd_options + \ + ((StdRdOptions *) (relation)->rd_options)->check_option_offset, \ + "cascaded") == 0 : false) + +/* + * RelationIsUsedAsCatalogTable + * Returns whether the relation should be treated as a catalog table + * from the pov of logical decoding. + */ +#define RelationIsUsedAsCatalogTable(relation) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false) + +/* * RelationIsValid * True iff relation descriptor is valid. */ @@ -347,7 +412,7 @@ typedef struct StdRdOptions * RelationGetTargetBlock * Fetch relation's current insertion target block. * - * Returns InvalidBlockNumber if there is no current target block. Note + * Returns InvalidBlockNumber if there is no current target block. Note * that the target block status is discarded on any smgr-level invalidation. */ #define RelationGetTargetBlock(relation) \ @@ -392,16 +457,10 @@ typedef struct StdRdOptions #endif /* - * RelationUsesTempNamespace - * True if relation's catalog entries live in a private namespace. - */ -#define RelationUsesTempNamespace(relation) \ - ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP) - -/* * RELATION_IS_LOCAL * If a rel is either temp or newly created in the current transaction, - * it can be assumed to be visible only to the current backend. + * it can be assumed to be accessible only to the current backend. + * This is typically used to decide that we can skip acquiring locks. * * Beware of multiple eval of argument */ @@ -413,7 +472,7 @@ typedef struct StdRdOptions (relation)->rd_createSubid != InvalidSubTransactionId)) #else #define RELATION_IS_LOCAL(relation) \ - ((relation)->rd_backend == MyBackendId || \ + ((relation)->rd_islocaltemp || \ (relation)->rd_createSubid != InvalidSubTransactionId) #endif @@ -441,10 +500,53 @@ typedef struct StdRdOptions (OidIsValid(MyCoordId) && (relation)->rd_backend != MyFirstBackendId))) #else #define RELATION_IS_OTHER_TEMP(relation) \ - ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP \ - && (relation)->rd_backend != MyBackendId) + ((relation)->rd_rel->relpersistence == RELPERSISTENCE_TEMP && \ + !(relation)->rd_islocaltemp) #endif + +/* + * RelationIsScannable + * Currently can only be false for a materialized view which has not been + * populated by its query. This is likely to get more complicated later, + * so use a macro which looks like a function. + */ +#define RelationIsScannable(relation) ((relation)->rd_rel->relispopulated) + +/* + * RelationIsPopulated + * Currently, we don't physically distinguish the "populated" and + * "scannable" properties of matviews, but that may change later. + * Hence, use the appropriate one of these macros in code tests. + */ +#define RelationIsPopulated(relation) ((relation)->rd_rel->relispopulated) + +/* + * RelationIsAccessibleInLogicalDecoding + * True if we need to log enough information to have access via + * decoding snapshot. + */ +#define RelationIsAccessibleInLogicalDecoding(relation) \ + (XLogLogicalInfoActive() && \ + RelationNeedsWAL(relation) && \ + (IsCatalogRelation(relation) || RelationIsUsedAsCatalogTable(relation))) + +/* + * RelationIsLogicallyLogged + * True if we need to log enough information to extract the data from the + * WAL stream. + * + * We don't log information for unlogged tables (since they don't WAL log + * anyway) and for system tables (their content is hard to make sense of, and + * it would complicate decoding slightly for little gain). Note that we *do* + * log information for user defined catalog tables since they presumably are + * interesting to the user... + */ +#define RelationIsLogicallyLogged(relation) \ + (XLogLogicalInfoActive() && \ + RelationNeedsWAL(relation) && \ + !IsCatalogRelation(relation)) + /* routines in utils/cache/relcache.c */ extern void RelationIncrementReferenceCount(Relation rel); extern void RelationDecrementReferenceCount(Relation rel); diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 2f39486c97..e4ca70f140 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -4,7 +4,7 @@ * Relation descriptor cache definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relcache.h @@ -23,7 +23,7 @@ typedef struct RelationData *Relation; /* ---------------- * RelationPtr is used in the executor to support index scans * where we have to keep track of several index relations in an - * array. -cim 9/10/89 + * array. -cim 9/10/89 * ---------------- */ typedef Relation *RelationPtr; @@ -39,9 +39,20 @@ extern void RelationClose(Relation relation); */ extern List *RelationGetIndexList(Relation relation); extern Oid RelationGetOidIndex(Relation relation); +extern Oid RelationGetReplicaIndex(Relation relation); extern List *RelationGetIndexExpressions(Relation relation); extern List *RelationGetIndexPredicate(Relation relation); -extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation); + +typedef enum IndexAttrBitmapKind +{ + INDEX_ATTR_BITMAP_ALL, + INDEX_ATTR_BITMAP_KEY, + INDEX_ATTR_BITMAP_IDENTITY_KEY +} IndexAttrBitmapKind; + +extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, + IndexAttrBitmapKind keyAttrs); + extern void RelationGetExclusionInfo(Relation indexRelation, Oid **operators, Oid **procs, @@ -53,6 +64,14 @@ extern void RelationSetIndexList(Relation relation, extern void RelationInitIndexAccessInfo(Relation relation); /* + * Routines to support ereport() reports of relation-related errors + */ +extern int errtable(Relation rel); +extern int errtablecol(Relation rel, int attnum); +extern int errtablecolname(Relation rel, const char *colname); +extern int errtableconstraint(Relation rel, const char *conname); + +/* * Routines for backend startup */ extern void RelationCacheInitialize(void); @@ -70,13 +89,14 @@ extern Relation RelationBuildLocalRelation(const char *relname, Oid reltablespace, bool shared_relation, bool mapped_relation, - char relpersistence); + char relpersistence, + char relkind); /* * Routine to manage assignment of new relfilenode to a relation */ extern void RelationSetNewRelfilenode(Relation relation, - TransactionId freezeXid); + TransactionId freezeXid, MultiXactId minmulti); /* * Routines for flushing/rebuilding relcache entries in various scenarios diff --git a/src/include/utils/relfilenodemap.h b/src/include/utils/relfilenodemap.h new file mode 100644 index 0000000000..a98791d8a3 --- /dev/null +++ b/src/include/utils/relfilenodemap.h @@ -0,0 +1,18 @@ +/*------------------------------------------------------------------------- + * + * relfilenodemap.h + * relfilenode to oid mapping cache. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/relfilenodemap.h + * + *------------------------------------------------------------------------- + */ +#ifndef RELFILENODEMAP_H +#define RELFILENODEMAP_H + +extern Oid RelidByRelfilenode(Oid reltablespace, Oid relfilenode); + +#endif /* RELFILENODEMAP_H */ diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h index 111a05c46a..2452c94352 100644 --- a/src/include/utils/relmapper.h +++ b/src/include/utils/relmapper.h @@ -4,7 +4,7 @@ * Catalog-to-filenode mapping * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relmapper.h @@ -36,6 +36,8 @@ typedef struct xl_relmap_update extern Oid RelationMapOidToFilenode(Oid relationId, bool shared); +extern Oid RelationMapFilenodeToOid(Oid relationId, bool shared); + extern void RelationMapUpdateMap(Oid relationId, Oid fileNode, bool shared, bool immediate); diff --git a/src/include/utils/reltrigger.h b/src/include/utils/reltrigger.h index b38d41b9bf..765f15df29 100644 --- a/src/include/utils/reltrigger.h +++ b/src/include/utils/reltrigger.h @@ -4,7 +4,7 @@ * POSTGRES relation trigger definitions. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/reltrigger.h @@ -70,5 +70,4 @@ typedef struct TriggerDesc bool trig_truncate_after_statement; } TriggerDesc; - #endif /* RELTRIGGER_H */ diff --git a/src/include/utils/resowner.h b/src/include/utils/resowner.h index 4ac4a2bbaa..e448e911a6 100644 --- a/src/include/utils/resowner.h +++ b/src/include/utils/resowner.h @@ -9,7 +9,7 @@ * See utils/resowner/README for more info. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/resowner.h @@ -19,11 +19,6 @@ #ifndef RESOWNER_H #define RESOWNER_H -#include "storage/fd.h" -#include "utils/catcache.h" -#include "utils/plancache.h" -#include "utils/snapshot.h" - /* * ResourceOwner objects are an opaque data structure known only within @@ -41,7 +36,7 @@ extern PGDLLIMPORT ResourceOwner TopTransactionResourceOwner; /* * Resource releasing is done in three phases: pre-locks, locks, and - * post-locks. The pre-lock phase must release any resources that are + * post-locks. The pre-lock phase must release any resources that are * visible to other backends (such as pinned buffers); this ensures that * when we release a lock that another backend may be waiting on, it will * see us as being fully out of our transaction. The post-lock phase @@ -84,65 +79,4 @@ extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg); -/* support for buffer refcount management */ -extern void ResourceOwnerEnlargeBuffers(ResourceOwner owner); -extern void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer); -extern void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer); - -/* support for catcache refcount management */ -extern void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner); -extern void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, - HeapTuple tuple); -extern void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, - HeapTuple tuple); -extern void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner); -extern void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, - CatCList *list); -extern void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, - CatCList *list); - -/* support for relcache refcount management */ -extern void ResourceOwnerEnlargeRelationRefs(ResourceOwner owner); -extern void ResourceOwnerRememberRelationRef(ResourceOwner owner, - Relation rel); -extern void ResourceOwnerForgetRelationRef(ResourceOwner owner, - Relation rel); - -/* support for plancache refcount management */ -extern void ResourceOwnerEnlargePlanCacheRefs(ResourceOwner owner); -extern void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, - CachedPlan *plan); -extern void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, - CachedPlan *plan); - -/* support for tupledesc refcount management */ -extern void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner); -extern void ResourceOwnerRememberTupleDesc(ResourceOwner owner, - TupleDesc tupdesc); -extern void ResourceOwnerForgetTupleDesc(ResourceOwner owner, - TupleDesc tupdesc); - -/* support for snapshot refcount management */ -extern void ResourceOwnerEnlargeSnapshots(ResourceOwner owner); -extern void ResourceOwnerRememberSnapshot(ResourceOwner owner, - Snapshot snapshot); -extern void ResourceOwnerForgetSnapshot(ResourceOwner owner, - Snapshot snapshot); - -/* support for temporary file management */ -extern void ResourceOwnerEnlargeFiles(ResourceOwner owner); -extern void ResourceOwnerRememberFile(ResourceOwner owner, - File file); -extern void ResourceOwnerForgetFile(ResourceOwner owner, - File file); - -#ifdef XCP -/* support for prepared statement management */ -extern void ResourceOwnerEnlargePreparedStmts(ResourceOwner owner); -extern void ResourceOwnerRememberPreparedStmt(ResourceOwner owner, - char *stmt); -extern void ResourceOwnerForgetPreparedStmt(ResourceOwner owner, - char *stmt); -#endif - #endif /* RESOWNER_H */ diff --git a/src/include/utils/resowner_private.h b/src/include/utils/resowner_private.h new file mode 100644 index 0000000000..d00ae499ed --- /dev/null +++ b/src/include/utils/resowner_private.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------- + * + * resowner_private.h + * POSTGRES resource owner private definitions. + * + * See utils/resowner/README for more info. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/resowner_private.h + * + *------------------------------------------------------------------------- + */ +#ifndef RESOWNER_PRIVATE_H +#define RESOWNER_PRIVATE_H + +#include "storage/dsm.h" +#include "storage/fd.h" +#include "storage/lock.h" +#include "utils/catcache.h" +#include "utils/plancache.h" +#include "utils/resowner.h" +#include "utils/snapshot.h" + + +/* support for buffer refcount management */ +extern void ResourceOwnerEnlargeBuffers(ResourceOwner owner); +extern void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer); +extern void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer); + +/* support for local lock management */ +extern void ResourceOwnerRememberLock(ResourceOwner owner, LOCALLOCK *locallock); +extern void ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock); + +/* support for catcache refcount management */ +extern void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner); +extern void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, + HeapTuple tuple); +extern void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, + HeapTuple tuple); +extern void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner); +extern void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, + CatCList *list); +extern void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, + CatCList *list); + +/* support for relcache refcount management */ +extern void ResourceOwnerEnlargeRelationRefs(ResourceOwner owner); +extern void ResourceOwnerRememberRelationRef(ResourceOwner owner, + Relation rel); +extern void ResourceOwnerForgetRelationRef(ResourceOwner owner, + Relation rel); + +/* support for plancache refcount management */ +extern void ResourceOwnerEnlargePlanCacheRefs(ResourceOwner owner); +extern void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, + CachedPlan *plan); +extern void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, + CachedPlan *plan); + +/* support for tupledesc refcount management */ +extern void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner); +extern void ResourceOwnerRememberTupleDesc(ResourceOwner owner, + TupleDesc tupdesc); +extern void ResourceOwnerForgetTupleDesc(ResourceOwner owner, + TupleDesc tupdesc); + +/* support for snapshot refcount management */ +extern void ResourceOwnerEnlargeSnapshots(ResourceOwner owner); +extern void ResourceOwnerRememberSnapshot(ResourceOwner owner, + Snapshot snapshot); +extern void ResourceOwnerForgetSnapshot(ResourceOwner owner, + Snapshot snapshot); + +/* support for temporary file management */ +extern void ResourceOwnerEnlargeFiles(ResourceOwner owner); +extern void ResourceOwnerRememberFile(ResourceOwner owner, + File file); +extern void ResourceOwnerForgetFile(ResourceOwner owner, + File file); + +/* support for dynamic shared memory management */ +extern void ResourceOwnerEnlargeDSMs(ResourceOwner owner); +extern void ResourceOwnerRememberDSM(ResourceOwner owner, + dsm_segment *); +extern void ResourceOwnerForgetDSM(ResourceOwner owner, + dsm_segment *); + +#ifdef XCP +/* support for prepared statement management */ +extern void ResourceOwnerEnlargePreparedStmts(ResourceOwner owner); +extern void ResourceOwnerRememberPreparedStmt(ResourceOwner owner, + char *stmt); +extern void ResourceOwnerForgetPreparedStmt(ResourceOwner owner, + char *stmt); +#endif + +#endif /* RESOWNER_PRIVATE_H */ diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h index 87c6554b32..0f662ec8bb 100644 --- a/src/include/utils/selfuncs.h +++ b/src/include/utils/selfuncs.h @@ -5,7 +5,7 @@ * standard operators and index access methods. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/selfuncs.h @@ -23,7 +23,7 @@ /* * Note: the default selectivity estimates are not chosen entirely at random. * We want them to be small enough to ensure that indexscans will be used if - * available, for typical table densities of ~100 tuples/page. Thus, for + * available, for typical table densities of ~100 tuples/page. Thus, for * example, 0.01 is not quite small enough, since that makes it appear that * nearly all pages will be hit anyway. Also, since we sometimes estimate * eqsel as 1/num_distinct, we probably want DEFAULT_NUM_DISTINCT to equal @@ -134,7 +134,7 @@ extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation, Const **prefix, - Const **rest); + Selectivity *rest_selec); extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation); diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h index f195981771..abe7016d04 100644 --- a/src/include/utils/snapmgr.h +++ b/src/include/utils/snapmgr.h @@ -3,7 +3,7 @@ * snapmgr.h * POSTGRES snapshot manager * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/snapmgr.h @@ -13,7 +13,9 @@ #ifndef SNAPMGR_H #define SNAPMGR_H +#include "fmgr.h" #include "utils/resowner.h" +#include "utils/snapshot.h" extern bool FirstSnapshotSet; @@ -21,11 +23,16 @@ extern bool FirstSnapshotSet; extern TransactionId TransactionXmin; extern TransactionId RecentXmin; extern TransactionId RecentGlobalXmin; +extern TransactionId RecentGlobalDataXmin; extern Snapshot GetTransactionSnapshot(void); extern Snapshot GetLatestSnapshot(void); extern void SnapshotSetCommandId(CommandId curcid); +extern Snapshot GetCatalogSnapshot(Oid relid); +extern Snapshot GetNonHistoricCatalogSnapshot(Oid relid); +extern void InvalidateCatalogSnapshot(void); + extern void PushActiveSnapshot(Snapshot snapshot); extern void PushCopiedSnapshot(Snapshot snapshot); extern void UpdateActiveSnapshotCommandId(void); @@ -46,5 +53,15 @@ extern Datum pg_export_snapshot(PG_FUNCTION_ARGS); extern void ImportSnapshot(const char *idstr); extern bool XactHasExportedSnapshots(void); extern void DeleteAllExportedSnapshotFiles(void); +extern bool ThereAreNoPriorRegisteredSnapshots(void); + +extern char *ExportSnapshot(Snapshot snapshot); + +/* Support for catalog timetravel for logical decoding */ +struct HTAB; +extern struct HTAB *HistoricSnapshotGetTupleCids(void); +extern void SetupHistoricSnapshot(Snapshot snapshot_now, struct HTAB *tuplecids); +extern void TeardownHistoricSnapshot(bool is_error); +extern bool HistoricSnapshotActive(void); #endif /* SNAPMGR_H */ diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h index 3747edb6c2..cfc70f9e50 100644 --- a/src/include/utils/snapshot.h +++ b/src/include/utils/snapshot.h @@ -3,7 +3,7 @@ * snapshot.h * POSTGRES snapshot definition * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -28,9 +28,25 @@ typedef struct SnapshotData *Snapshot; * The specific semantics of a snapshot are encoded by the "satisfies" * function. */ -typedef bool (*SnapshotSatisfiesFunc) (HeapTupleHeader tuple, +typedef bool (*SnapshotSatisfiesFunc) (HeapTuple htup, Snapshot snapshot, Buffer buffer); +/* + * Struct representing all kind of possible snapshots. + * + * There are several different kinds of snapshots: + * * Normal MVCC snapshots + * * MVCC snapshots taken during recovery (in Hot-Standby mode) + * * Historic MVCC snapshots used during logical decoding + * * snapshots passed to HeapTupleSatisfiesDirty() + * * snapshots used for SatisfiesAny, Toast, Self where no members are + * accessed. + * + * TODO: It's probably a good idea to split this struct using a NodeTag + * similar to how parser and executor nodes are handled, with one type for + * each different kind of snapshot to avoid overloading the meaning of + * individual fields. + */ typedef struct SnapshotData { SnapshotSatisfiesFunc satisfies; /* tuple test function */ @@ -47,14 +63,28 @@ typedef struct SnapshotData */ TransactionId xmin; /* all XID < xmin are visible to me */ TransactionId xmax; /* all XID >= xmax are invisible to me */ - TransactionId *xip; /* array of xact IDs in progress */ + + /* + * For normal MVCC snapshot this contains the all xact IDs that are in + * progress, unless the snapshot was taken during recovery in which case + * it's empty. For historic MVCC snapshots, the meaning is inverted, i.e. + * it contains *committed* transactions between xmin and xmax. + */ + TransactionId *xip; uint32 xcnt; /* # of xact ids in xip[] */ #ifdef PGXC /* PGXC_COORD */ uint32 max_xcnt; /* Max # of xact in xip[] */ #endif /* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */ int32 subxcnt; /* # of xact ids in subxip[] */ - TransactionId *subxip; /* array of subxact IDs in progress */ + + /* + * For non-historic MVCC snapshots, this contains subxact IDs that are in + * progress (and other transactions that are in progress if taken during + * recovery). For historic snapshot it contains *all* xids assigned to the + * replayed transaction, including the toplevel xid. + */ + TransactionId *subxip; bool suboverflowed; /* has the subxip array overflowed? */ bool takenDuringRecovery; /* recovery-shaped snapshot? */ bool copied; /* false if it's a static snapshot */ diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h index 720a54c0d7..8b6b0de2e8 100644 --- a/src/include/utils/sortsupport.h +++ b/src/include/utils/sortsupport.h @@ -33,11 +33,11 @@ * * Note: since pg_amproc functions are indexed by (lefttype, righttype) * it is possible to associate a BTSORTSUPPORT function with a cross-type - * comparison. This could sensibly be used to provide a fast comparator + * comparison. This could sensibly be used to provide a fast comparator * function for such cases, but probably not any other acceleration method. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/sortsupport.h @@ -101,14 +101,21 @@ typedef struct SortSupportData } SortSupportData; -/* ApplySortComparator should be inlined if possible */ -#ifdef USE_INLINE - +/* + * ApplySortComparator should be inlined if possible. See STATIC_IF_INLINE + * in c.h. + */ +#ifndef PG_USE_INLINE +extern int ApplySortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup); +#endif /* !PG_USE_INLINE */ +#if defined(PG_USE_INLINE) || defined(SORTSUPPORT_INCLUDE_DEFINITIONS) /* * Apply a sort comparator function and return a 3-way comparison result. * This takes care of handling reverse-sort and NULLs-ordering properly. */ -static inline int +STATIC_IF_INLINE int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup) @@ -140,12 +147,7 @@ ApplySortComparator(Datum datum1, bool isNull1, return compare; } -#else - -extern int ApplySortComparator(Datum datum1, bool isNull1, - Datum datum2, bool isNull2, - SortSupport ssup); -#endif /* USE_INLINE */ +#endif /*-- PG_USE_INLINE || SORTSUPPORT_INCLUDE_DEFINITIONS */ /* Other functions in utils/sort/sortsupport.c */ extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup); diff --git a/src/include/utils/spccache.h b/src/include/utils/spccache.h index 8906a40d0c..babcefd0cc 100644 --- a/src/include/utils/spccache.h +++ b/src/include/utils/spccache.h @@ -3,7 +3,7 @@ * spccache.h * Tablespace cache. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/spccache.h diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index f1380983e3..b033c6e88e 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -6,7 +6,7 @@ * See also lsyscache.h, which provides convenience routines for * common cache-lookup operations. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2010-2012 Postgres-XC Development Group * @@ -17,7 +17,9 @@ #ifndef SYSCACHE_H #define SYSCACHE_H -#include "utils/catcache.h" +#include "access/attnum.h" +#include "access/htup.h" +/* we purposedly do not include utils/catcache.h here */ /* * SysCache identifiers. @@ -55,6 +57,8 @@ enum SysCacheIdentifier DEFACLROLENSPOBJ, ENUMOID, ENUMTYPOIDNAME, + EVENTTRIGGERNAME, + EVENTTRIGGEROID, FOREIGNDATAWRAPPERNAME, FOREIGNDATAWRAPPEROID, FOREIGNSERVERNAME, @@ -126,9 +130,13 @@ extern uint32 GetSysCacheHashValue(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4); /* list-search interface. Users of this must import catcache.h too */ +struct catclist; extern struct catclist *SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3, Datum key4); +extern bool RelationInvalidatesSnapshotsOnly(Oid); +extern bool RelationHasSysCache(Oid); + /* * The use of the macros below rather than direct calls to the corresponding * functions is encouraged, as it insulates the caller from changes in the diff --git a/src/include/utils/timeout.h b/src/include/utils/timeout.h new file mode 100644 index 0000000000..814fbf35f5 --- /dev/null +++ b/src/include/utils/timeout.h @@ -0,0 +1,84 @@ +/*------------------------------------------------------------------------- + * + * timeout.h + * Routines to multiplex SIGALRM interrupts for multiple timeout reasons. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/utils/timeout.h + * + *------------------------------------------------------------------------- + */ +#ifndef TIMEOUT_H +#define TIMEOUT_H + +#include "datatype/timestamp.h" + +/* + * Identifiers for timeout reasons. Note that in case multiple timeouts + * trigger at the same time, they are serviced in the order of this enum. + */ +typedef enum TimeoutId +{ + /* Predefined timeout reasons */ + STARTUP_PACKET_TIMEOUT, + DEADLOCK_TIMEOUT, + LOCK_TIMEOUT, + STATEMENT_TIMEOUT, + STANDBY_DEADLOCK_TIMEOUT, + STANDBY_TIMEOUT, + /* First user-definable timeout reason */ + USER_TIMEOUT, + /* Maximum number of timeout reasons */ + MAX_TIMEOUTS = 16 +} TimeoutId; + +/* callback function signature */ +typedef void (*timeout_handler_proc) (void); + +/* + * Parameter structure for setting multiple timeouts at once + */ +typedef enum TimeoutType +{ + TMPARAM_AFTER, + TMPARAM_AT +} TimeoutType; + +typedef struct +{ + TimeoutId id; /* timeout to set */ + TimeoutType type; /* TMPARAM_AFTER or TMPARAM_AT */ + int delay_ms; /* only used for TMPARAM_AFTER */ + TimestampTz fin_time; /* only used for TMPARAM_AT */ +} EnableTimeoutParams; + +/* + * Parameter structure for clearing multiple timeouts at once + */ +typedef struct +{ + TimeoutId id; /* timeout to clear */ + bool keep_indicator; /* keep the indicator flag? */ +} DisableTimeoutParams; + +/* timeout setup */ +extern void InitializeTimeouts(void); +extern TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler); +extern void reschedule_timeouts(void); + +/* timeout operation */ +extern void enable_timeout_after(TimeoutId id, int delay_ms); +extern void enable_timeout_at(TimeoutId id, TimestampTz fin_time); +extern void enable_timeouts(const EnableTimeoutParams *timeouts, int count); +extern void disable_timeout(TimeoutId id, bool keep_indicator); +extern void disable_timeouts(const DisableTimeoutParams *timeouts, int count); +extern void disable_all_timeouts(bool keep_indicators); + +/* accessors */ +extern bool get_timeout_indicator(TimeoutId id, bool reset_indicator); +extern TimestampTz get_timeout_start_time(TimeoutId id); + +#endif /* TIMEOUT_H */ diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 561c6f8ccf..36bb61a59b 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * timestamp.h - * Definitions for the SQL92 "timestamp" and "interval" types. + * Definitions for the SQL "timestamp" and "interval" types. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/timestamp.h @@ -124,6 +124,10 @@ extern Datum timestamp_gt_timestamptz(PG_FUNCTION_ARGS); extern Datum timestamp_ge_timestamptz(PG_FUNCTION_ARGS); extern Datum timestamp_cmp_timestamptz(PG_FUNCTION_ARGS); +extern Datum make_timestamp(PG_FUNCTION_ARGS); +extern Datum make_timestamptz(PG_FUNCTION_ARGS); +extern Datum make_timestamptz_at_timezone(PG_FUNCTION_ARGS); + extern Datum timestamptz_eq_timestamp(PG_FUNCTION_ARGS); extern Datum timestamptz_ne_timestamp(PG_FUNCTION_ARGS); extern Datum timestamptz_lt_timestamp(PG_FUNCTION_ARGS); @@ -154,6 +158,7 @@ extern Datum interval_larger(PG_FUNCTION_ARGS); extern Datum interval_justify_interval(PG_FUNCTION_ARGS); extern Datum interval_justify_hours(PG_FUNCTION_ARGS); extern Datum interval_justify_days(PG_FUNCTION_ARGS); +extern Datum make_interval(PG_FUNCTION_ARGS); extern Datum timestamp_trunc(PG_FUNCTION_ARGS); extern Datum interval_trunc(PG_FUNCTION_ARGS); @@ -185,6 +190,7 @@ extern Datum interval_accum(PG_FUNCTION_ARGS); #ifdef PGXC extern Datum interval_collect(PG_FUNCTION_ARGS); #endif +extern Datum interval_accum_inv(PG_FUNCTION_ARGS); extern Datum interval_avg(PG_FUNCTION_ARGS); extern Datum timestamp_mi(PG_FUNCTION_ARGS); @@ -212,13 +218,24 @@ extern Datum generate_series_timestamptz(PG_FUNCTION_ARGS); /* Internal routines (not fmgr-callable) */ extern TimestampTz GetCurrentTimestamp(void); - extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs); extern bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec); +/* + * Prototypes for functions to deal with integer timestamps, when the native + * format is float timestamps. + */ +#ifndef HAVE_INT64_TIMESTAMP +extern int64 GetCurrentIntegerTimestamp(void); +extern TimestampTz IntegerTimestampToTimestampTz(int64 timestamp); +#else +#define GetCurrentIntegerTimestamp() GetCurrentTimestamp() +#define IntegerTimestampToTimestampTz(timestamp) (timestamp) +#endif + extern TimestampTz time_t_to_timestamptz(pg_time_t tm); extern pg_time_t timestamptz_to_time_t(TimestampTz t); @@ -242,7 +259,7 @@ extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2); extern int isoweek2j(int year, int week); extern void isoweek2date(int woy, int *year, int *mon, int *mday); -extern void isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday); +extern void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday); extern int date2isoweek(int year, int mon, int mday); extern int date2isoyear(int year, int mon, int mday); extern int date2isoyearday(int year, int mon, int mday); diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h index ff74f868a6..ae285c3ed5 100644 --- a/src/include/utils/tqual.h +++ b/src/include/utils/tqual.h @@ -3,9 +3,9 @@ * tqual.h * POSTGRES "time qualification" definitions, ie, tuple visibility rules. * - * Should be moved/renamed... - vadim 07/28/98 + * Should be moved/renamed... - vadim 07/28/98 * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tqual.h @@ -19,12 +19,11 @@ /* Static variables representing various special snapshot semantics */ -extern PGDLLIMPORT SnapshotData SnapshotNowData; extern PGDLLIMPORT SnapshotData SnapshotSelfData; extern PGDLLIMPORT SnapshotData SnapshotAnyData; extern PGDLLIMPORT SnapshotData SnapshotToastData; +extern PGDLLIMPORT SnapshotData CatalogSnapshotData; -#define SnapshotNow (&SnapshotNowData) #define SnapshotSelf (&SnapshotSelfData) #define SnapshotAny (&SnapshotAnyData) #define SnapshotToast (&SnapshotToastData) @@ -39,7 +38,8 @@ extern PGDLLIMPORT SnapshotData SnapshotToastData; /* This macro encodes the knowledge of which snapshots are MVCC-safe */ #define IsMVCCSnapshot(snapshot) \ - ((snapshot)->satisfies == HeapTupleSatisfiesMVCC) + ((snapshot)->satisfies == HeapTupleSatisfiesMVCC || \ + (snapshot)->satisfies == HeapTupleSatisfiesHistoricMVCC) /* * HeapTupleSatisfiesVisibility @@ -52,7 +52,7 @@ extern PGDLLIMPORT SnapshotData SnapshotToastData; * if so, the indicated buffer is marked dirty. */ #define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \ - ((*(snapshot)->satisfies) ((tuple)->t_data, snapshot, buffer)) + ((*(snapshot)->satisfies) (tuple, snapshot, buffer)) /* Result codes for HeapTupleSatisfiesVacuum */ typedef enum @@ -65,28 +65,38 @@ typedef enum } HTSV_Result; /* These are the "satisfies" test routines for the various snapshot types */ -extern bool HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, +extern bool HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesSelf(HeapTupleHeader tuple, +extern bool HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesAny(HeapTupleHeader tuple, +extern bool HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple, +extern bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple, +extern bool HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, + Snapshot snapshot, Buffer buffer); /* Special "satisfies" routines with different APIs */ -extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, +extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, Buffer buffer); -extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, +extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, Buffer buffer); -extern bool HeapTupleIsSurelyDead(HeapTupleHeader tuple, +extern bool HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin); extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, uint16 infomask, TransactionId xid); +extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); +/* + * To avoid leaking to much knowledge about reorderbuffer implementation + * details this is implemented in reorderbuffer.c not tqual.c. + */ +extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data, + Snapshot snapshot, + HeapTuple htup, + Buffer buffer, + CommandId *cmin, CommandId *cmax); #endif /* TQUAL_H */ diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h index 6c0d024cd0..7fc0d9de02 100644 --- a/src/include/utils/tuplesort.h +++ b/src/include/utils/tuplesort.h @@ -6,7 +6,7 @@ * This module handles sorting of heap tuples, index tuples, or single * Datums (and could easily support other kinds of sortable objects, * if necessary). It works efficiently for both small and large amounts - * of data. Small amounts are sorted in-memory using qsort(). Large + * of data. Small amounts are sorted in-memory using qsort(). Large * amounts are sorted using temporary files and a standard external sort * algorithm. * @@ -15,7 +15,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tuplesort.h @@ -49,9 +49,9 @@ typedef struct Tuplesortstate Tuplesortstate; * The "heap" API actually stores/sorts MinimalTuples, which means it doesn't * preserve the system columns (tuple identity and transaction visibility * info). The sort keys are specified by column numbers within the tuples - * and sort operator OIDs. We save some cycles by passing and returning the + * and sort operator OIDs. We save some cycles by passing and returning the * tuples in TupleTableSlots, rather than forming actual HeapTuples (which'd - * have to be converted to MinimalTuples). This API works well for sorts + * have to be converted to MinimalTuples). This API works well for sorts * executed as parts of plan trees. * * The "cluster" API stores/sorts full HeapTuples including all visibility @@ -60,7 +60,7 @@ typedef struct Tuplesortstate Tuplesortstate; * go with this API, not the "begin_heap" one! * * The "index_btree" API stores/sorts IndexTuples (preserving all their - * header fields). The sort keys are specified by a btree index definition. + * header fields). The sort keys are specified by a btree index definition. * * The "index_hash" API is similar to index_btree, but the tuples are * actually sorted by their hash codes not the raw data. @@ -74,10 +74,12 @@ extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc, extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc, Relation indexRel, int workMem, bool randomAccess); -extern Tuplesortstate *tuplesort_begin_index_btree(Relation indexRel, +extern Tuplesortstate *tuplesort_begin_index_btree(Relation heapRel, + Relation indexRel, bool enforceUnique, int workMem, bool randomAccess); -extern Tuplesortstate *tuplesort_begin_index_hash(Relation indexRel, +extern Tuplesortstate *tuplesort_begin_index_hash(Relation heapRel, + Relation indexRel, uint32 hash_mask, int workMem, bool randomAccess); extern Tuplesortstate *tuplesort_begin_datum(Oid datumType, @@ -116,6 +118,9 @@ extern IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward, extern bool tuplesort_getdatum(Tuplesortstate *state, bool forward, Datum *val, bool *isNull); +extern bool tuplesort_skiptuples(Tuplesortstate *state, int64 ntuples, + bool forward); + extern void tuplesort_end(Tuplesortstate *state); extern void tuplesort_get_stats(Tuplesortstate *state, @@ -123,7 +128,7 @@ extern void tuplesort_get_stats(Tuplesortstate *state, const char **spaceType, long *spaceUsed); -extern int tuplesort_merge_order(long allowedMem); +extern int tuplesort_merge_order(int64 allowedMem); /* * These routines may only be called if randomAccess was specified 'true'. diff --git a/src/include/utils/tuplestore.h b/src/include/utils/tuplestore.h index 53c56ceea3..694507193f 100644 --- a/src/include/utils/tuplestore.h +++ b/src/include/utils/tuplestore.h @@ -8,7 +8,7 @@ * a dumbed-down version of tuplesort.c; it does no sorting of tuples * but can only store and regurgitate a sequence of tuples. However, * because no sort is required, it is allowed to start reading the sequence - * before it has all been written. This is particularly useful for cursors, + * before it has all been written. This is particularly useful for cursors, * because it allows random access within the already-scanned portion of * a query without having to process the underlying scan to completion. * Also, it is possible to support multiple independent read pointers. @@ -26,7 +26,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Portions Copyright (c) 2012-2014, TransLattice, Inc. - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tuplestore.h @@ -77,8 +77,12 @@ extern bool tuplestore_in_memory(Tuplestorestate *state); extern bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, bool copy, TupleTableSlot *slot); + extern bool tuplestore_advance(Tuplestorestate *state, bool forward); +extern bool tuplestore_skiptuples(Tuplestorestate *state, + int64 ntuples, bool forward); + extern bool tuplestore_ateof(Tuplestorestate *state); extern void tuplestore_rescan(Tuplestorestate *state); diff --git a/src/include/utils/typcache.h b/src/include/utils/typcache.h index 12fb4f8310..ae1fc9c632 100644 --- a/src/include/utils/typcache.h +++ b/src/include/utils/typcache.h @@ -6,7 +6,7 @@ * The type cache exists to speed lookup of certain information about data * types that is not directly available from a type's pg_type row. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/typcache.h @@ -56,7 +56,7 @@ typedef struct TypeCacheEntry /* * Pre-set-up fmgr call info for the equality operator, the btree - * comparison function, and the hash calculation function. These are kept + * comparison function, and the hash calculation function. These are kept * in the type cache to avoid problems with memory leaks in repeated calls * to functions such as array_eq, array_cmp, hash_array. There is not * currently a need to maintain call info for the lt_opr or gt_opr. @@ -73,7 +73,7 @@ typedef struct TypeCacheEntry TupleDesc tupDesc; /* - * Fields computed when TYPECACHE_RANGE_INFO is requested. Zeroes if not + * Fields computed when TYPECACHE_RANGE_INFO is requested. Zeroes if not * a range type or information hasn't yet been requested. Note that * rng_cmp_proc_finfo could be different from the element type's default * btree comparison function. @@ -88,7 +88,7 @@ typedef struct TypeCacheEntry int flags; /* flags about what we've computed */ /* - * Private information about an enum type. NULL if not enum or + * Private information about an enum type. NULL if not enum or * information hasn't been requested. */ struct TypeCacheEnumData *enumData; diff --git a/src/include/utils/tzparser.h b/src/include/utils/tzparser.h index 7f238da644..82728a67dd 100644 --- a/src/include/utils/tzparser.h +++ b/src/include/utils/tzparser.h @@ -3,7 +3,7 @@ * tzparser.h * Timezone offset file parsing definitions. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tzparser.h diff --git a/src/include/utils/uuid.h b/src/include/utils/uuid.h index a05e681e1f..0afc1992d2 100644 --- a/src/include/utils/uuid.h +++ b/src/include/utils/uuid.h @@ -5,7 +5,7 @@ * to avoid conflicts with any uuid_t type that might be defined by * the system headers. * - * Copyright (c) 2007-2012, PostgreSQL Global Development Group + * Copyright (c) 2007-2014, PostgreSQL Global Development Group * * src/include/utils/uuid.h * diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h index 52dca8b5d2..974de7db09 100644 --- a/src/include/utils/varbit.h +++ b/src/include/utils/varbit.h @@ -5,7 +5,7 @@ * * Code originally contributed by Adriaan Joubert. * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/varbit.h @@ -15,6 +15,8 @@ #ifndef VARBIT_H #define VARBIT_H +#include <limits.h> + #include "fmgr.h" /* @@ -53,6 +55,11 @@ typedef struct /* Number of bytes needed to store a bit string of a given length */ #define VARBITTOTALLEN(BITLEN) (((BITLEN) + BITS_PER_BYTE-1)/BITS_PER_BYTE + \ VARHDRSZ + VARBITHDRSZ) +/* + * Maximum number of bits. Several code sites assume no overflow from + * computing bitlen + X; VARBITTOTALLEN() has the largest such X. + */ +#define VARBITMAXLEN (INT_MAX - BITS_PER_BYTE + 1) /* pointer beyond the end of the bit string (like end() in STL containers) */ #define VARBITEND(PTR) (((bits8 *) (PTR)) + VARSIZE(PTR)) /* Mask that will cover exactly one byte, i.e. BITS_PER_BYTE bits */ diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h index a645af918c..24ea9a0914 100644 --- a/src/include/utils/xml.h +++ b/src/include/utils/xml.h @@ -4,7 +4,7 @@ * Declarations for XML data type support. * * - * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/xml.h diff --git a/src/include/windowapi.h b/src/include/windowapi.h index e4e466da7e..8557464643 100644 --- a/src/include/windowapi.h +++ b/src/include/windowapi.h @@ -19,7 +19,7 @@ * function in nodeWindowAgg.c for details. * * - * Portions Copyright (c) 2000-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2014, PostgreSQL Global Development Group * * src/include/windowapi.h * |