mirror of
https://github.com/postgres/postgres.git
synced 2026-01-26 09:41:40 +03:00
Move instrumentation-related structs to instrument_node.h
Some structs and enums related to parallel query instrumentation had organically grown scattered across various files, and were causing header pollution especially through execnodes.h. Create a single file where they can live together. This only moves the structs to the new file; cleaning up the pollution by removing no-longer-necessary cross-header inclusion will be done in future commits. Co-authored-by: Álvaro Herrera <alvherre@kurilemu.de> Co-authored-by: Mario González <gonzalemario@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/202510051642.wwmn4mj77wch@alvherre.pgsql Discussion: https://postgr.es/m/CAFsReFUr4KrQ60z+ck9cRM4WuUw1TCghN7EFwvV0KvuncTRc2w@mail.gmail.com
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "access/relscan.h"
|
||||
#include "bloom.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/bufmgr.h"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "access/gin_private.h"
|
||||
#include "access/relscan.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "pgstat.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "access/genam.h"
|
||||
#include "access/gist_private.h"
|
||||
#include "access/relscan.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "lib/pairingheap.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "access/hash.h"
|
||||
#include "access/relscan.h"
|
||||
#include "miscadmin.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/predicate.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "access/nbtree.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/xact.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/predicate.h"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "access/genam.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/spgist_private.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/bufmgr.h"
|
||||
|
||||
@@ -200,7 +200,7 @@ struct Tuplesortstate
|
||||
int64 maxSpace; /* maximum amount of space occupied among sort
|
||||
* of groups, either in-memory or on-disk */
|
||||
bool isMaxSpaceDisk; /* true when maxSpace is value for on-disk
|
||||
* space, false when its value for in-memory
|
||||
* space, false when it's value for in-memory
|
||||
* space */
|
||||
TupSortStatus maxSpaceStatus; /* sort status when maxSpace was reached */
|
||||
LogicalTapeSet *tapeset; /* logtape.c object for tapes in a temp file */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "access/htup.h"
|
||||
#include "access/sdir.h"
|
||||
#include "access/skey.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "nodes/tidbitmap.h"
|
||||
#include "storage/buf.h"
|
||||
#include "storage/lockdefs.h"
|
||||
@@ -29,28 +30,6 @@ typedef struct TupleTableSlot TupleTableSlot;
|
||||
/* or relcache.h */
|
||||
typedef struct RelationData *Relation;
|
||||
|
||||
|
||||
/*
|
||||
* Struct for statistics maintained by amgettuple and amgetbitmap
|
||||
*
|
||||
* Note: IndexScanInstrumentation can't contain any pointers, since it is
|
||||
* copied into a SharedIndexScanInstrumentation during parallel scans
|
||||
*/
|
||||
typedef struct IndexScanInstrumentation
|
||||
{
|
||||
/* Index search count (incremented with pgstat_count_index_scan call) */
|
||||
uint64 nsearches;
|
||||
} IndexScanInstrumentation;
|
||||
|
||||
/*
|
||||
* Struct for every worker's IndexScanInstrumentation, stored in shared memory
|
||||
*/
|
||||
typedef struct SharedIndexScanInstrumentation
|
||||
{
|
||||
int num_workers;
|
||||
IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedIndexScanInstrumentation;
|
||||
|
||||
/*
|
||||
* Struct for statistics returned by ambuild
|
||||
*/
|
||||
|
||||
211
src/include/executor/instrument_node.h
Normal file
211
src/include/executor/instrument_node.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* instrument_node.h
|
||||
* Definitions for node-specific support for parallel query instrumentation
|
||||
*
|
||||
* These structs purposely contain no pointers because they are copied
|
||||
* across processes during parallel query execution. Each worker copies its
|
||||
* individual information into the container struct at executor shutdown time,
|
||||
* to allow the leader to display the information in EXPLAIN ANALYZE.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/executor/instrument_node.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef INSTRUMENT_NODE_H
|
||||
#define INSTRUMENT_NODE_H
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for aggregate function execution
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct AggregateInstrumentation
|
||||
{
|
||||
Size hash_mem_peak; /* peak hash table memory usage */
|
||||
uint64 hash_disk_used; /* kB of disk space used */
|
||||
int hash_batches_used; /* batches used during entire execution */
|
||||
} AggregateInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker aggregate information
|
||||
*/
|
||||
typedef struct SharedAggInfo
|
||||
{
|
||||
int num_workers;
|
||||
AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedAggInfo;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for indexscans (amgettuple and amgetbitmap)
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct IndexScanInstrumentation
|
||||
{
|
||||
/* Index search count (incremented with pgstat_count_index_scan call) */
|
||||
uint64 nsearches;
|
||||
} IndexScanInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker information
|
||||
*/
|
||||
typedef struct SharedIndexScanInstrumentation
|
||||
{
|
||||
int num_workers;
|
||||
IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedIndexScanInstrumentation;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for bitmap heap scans
|
||||
*
|
||||
* exact_pages total number of exact pages retrieved
|
||||
* lossy_pages total number of lossy pages retrieved
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct BitmapHeapScanInstrumentation
|
||||
{
|
||||
uint64 exact_pages;
|
||||
uint64 lossy_pages;
|
||||
} BitmapHeapScanInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker information
|
||||
*/
|
||||
typedef struct SharedBitmapHeapInstrumentation
|
||||
{
|
||||
int num_workers;
|
||||
BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedBitmapHeapInstrumentation;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for Memoize
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct MemoizeInstrumentation
|
||||
{
|
||||
uint64 cache_hits; /* number of rescans where we've found the
|
||||
* scan parameters values to be cached */
|
||||
uint64 cache_misses; /* number of rescans where we've not found the
|
||||
* scan parameters values to be cached */
|
||||
uint64 cache_evictions; /* number of cache entries removed due to
|
||||
* the need to free memory */
|
||||
uint64 cache_overflows; /* number of times we've had to bypass the
|
||||
* cache when filling it due to not being
|
||||
* able to free enough space to store the
|
||||
* current scan's tuples */
|
||||
uint64 mem_peak; /* peak memory usage in bytes */
|
||||
} MemoizeInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker memoize information
|
||||
*/
|
||||
typedef struct SharedMemoizeInfo
|
||||
{
|
||||
int num_workers;
|
||||
MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedMemoizeInfo;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for Sorts.
|
||||
* ---------------------
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SORT_SPACE_TYPE_DISK,
|
||||
SORT_SPACE_TYPE_MEMORY,
|
||||
} TuplesortSpaceType;
|
||||
|
||||
/*
|
||||
* The parallel-sort infrastructure relies on having a zero TuplesortMethod
|
||||
* to indicate that a worker never did anything, so we assign zero to
|
||||
* SORT_TYPE_STILL_IN_PROGRESS. The other values of this enum can be
|
||||
* OR'ed together to represent a situation where different workers used
|
||||
* different methods, so we need a separate bit for each one. Keep the
|
||||
* NUM_TUPLESORTMETHODS constant in sync with the number of bits!
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SORT_TYPE_STILL_IN_PROGRESS = 0,
|
||||
SORT_TYPE_TOP_N_HEAPSORT = 1 << 0,
|
||||
SORT_TYPE_QUICKSORT = 1 << 1,
|
||||
SORT_TYPE_EXTERNAL_SORT = 1 << 2,
|
||||
SORT_TYPE_EXTERNAL_MERGE = 1 << 3,
|
||||
} TuplesortMethod;
|
||||
#define NUM_TUPLESORTMETHODS 4
|
||||
|
||||
typedef struct TuplesortInstrumentation
|
||||
{
|
||||
TuplesortMethod sortMethod; /* sort algorithm used */
|
||||
TuplesortSpaceType spaceType; /* type of space spaceUsed represents */
|
||||
int64 spaceUsed; /* space consumption, in kB */
|
||||
} TuplesortInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker sort information
|
||||
*/
|
||||
typedef struct SharedSortInfo
|
||||
{
|
||||
int num_workers;
|
||||
TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedSortInfo;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for nodeHash.c
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct HashInstrumentation
|
||||
{
|
||||
int nbuckets; /* number of buckets at end of execution */
|
||||
int nbuckets_original; /* planned number of buckets */
|
||||
int nbatch; /* number of batches at end of execution */
|
||||
int nbatch_original; /* planned number of batches */
|
||||
Size space_peak; /* peak memory usage in bytes */
|
||||
} HashInstrumentation;
|
||||
|
||||
/*
|
||||
* Shared memory container for per-worker information
|
||||
*/
|
||||
typedef struct SharedHashInfo
|
||||
{
|
||||
int num_workers;
|
||||
HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedHashInfo;
|
||||
|
||||
|
||||
/* ---------------------
|
||||
* Instrumentation information for IncrementalSort
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct IncrementalSortGroupInfo
|
||||
{
|
||||
int64 groupCount;
|
||||
int64 maxDiskSpaceUsed;
|
||||
int64 totalDiskSpaceUsed;
|
||||
int64 maxMemorySpaceUsed;
|
||||
int64 totalMemorySpaceUsed;
|
||||
bits32 sortMethods; /* bitmask of TuplesortMethod */
|
||||
} IncrementalSortGroupInfo;
|
||||
|
||||
typedef struct IncrementalSortInfo
|
||||
{
|
||||
IncrementalSortGroupInfo fullsortGroupInfo;
|
||||
IncrementalSortGroupInfo prefixsortGroupInfo;
|
||||
} IncrementalSortInfo;
|
||||
|
||||
/* Shared memory container for per-worker incremental sort information */
|
||||
typedef struct SharedIncrementalSortInfo
|
||||
{
|
||||
int num_workers;
|
||||
IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedIncrementalSortInfo;
|
||||
|
||||
#endif /* INSTRUMENT_NODE_H */
|
||||
@@ -1816,19 +1816,6 @@ typedef struct BitmapIndexScanState
|
||||
SharedIndexScanInstrumentation *biss_SharedInfo;
|
||||
} BitmapIndexScanState;
|
||||
|
||||
/* ----------------
|
||||
* BitmapHeapScanInstrumentation information
|
||||
*
|
||||
* exact_pages total number of exact pages retrieved
|
||||
* lossy_pages total number of lossy pages retrieved
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct BitmapHeapScanInstrumentation
|
||||
{
|
||||
uint64 exact_pages;
|
||||
uint64 lossy_pages;
|
||||
} BitmapHeapScanInstrumentation;
|
||||
|
||||
/* ----------------
|
||||
* SharedBitmapState information
|
||||
*
|
||||
@@ -1865,20 +1852,6 @@ typedef struct ParallelBitmapHeapState
|
||||
ConditionVariable cv;
|
||||
} ParallelBitmapHeapState;
|
||||
|
||||
/* ----------------
|
||||
* Instrumentation data for a parallel bitmap heap scan.
|
||||
*
|
||||
* A shared memory struct that each parallel worker copies its
|
||||
* BitmapHeapScanInstrumentation information into at executor shutdown to
|
||||
* allow the leader to display the information in EXPLAIN ANALYZE.
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedBitmapHeapInstrumentation
|
||||
{
|
||||
int num_workers;
|
||||
BitmapHeapScanInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedBitmapHeapInstrumentation;
|
||||
|
||||
/* ----------------
|
||||
* BitmapHeapScanState information
|
||||
*
|
||||
@@ -2305,31 +2278,6 @@ struct MemoizeEntry;
|
||||
struct MemoizeTuple;
|
||||
struct MemoizeKey;
|
||||
|
||||
typedef struct MemoizeInstrumentation
|
||||
{
|
||||
uint64 cache_hits; /* number of rescans where we've found the
|
||||
* scan parameter values to be cached */
|
||||
uint64 cache_misses; /* number of rescans where we've not found the
|
||||
* scan parameter values to be cached. */
|
||||
uint64 cache_evictions; /* number of cache entries removed due to
|
||||
* the need to free memory */
|
||||
uint64 cache_overflows; /* number of times we've had to bypass the
|
||||
* cache when filling it due to not being
|
||||
* able to free enough space to store the
|
||||
* current scan's tuples. */
|
||||
uint64 mem_peak; /* peak memory usage in bytes */
|
||||
} MemoizeInstrumentation;
|
||||
|
||||
/* ----------------
|
||||
* Shared memory container for per-worker memoize information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedMemoizeInfo
|
||||
{
|
||||
int num_workers;
|
||||
MemoizeInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedMemoizeInfo;
|
||||
|
||||
/* ----------------
|
||||
* MemoizeState information
|
||||
*
|
||||
@@ -2385,16 +2333,6 @@ typedef struct PresortedKeyData
|
||||
OffsetNumber attno; /* attribute number in tuple */
|
||||
} PresortedKeyData;
|
||||
|
||||
/* ----------------
|
||||
* Shared memory container for per-worker sort information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedSortInfo
|
||||
{
|
||||
int num_workers;
|
||||
TuplesortInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedSortInfo;
|
||||
|
||||
/* ----------------
|
||||
* SortState information
|
||||
* ----------------
|
||||
@@ -2414,40 +2352,6 @@ typedef struct SortState
|
||||
SharedSortInfo *shared_info; /* one entry per worker */
|
||||
} SortState;
|
||||
|
||||
/* ----------------
|
||||
* Instrumentation information for IncrementalSort
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct IncrementalSortGroupInfo
|
||||
{
|
||||
int64 groupCount;
|
||||
int64 maxDiskSpaceUsed;
|
||||
int64 totalDiskSpaceUsed;
|
||||
int64 maxMemorySpaceUsed;
|
||||
int64 totalMemorySpaceUsed;
|
||||
bits32 sortMethods; /* bitmask of TuplesortMethod */
|
||||
} IncrementalSortGroupInfo;
|
||||
|
||||
typedef struct IncrementalSortInfo
|
||||
{
|
||||
IncrementalSortGroupInfo fullsortGroupInfo;
|
||||
IncrementalSortGroupInfo prefixsortGroupInfo;
|
||||
} IncrementalSortInfo;
|
||||
|
||||
/* ----------------
|
||||
* Shared memory container for per-worker incremental sort information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedIncrementalSortInfo
|
||||
{
|
||||
int num_workers;
|
||||
IncrementalSortInfo sinfo[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedIncrementalSortInfo;
|
||||
|
||||
/* ----------------
|
||||
* IncrementalSortState information
|
||||
* ----------------
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
INCSORT_LOADFULLSORT,
|
||||
@@ -2490,27 +2394,6 @@ typedef struct GroupState
|
||||
bool grp_done; /* indicates completion of Group scan */
|
||||
} GroupState;
|
||||
|
||||
/* ---------------------
|
||||
* per-worker aggregate information
|
||||
* ---------------------
|
||||
*/
|
||||
typedef struct AggregateInstrumentation
|
||||
{
|
||||
Size hash_mem_peak; /* peak hash table memory usage */
|
||||
uint64 hash_disk_used; /* kB of disk space used */
|
||||
int hash_batches_used; /* batches used during entire execution */
|
||||
} AggregateInstrumentation;
|
||||
|
||||
/* ----------------
|
||||
* Shared memory container for per-worker aggregate information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedAggInfo
|
||||
{
|
||||
int num_workers;
|
||||
AggregateInstrumentation sinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedAggInfo;
|
||||
|
||||
/* ---------------------
|
||||
* AggState information
|
||||
*
|
||||
@@ -2787,29 +2670,6 @@ typedef struct GatherMergeState
|
||||
struct binaryheap *gm_heap; /* binary heap of slot indices */
|
||||
} GatherMergeState;
|
||||
|
||||
/* ----------------
|
||||
* Values displayed by EXPLAIN ANALYZE
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct HashInstrumentation
|
||||
{
|
||||
int nbuckets; /* number of buckets at end of execution */
|
||||
int nbuckets_original; /* planned number of buckets */
|
||||
int nbatch; /* number of batches at end of execution */
|
||||
int nbatch_original; /* planned number of batches */
|
||||
Size space_peak; /* peak memory usage in bytes */
|
||||
} HashInstrumentation;
|
||||
|
||||
/* ----------------
|
||||
* Shared memory container for per-worker hash information
|
||||
* ----------------
|
||||
*/
|
||||
typedef struct SharedHashInfo
|
||||
{
|
||||
int num_workers;
|
||||
HashInstrumentation hinstrument[FLEXIBLE_ARRAY_MEMBER];
|
||||
} SharedHashInfo;
|
||||
|
||||
/* ----------------
|
||||
* HashState information
|
||||
* ----------------
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "access/brin_tuple.h"
|
||||
#include "access/gin_tuple.h"
|
||||
#include "access/itup.h"
|
||||
#include "executor/instrument_node.h"
|
||||
#include "executor/tuptable.h"
|
||||
#include "storage/dsm.h"
|
||||
#include "utils/logtape.h"
|
||||
@@ -61,35 +62,6 @@ typedef struct SortCoordinateData
|
||||
|
||||
typedef struct SortCoordinateData *SortCoordinate;
|
||||
|
||||
/*
|
||||
* Data structures for reporting sort statistics. Note that
|
||||
* TuplesortInstrumentation can't contain any pointers because we
|
||||
* sometimes put it in shared memory.
|
||||
*
|
||||
* The parallel-sort infrastructure relies on having a zero TuplesortMethod
|
||||
* to indicate that a worker never did anything, so we assign zero to
|
||||
* SORT_TYPE_STILL_IN_PROGRESS. The other values of this enum can be
|
||||
* OR'ed together to represent a situation where different workers used
|
||||
* different methods, so we need a separate bit for each one. Keep the
|
||||
* NUM_TUPLESORTMETHODS constant in sync with the number of bits!
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SORT_TYPE_STILL_IN_PROGRESS = 0,
|
||||
SORT_TYPE_TOP_N_HEAPSORT = 1 << 0,
|
||||
SORT_TYPE_QUICKSORT = 1 << 1,
|
||||
SORT_TYPE_EXTERNAL_SORT = 1 << 2,
|
||||
SORT_TYPE_EXTERNAL_MERGE = 1 << 3,
|
||||
} TuplesortMethod;
|
||||
|
||||
#define NUM_TUPLESORTMETHODS 4
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SORT_SPACE_TYPE_DISK,
|
||||
SORT_SPACE_TYPE_MEMORY,
|
||||
} TuplesortSpaceType;
|
||||
|
||||
/* Bitwise option flags for tuple sorts */
|
||||
#define TUPLESORT_NONE 0
|
||||
|
||||
@@ -108,13 +80,6 @@ typedef enum
|
||||
*/
|
||||
#define TupleSortUseBumpTupleCxt(opt) (((opt) & TUPLESORT_ALLOWBOUNDED) == 0)
|
||||
|
||||
typedef struct TuplesortInstrumentation
|
||||
{
|
||||
TuplesortMethod sortMethod; /* sort algorithm used */
|
||||
TuplesortSpaceType spaceType; /* type of space spaceUsed represents */
|
||||
int64 spaceUsed; /* space consumption, in kB */
|
||||
} TuplesortInstrumentation;
|
||||
|
||||
/*
|
||||
* The objects we actually sort are SortTuple structs. These contain
|
||||
* a pointer to the tuple proper (might be a MinimalTuple or IndexTuple),
|
||||
|
||||
Reference in New Issue
Block a user