diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_aggregate.dat | 10 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 10 | ||||
-rw-r--r-- | src/include/nodes/pathnodes.h | 140 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 9 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 1 | ||||
-rw-r--r-- | src/include/optimizer/extendplan.h | 72 | ||||
-rw-r--r-- | src/include/optimizer/geqo.h | 12 | ||||
-rw-r--r-- | src/include/optimizer/optimizer.h | 5 | ||||
-rw-r--r-- | src/include/optimizer/pathnode.h | 4 | ||||
-rw-r--r-- | src/include/optimizer/paths.h | 4 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 1 | ||||
-rw-r--r-- | src/include/optimizer/planner.h | 25 | ||||
-rw-r--r-- | src/include/pgstat.h | 4 | ||||
-rw-r--r-- | src/include/replication/reorderbuffer.h | 3 | ||||
-rw-r--r-- | src/include/storage/buf_internals.h | 4 | ||||
-rw-r--r-- | src/include/storage/bufmgr.h | 3 | ||||
-rw-r--r-- | src/include/tcop/tcopprot.h | 4 | ||||
-rw-r--r-- | src/include/utils/float.h | 67 | ||||
-rw-r--r-- | src/include/utils/pgstat_internal.h | 1 |
20 files changed, 307 insertions, 74 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 642abe5217e..a98c6d6d820 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202510062 +#define CATALOG_VERSION_NO 202510083 #endif diff --git a/src/include/catalog/pg_aggregate.dat b/src/include/catalog/pg_aggregate.dat index d6aa1f6ec47..870769e8f14 100644 --- a/src/include/catalog/pg_aggregate.dat +++ b/src/include/catalog/pg_aggregate.dat @@ -558,26 +558,28 @@ aggfinalfn => 'array_agg_finalfn', aggcombinefn => 'array_agg_combine', aggserialfn => 'array_agg_serialize', aggdeserialfn => 'array_agg_deserialize', aggfinalextra => 't', - aggtranstype => 'internal' }, + aggtranstype => 'internal', aggtransspace => '-1' }, { aggfnoid => 'array_agg(anyarray)', aggtransfn => 'array_agg_array_transfn', aggfinalfn => 'array_agg_array_finalfn', aggcombinefn => 'array_agg_array_combine', aggserialfn => 'array_agg_array_serialize', aggdeserialfn => 'array_agg_array_deserialize', aggfinalextra => 't', - aggtranstype => 'internal' }, + aggtranstype => 'internal', aggtransspace => '-1' }, # text { aggfnoid => 'string_agg(text,text)', aggtransfn => 'string_agg_transfn', aggfinalfn => 'string_agg_finalfn', aggcombinefn => 'string_agg_combine', aggserialfn => 'string_agg_serialize', - aggdeserialfn => 'string_agg_deserialize', aggtranstype => 'internal' }, + aggdeserialfn => 'string_agg_deserialize', + aggtranstype => 'internal', aggtransspace => '-1' }, # bytea { aggfnoid => 'string_agg(bytea,bytea)', aggtransfn => 'bytea_string_agg_transfn', aggfinalfn => 'bytea_string_agg_finalfn', aggcombinefn => 'string_agg_combine', aggserialfn => 'string_agg_serialize', - aggdeserialfn => 'string_agg_deserialize', aggtranstype => 'internal' }, + aggdeserialfn => 'string_agg_deserialize', + aggtranstype => 'internal', aggtransspace => '-1' }, # range { aggfnoid => 'range_intersect_agg(anyrange)', diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 7c20180637f..25687eaecea 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5691,9 +5691,9 @@ { oid => '6169', descr => 'statistics: information about replication slot', proname => 'pg_stat_get_replication_slot', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,text,int8,int8,int8,int8,int8,int8,int8,int8,timestamptz}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{slot_name,slot_name,spill_txns,spill_count,spill_bytes,stream_txns,stream_count,stream_bytes,total_txns,total_bytes,stats_reset}', + proallargtypes => '{text,text,int8,int8,int8,int8,int8,int8,int8,int8,int8,timestamptz}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{slot_name,slot_name,spill_txns,spill_count,spill_bytes,stream_txns,stream_count,stream_bytes,mem_exceeded_count,total_txns,total_bytes,stats_reset}', prosrc => 'pg_stat_get_replication_slot' }, { oid => '6230', descr => 'statistics: check if a stats object exists', @@ -6071,6 +6071,10 @@ proname => 'pg_stat_get_function_self_time', provolatile => 's', proparallel => 'r', prorettype => 'float8', proargtypes => 'oid', prosrc => 'pg_stat_get_function_self_time' }, +{ oid => '8745', descr => 'statistics: last reset for a function', + proname => 'pg_stat_get_function_stat_reset_time', provolatile => 's', + proparallel => 'r', prorettype => 'timestamptz', proargtypes => 'oid', + prosrc => 'pg_stat_get_function_stat_reset_time' }, { oid => '3037', descr => 'statistics: number of scans done for table/index in current transaction', diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index b12a2508d8c..79408743166 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -110,6 +110,9 @@ typedef struct PlannerGlobal /* PlannerInfos for SubPlan nodes */ List *subroots pg_node_attr(read_write_ignore); + /* names already used for subplans (list of C strings) */ + List *subplanNames pg_node_attr(read_write_ignore); + /* indices of subplans that require REWIND */ Bitmapset *rewindPlanIDs; @@ -182,6 +185,10 @@ typedef struct PlannerGlobal /* hash table for NOT NULL attnums of relations */ struct HTAB *rel_notnullatts_hash pg_node_attr(read_write_ignore); + + /* extension state */ + void **extension_state pg_node_attr(read_write_ignore); + int extension_state_allocated; } PlannerGlobal; /* macro for fetching the Plan associated with a SubPlan node */ @@ -228,6 +235,9 @@ struct PlannerInfo /* NULL at outermost Query */ PlannerInfo *parent_root pg_node_attr(read_write_ignore); + /* Subplan name for EXPLAIN and debugging purposes (NULL at top level) */ + char *plan_name; + /* * plan_params contains the expressions that this query level needs to * make available to a lower query level that is currently being planned. @@ -391,6 +401,15 @@ struct PlannerInfo /* list of PlaceHolderInfos */ List *placeholder_list; + /* list of AggClauseInfos */ + List *agg_clause_list; + + /* list of GroupExprInfos */ + List *group_expr_list; + + /* list of plain Vars contained in targetlist and havingQual */ + List *tlist_vars; + /* array of PlaceHolderInfos indexed by phid */ struct PlaceHolderInfo **placeholder_array pg_node_attr(read_write_ignore, array_size(placeholder_array_size)); /* allocated size of array */ @@ -526,6 +545,8 @@ struct PlannerInfo bool placeholdersFrozen; /* true if planning a recursive WITH item */ bool hasRecursion; + /* true if a planner extension may replan this subquery */ + bool assumeReplanning; /* * The rangetable index for the RTE_GROUP RTE, or 0 if there is no @@ -572,14 +593,15 @@ struct PlannerInfo bool *isAltSubplan pg_node_attr(read_write_ignore); bool *isUsedSubplan pg_node_attr(read_write_ignore); - /* optional private data for join_search_hook, e.g., GEQO */ - void *join_search_private pg_node_attr(read_write_ignore); - /* Does this query modify any partition key columns? */ bool partColsUpdated; /* PartitionPruneInfos added in this query's plan. */ List *partPruneInfos; + + /* extension state */ + void **extension_state pg_node_attr(read_write_ignore); + int extension_state_allocated; }; @@ -1041,6 +1063,14 @@ typedef struct RelOptInfo bool consider_partitionwise_join; /* + * used by eager aggregation: + */ + /* information needed to create grouped paths */ + struct RelAggInfo *agg_info; + /* the partially-aggregated version of the relation */ + struct RelOptInfo *grouped_rel; + + /* * inheritance links, if this is an otherrel (otherwise NULL): */ /* Immediate parent relation (dumping it would be too verbose) */ @@ -1091,6 +1121,10 @@ typedef struct RelOptInfo List **partexprs pg_node_attr(read_write_ignore); /* Nullable partition key expressions */ List **nullable_partexprs pg_node_attr(read_write_ignore); + + /* extension state */ + void **extension_state pg_node_attr(read_write_ignore); + int extension_state_allocated; } RelOptInfo; /* @@ -1125,6 +1159,63 @@ typedef struct RelOptInfo bms_equal((sjinfo)->syn_righthand, (rel)->relids)) /* + * Is the given relation a grouped relation? + */ +#define IS_GROUPED_REL(rel) \ + ((rel)->agg_info != NULL) + +/* + * RelAggInfo + * Information needed to create paths for a grouped relation. + * + * "target" is the default result targetlist for Paths scanning this grouped + * relation; list of Vars/Exprs, cost, width. + * + * "agg_input" is the output tlist for the paths that provide input to the + * grouped paths. One difference from the reltarget of the non-grouped + * relation is that agg_input has its sortgrouprefs[] initialized. + * + * "group_clauses" and "group_exprs" are lists of SortGroupClauses and the + * corresponding grouping expressions. + * + * "apply_at" tracks the set of relids at which partial aggregation is applied + * in the paths of this grouped relation. + * + * "grouped_rows" is the estimated number of result tuples of the grouped + * relation. + * + * "agg_useful" is a flag to indicate whether the grouped paths are considered + * useful. It is set true if the average partial group size is no less than + * min_eager_agg_group_size, suggesting a significant row count reduction. + */ +typedef struct RelAggInfo +{ + pg_node_attr(no_copy_equal, no_read, no_query_jumble) + + NodeTag type; + + /* the output tlist for the grouped paths */ + struct PathTarget *target; + + /* the output tlist for the input paths */ + struct PathTarget *agg_input; + + /* a list of SortGroupClauses */ + List *group_clauses; + /* a list of grouping expressions */ + List *group_exprs; + + /* the set of relids partial aggregation is applied at */ + Relids apply_at; + + /* estimated number of result tuples */ + Cardinality grouped_rows; + + /* the grouped paths are considered useful? */ + bool agg_useful; +} RelAggInfo; + +/* * IndexOptInfo * Per-index information for planning/optimization * @@ -3269,6 +3360,49 @@ typedef struct MinMaxAggInfo } MinMaxAggInfo; /* + * For each distinct Aggref node that appears in the targetlist and HAVING + * clauses, we store an AggClauseInfo node in the PlannerInfo node's + * agg_clause_list. Each AggClauseInfo records the set of relations referenced + * by the aggregate expression. This information is used to determine how far + * the aggregate can be safely pushed down in the join tree. + */ +typedef struct AggClauseInfo +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + + /* the Aggref expr */ + Aggref *aggref; + + /* lowest level we can evaluate this aggregate at */ + Relids agg_eval_at; +} AggClauseInfo; + +/* + * For each grouping expression that appears in grouping clauses, we store a + * GroupingExprInfo node in the PlannerInfo node's group_expr_list. Each + * GroupingExprInfo records the expression being grouped on, its sortgroupref, + * and the EquivalenceClass it belongs to. This information is necessary to + * reproduce correct grouping semantics at different levels of the join tree. + */ +typedef struct GroupingExprInfo +{ + pg_node_attr(no_read, no_query_jumble) + + NodeTag type; + + /* the represented expression */ + Expr *expr; + + /* the tleSortGroupRef of the corresponding SortGroupClause */ + Index sortgroupref; + + /* the equivalence class the expression belongs to */ + EquivalenceClass *ec pg_node_attr(copy_as_scalar, equal_as_scalar); +} GroupingExprInfo; + +/* * 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 diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 3d196f5078e..77ec2bc10b2 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -149,6 +149,15 @@ typedef struct PlannedStmt /* non-null if this is utility stmt */ Node *utilityStmt; + /* + * DefElem objects added by extensions, e.g. using planner_shutdown_hook + * + * Set each DefElem's defname to the name of the plugin or extension, and + * the argument to a tree of nodes that all have copy and read/write + * support. + */ + List *extension_state; + /* statement location in source string (copied from Query) */ /* start location, or -1 if unknown */ ParseLoc stmt_location; diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index e9d8bf74145..1b4436f2ff6 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -1108,6 +1108,7 @@ typedef struct SubPlan Oid firstColCollation; /* Collation of first column of subplan * result */ /* Information about execution strategy: */ + bool isInitPlan; /* true if it's an InitPlan */ bool useHashTable; /* true to store subselect output in a hash * table (implies we are doing "IN") */ bool unknownEqFalse; /* true if it's okay to return FALSE when the diff --git a/src/include/optimizer/extendplan.h b/src/include/optimizer/extendplan.h new file mode 100644 index 00000000000..de9618761dd --- /dev/null +++ b/src/include/optimizer/extendplan.h @@ -0,0 +1,72 @@ +/*------------------------------------------------------------------------- + * + * extendplan.h + * Extend core planner objects with additional private state + * + * + * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/extendplan.h + * + *------------------------------------------------------------------------- + */ +#ifndef EXTENDPLAN_H +#define EXTENDPLAN_H + +#include "nodes/pathnodes.h" + +extern int GetPlannerExtensionId(const char *extension_name); + +/* + * Get extension-specific state from a PlannerGlobal. + */ +static inline void * +GetPlannerGlobalExtensionState(PlannerGlobal *glob, int extension_id) +{ + Assert(extension_id >= 0); + + if (extension_id >= glob->extension_state_allocated) + return NULL; + + return glob->extension_state[extension_id]; +} + +/* + * Get extension-specific state from a PlannerInfo. + */ +static inline void * +GetPlannerInfoExtensionState(PlannerInfo *root, int extension_id) +{ + Assert(extension_id >= 0); + + if (extension_id >= root->extension_state_allocated) + return NULL; + + return root->extension_state[extension_id]; +} + +/* + * Get extension-specific state from a PlannerInfo. + */ +static inline void * +GetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id) +{ + Assert(extension_id >= 0); + + if (extension_id >= rel->extension_state_allocated) + return NULL; + + return rel->extension_state[extension_id]; +} + +/* Functions to store private state into various planner objects */ +extern void SetPlannerGlobalExtensionState(PlannerGlobal *glob, + int extension_id, + void *opaque); +extern void SetPlannerInfoExtensionState(PlannerInfo *root, int extension_id, + void *opaque); +extern void SetRelOptInfoExtensionState(RelOptInfo *rel, int extension_id, + void *opaque); + +#endif diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h index 9f8e0f337aa..b3017dd8ec4 100644 --- a/src/include/optimizer/geqo.h +++ b/src/include/optimizer/geqo.h @@ -24,6 +24,7 @@ #include "common/pg_prng.h" #include "nodes/pathnodes.h" +#include "optimizer/extendplan.h" #include "optimizer/geqo_gene.h" @@ -62,6 +63,8 @@ extern PGDLLIMPORT int Geqo_generations; /* 1 .. inf, or 0 to use default */ extern PGDLLIMPORT double Geqo_selection_bias; +extern PGDLLIMPORT int Geqo_planner_extension_id; + #define DEFAULT_GEQO_SELECTION_BIAS 2.0 #define MIN_GEQO_SELECTION_BIAS 1.5 #define MAX_GEQO_SELECTION_BIAS 2.0 @@ -70,7 +73,7 @@ extern PGDLLIMPORT double Geqo_seed; /* 0 .. 1 */ /* - * Private state for a GEQO run --- accessible via root->join_search_private + * Private state for a GEQO run --- accessible via GetGeqoPrivateData */ typedef struct { @@ -78,6 +81,13 @@ typedef struct pg_prng_state random_state; /* PRNG state */ } GeqoPrivateData; +static inline GeqoPrivateData * +GetGeqoPrivateData(PlannerInfo *root) +{ + /* headers must be C++-compliant, so the cast is required here */ + return (GeqoPrivateData *) + GetPlannerInfoExtensionState(root, Geqo_planner_extension_id); +} /* routines in geqo_main.c */ extern RelOptInfo *geqo(PlannerInfo *root, diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 04878f1f1c2..a34113903c0 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -24,6 +24,8 @@ #include "nodes/parsenodes.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ + /* * We don't want to include nodes/pathnodes.h here, because non-planner * code should generally treat PlannerInfo as an opaque typedef. @@ -104,7 +106,8 @@ extern PGDLLIMPORT bool enable_distinct_reordering; extern PlannedStmt *planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern Expr *expression_planner(Expr *expr); extern Expr *expression_planner_with_deps(Expr *expr, diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 763cd25bb3c..da60383c2aa 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -312,6 +312,8 @@ extern void setup_simple_rel_arrays(PlannerInfo *root); extern void expand_planner_arrays(PlannerInfo *root, int add_size); extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent); +extern RelOptInfo *build_simple_grouped_rel(PlannerInfo *root, RelOptInfo *rel); +extern RelOptInfo *build_grouped_rel(PlannerInfo *root, RelOptInfo *rel); extern RelOptInfo *find_base_rel(PlannerInfo *root, int relid); extern RelOptInfo *find_base_rel_noerr(PlannerInfo *root, int relid); extern RelOptInfo *find_base_rel_ignore_join(PlannerInfo *root, int relid); @@ -351,4 +353,6 @@ extern RelOptInfo *build_child_join_rel(PlannerInfo *root, SpecialJoinInfo *sjinfo, int nappinfos, AppendRelInfo **appinfos); +extern RelAggInfo *create_rel_agg_info(PlannerInfo *root, RelOptInfo *rel, + bool calculate_grouped_rows); #endif /* PATHNODE_H */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index cbade77b717..f6a62df0b43 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -21,7 +21,9 @@ * allpaths.c */ extern PGDLLIMPORT bool enable_geqo; +extern PGDLLIMPORT bool enable_eager_aggregate; extern PGDLLIMPORT int geqo_threshold; +extern PGDLLIMPORT double min_eager_agg_group_size; extern PGDLLIMPORT int min_parallel_table_scan_size; extern PGDLLIMPORT int min_parallel_index_scan_size; extern PGDLLIMPORT bool enable_group_by_reordering; @@ -57,6 +59,8 @@ extern void generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows); extern void generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows); +extern void generate_grouped_paths(PlannerInfo *root, RelOptInfo *grouped_rel, + RelOptInfo *rel); extern int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers); extern void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel, diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 9d3debcab28..09b48b26f8f 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -76,6 +76,7 @@ extern void add_vars_to_targetlist(PlannerInfo *root, List *vars, extern void add_vars_to_attr_needed(PlannerInfo *root, List *vars, Relids where_needed); extern void remove_useless_groupby_columns(PlannerInfo *root); +extern void setup_eager_aggregation(PlannerInfo *root); extern void find_lateral_references(PlannerInfo *root); extern void rebuild_lateral_attr_needed(PlannerInfo *root); extern void create_lateral_join_info(PlannerInfo *root); diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index f220e9a270d..55d9b7940aa 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -22,13 +22,29 @@ #include "nodes/plannodes.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ + /* Hook for plugins to get control in planner() */ typedef PlannedStmt *(*planner_hook_type) (Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern PGDLLIMPORT planner_hook_type planner_hook; +/* Hook for plugins to get control after PlannerGlobal is initialized */ +typedef void (*planner_setup_hook_type) (PlannerGlobal *glob, Query *parse, + const char *query_string, + double *tuple_fraction, + ExplainState *es); +extern PGDLLIMPORT planner_setup_hook_type planner_setup_hook; + +/* Hook for plugins to get control before PlannerGlobal is discarded */ +typedef void (*planner_shutdown_hook_type) (PlannerGlobal *glob, Query *parse, + const char *query_string, + PlannedStmt *pstmt); +extern PGDLLIMPORT planner_shutdown_hook_type planner_shutdown_hook; + /* Hook for plugins to get control when grouping_planner() plans upper rels */ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, UpperRelationKind stage, @@ -40,9 +56,11 @@ extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; extern PlannedStmt *standard_planner(Query *parse, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, + char *plan_name, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction, SetOperationStmt *setops); @@ -62,4 +80,7 @@ extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr); extern RelOptInfo *create_unique_paths(PlannerInfo *root, RelOptInfo *rel, SpecialJoinInfo *sjinfo); +extern char *choose_plan_name(PlannerGlobal *glob, const char *name, + bool always_number); + #endif /* PLANNER_H */ diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 8e8adb01176..bc8077cbae6 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -212,7 +212,7 @@ typedef struct PgStat_TableXactStatus * ------------------------------------------------------------ */ -#define PGSTAT_FILE_FORMAT_ID 0x01A5BCB8 +#define PGSTAT_FILE_FORMAT_ID 0x01A5BCB9 typedef struct PgStat_ArchiverStats { @@ -384,6 +384,7 @@ typedef struct PgStat_StatFuncEntry PgStat_Counter total_time; /* times in microseconds */ PgStat_Counter self_time; + TimestampTz stat_reset_timestamp; } PgStat_StatFuncEntry; typedef struct PgStat_StatReplSlotEntry @@ -394,6 +395,7 @@ typedef struct PgStat_StatReplSlotEntry PgStat_Counter stream_txns; PgStat_Counter stream_count; PgStat_Counter stream_bytes; + PgStat_Counter mem_exceeded_count; PgStat_Counter total_txns; PgStat_Counter total_bytes; TimestampTz stat_reset_timestamp; diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 91dc7e5e448..3cbe106a3c7 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -690,6 +690,9 @@ struct ReorderBuffer int64 streamCount; /* streaming invocation counter */ int64 streamBytes; /* amount of data decoded */ + /* Number of times the logical_decoding_work_mem limit has been reached */ + int64 memExceededCount; + /* * Statistics about all the transactions sent to the decoding output * plugin diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index dfd614f7ca4..c1206a46aba 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -371,6 +371,8 @@ UnlockBufHdr(BufferDesc *desc, uint32 buf_state) pg_atomic_write_u32(&desc->state, buf_state & (~BM_LOCKED)); } +extern uint32 WaitBufHdrUnlocked(BufferDesc *buf); + /* in bufmgr.c */ /* @@ -425,6 +427,8 @@ extern void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_co extern void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag); +extern void TrackNewBufferPin(Buffer buf); + /* solely to make it easier to write tests */ extern bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait); extern void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits, diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 47360a3d3d8..3f37b294af6 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -230,7 +230,8 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation); extern void ReleaseBuffer(Buffer buffer); extern void UnlockReleaseBuffer(Buffer buffer); -extern bool BufferIsExclusiveLocked(Buffer buffer); +extern bool BufferIsLockedByMe(Buffer buffer); +extern bool BufferIsLockedByMeInMode(Buffer buffer, int mode); extern bool BufferIsDirty(Buffer buffer); extern void MarkBufferDirty(Buffer buffer); extern void IncrBufferRefCount(Buffer buffer); diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index a83cc4f4850..c1bcfdec673 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -20,6 +20,7 @@ #include "utils/guc.h" #include "utils/queryenvironment.h" +typedef struct ExplainState ExplainState; /* defined in explain_state.h */ extern PGDLLIMPORT CommandDest whereToSendOutput; extern PGDLLIMPORT const char *debug_query_string; @@ -63,7 +64,8 @@ extern List *pg_analyze_and_rewrite_withcb(RawStmt *parsetree, QueryEnvironment *queryEnv); extern PlannedStmt *pg_plan_query(Query *querytree, const char *query_string, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams, + ExplainState *es); extern List *pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, ParamListInfo boundParams); diff --git a/src/include/utils/float.h b/src/include/utils/float.h index 0e2e9ec5347..fc2a9cf6475 100644 --- a/src/include/utils/float.h +++ b/src/include/utils/float.h @@ -25,13 +25,6 @@ /* Radians per degree, a.k.a. PI / 180 */ #define RADIANS_PER_DEGREE 0.0174532925199432957692 -/* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */ -#if defined(WIN32) && !defined(NAN) -static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; - -#define NAN (*(const float8 *) nan) -#endif - extern PGDLLIMPORT int extra_float_digits; /* @@ -52,84 +45,46 @@ extern int float4_cmp_internal(float4 a, float4 b); extern int float8_cmp_internal(float8 a, float8 b); /* - * Routines to provide reasonably platform-independent handling of - * infinity and NaN + * Postgres requires IEEE-standard float arithmetic, including infinities + * and NaNs. We used to support pre-C99 compilers on which <math.h> might + * not supply the standard macros INFINITY and NAN. We no longer do so, + * but these wrapper functions are still preferred over using those macros + * directly. * - * We assume that isinf() and isnan() are available and work per spec. - * (On some platforms, we have to supply our own; see src/port.) However, - * generating an Infinity or NaN in the first place is less well standardized; - * pre-C99 systems tend not to have C99's INFINITY and NaN macros. We - * centralize our workarounds for this here. + * If you change these functions, see copies in interfaces/ecpg/ecpglib/data.c. */ -/* - * The funny placements of the two #pragmas is necessary because of a - * long lived bug in the Microsoft compilers. - * See http://support.microsoft.com/kb/120968/en-us for details - */ -#ifdef _MSC_VER -#pragma warning(disable:4756) -#endif static inline float4 get_float4_infinity(void) { -#ifdef INFINITY /* C99 standard way */ return (float4) INFINITY; -#else -#ifdef _MSC_VER -#pragma warning(default:4756) -#endif - - /* - * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the - * largest normal float8. We assume forcing an overflow will get us a - * true infinity. - */ - return (float4) (HUGE_VAL * HUGE_VAL); -#endif } static inline float8 get_float8_infinity(void) { -#ifdef INFINITY /* C99 standard way */ return (float8) INFINITY; -#else - - /* - * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the - * largest normal float8. We assume forcing an overflow will get us a - * true infinity. - */ - return (float8) (HUGE_VAL * HUGE_VAL); -#endif } +/* The C standard allows implementations to omit NAN, but we don't */ +#ifndef NAN +#error "Postgres requires support for IEEE quiet NaNs" +#endif + static inline float4 get_float4_nan(void) { -#ifdef NAN /* C99 standard way */ return (float4) NAN; -#else - /* Assume we can get a NAN via zero divide */ - return (float4) (0.0 / 0.0); -#endif } static inline float8 get_float8_nan(void) { - /* (float8) NAN doesn't work on some NetBSD/MIPS releases */ -#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__)) /* C99 standard way */ return (float8) NAN; -#else - /* Assume we can get a NaN via zero divide */ - return (float8) (0.0 / 0.0); -#endif } /* diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h index dc42d8043b5..4d2b8aa6081 100644 --- a/src/include/utils/pgstat_internal.h +++ b/src/include/utils/pgstat_internal.h @@ -691,6 +691,7 @@ extern void pgstat_database_reset_timestamp_cb(PgStatShared_Common *header, Time */ extern bool pgstat_function_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); +extern void pgstat_function_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); /* |