mirror of https://github.com/citusdata/citus.git
PG18 - define some EXPLAIN funcs and structs only in PG17 (#8239)
PG18 changed the visibility of various Explain Serialize functions and structs to `extern`. Previously, for PG17 support, these were `static`, so we had to copy paste their definitions from `explain.c` to Citus's `multi_explain.c`. Relevant PG18 commits: https://github.com/postgres/postgres/commit/555960a0 https://github.com/postgres/postgres/commit/77cb08be Now we don't need to define the following anymore in Citus, since they are extern in PG18: - typedef struct SerializeMetrics - void ExplainIndentText(ExplainState *es); - SerializeMetrics GetSerializationMetrics(DestReceiver *dest); - typedef struct SerializeDestReceiver (this is not extern, however it is only used by GetSerializationMetrics function) This was incorrectly handled in https://github.com/citusdata/citus/commit/9e42f3f2c by wrapping these definitions and usages in PG17 only, causing such diffs in PG18 (not able to see serialization at all): ```diff citus/src/test/regress/expected/pg17.out select public.explain_filter('explain (analyze, serialize binary,buffers,timing) select * from int8_tbl i8'); ... Planning Time: N.N ms - Serialization: time=N.N ms output=NkB format=binary Execution Time: N.N ms Planning Time: N.N ms Serialization: time=N.N ms output=NkB format=binary Execution Time: N.N ms -(14 rows) +(13 rows) ```pull/8238/head
parent
287abea661
commit
351cb2044d
|
|
@ -149,13 +149,6 @@ typedef struct ExplainAnalyzeDestination
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
||||||
|
|
||||||
/*
|
|
||||||
* Various places within need to convert bytes to kilobytes. Round these up
|
|
||||||
* to the next whole kilobyte.
|
|
||||||
* copied from explain.c
|
|
||||||
*/
|
|
||||||
#define BYTES_TO_KILOBYTES(b) (((b) + 1023) / 1024)
|
|
||||||
|
|
||||||
/* copied from explain.c */
|
/* copied from explain.c */
|
||||||
/* Instrumentation data for SERIALIZE option */
|
/* Instrumentation data for SERIALIZE option */
|
||||||
typedef struct SerializeMetrics
|
typedef struct SerializeMetrics
|
||||||
|
|
@ -166,13 +159,7 @@ typedef struct SerializeMetrics
|
||||||
} SerializeMetrics;
|
} SerializeMetrics;
|
||||||
|
|
||||||
/* copied from explain.c */
|
/* copied from explain.c */
|
||||||
static bool peek_buffer_usage(ExplainState *es, const BufferUsage *usage);
|
|
||||||
static void show_buffer_usage(ExplainState *es, const BufferUsage *usage);
|
|
||||||
static void show_memory_counters(ExplainState *es,
|
|
||||||
const MemoryContextCounters *mem_counters);
|
|
||||||
static void ExplainIndentText(ExplainState *es);
|
static void ExplainIndentText(ExplainState *es);
|
||||||
static void ExplainPrintSerialize(ExplainState *es,
|
|
||||||
SerializeMetrics *metrics);
|
|
||||||
static SerializeMetrics GetSerializationMetrics(DestReceiver *dest);
|
static SerializeMetrics GetSerializationMetrics(DestReceiver *dest);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -200,6 +187,23 @@ typedef struct SerializeDestReceiver
|
||||||
} SerializeDestReceiver;
|
} SerializeDestReceiver;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various places within need to convert bytes to kilobytes. Round these up
|
||||||
|
* to the next whole kilobyte.
|
||||||
|
* copied from explain.c
|
||||||
|
*/
|
||||||
|
#define BYTES_TO_KILOBYTES(b) (((b) + 1023) / 1024)
|
||||||
|
|
||||||
|
/* copied from explain.c */
|
||||||
|
static bool peek_buffer_usage(ExplainState *es, const BufferUsage *usage);
|
||||||
|
static void show_buffer_usage(ExplainState *es, const BufferUsage *usage);
|
||||||
|
static void show_memory_counters(ExplainState *es,
|
||||||
|
const MemoryContextCounters *mem_counters);
|
||||||
|
static void ExplainPrintSerialize(ExplainState *es,
|
||||||
|
SerializeMetrics *metrics);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Explain functions for distributed queries */
|
/* Explain functions for distributed queries */
|
||||||
static void ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es);
|
static void ExplainSubPlans(DistributedPlan *distributedPlan, ExplainState *es);
|
||||||
|
|
@ -2409,7 +2413,7 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DistributedSubPlan *subPlan, DestRec
|
||||||
/* Create textual dump of plan tree */
|
/* Create textual dump of plan tree */
|
||||||
ExplainPrintPlan(es, queryDesc);
|
ExplainPrintPlan(es, queryDesc);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
/* Show buffer and/or memory usage in planning */
|
/* Show buffer and/or memory usage in planning */
|
||||||
if (peek_buffer_usage(es, bufusage) || mem_counters)
|
if (peek_buffer_usage(es, bufusage) || mem_counters)
|
||||||
{
|
{
|
||||||
|
|
@ -2455,7 +2459,7 @@ ExplainWorkerPlan(PlannedStmt *plannedstmt, DistributedSubPlan *subPlan, DestRec
|
||||||
if (es->costs)
|
if (es->costs)
|
||||||
ExplainPrintJITSummary(es, queryDesc);
|
ExplainPrintJITSummary(es, queryDesc);
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
|
if (es->serialize != EXPLAIN_SERIALIZE_NONE)
|
||||||
{
|
{
|
||||||
/* the SERIALIZE option requires its own tuple receiver */
|
/* the SERIALIZE option requires its own tuple receiver */
|
||||||
|
|
@ -2530,6 +2534,50 @@ elapsed_time(instr_time *starttime)
|
||||||
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
#if PG_VERSION_NUM >= PG_VERSION_17 && PG_VERSION_NUM < PG_VERSION_18
|
||||||
|
/*
|
||||||
|
* Indent a text-format line.
|
||||||
|
*
|
||||||
|
* We indent by two spaces per indentation level. However, when emitting
|
||||||
|
* data for a parallel worker there might already be data on the current line
|
||||||
|
* (cf. ExplainOpenWorker); in that case, don't indent any more.
|
||||||
|
*
|
||||||
|
* Copied from explain.c.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ExplainIndentText(ExplainState *es)
|
||||||
|
{
|
||||||
|
Assert(es->format == EXPLAIN_FORMAT_TEXT);
|
||||||
|
if (es->str->len == 0 || es->str->data[es->str->len - 1] == '\n')
|
||||||
|
appendStringInfoSpaces(es->str, es->indent * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetSerializationMetrics - collect metrics
|
||||||
|
*
|
||||||
|
* We have to be careful here since the receiver could be an IntoRel
|
||||||
|
* receiver if the subject statement is CREATE TABLE AS. In that
|
||||||
|
* case, return all-zeroes stats.
|
||||||
|
*
|
||||||
|
* Copied from explain.c.
|
||||||
|
*/
|
||||||
|
static SerializeMetrics
|
||||||
|
GetSerializationMetrics(DestReceiver *dest)
|
||||||
|
{
|
||||||
|
SerializeMetrics empty;
|
||||||
|
|
||||||
|
if (dest->mydest == DestExplainSerialize)
|
||||||
|
return ((SerializeDestReceiver *) dest)->metrics;
|
||||||
|
|
||||||
|
memset(&empty, 0, sizeof(SerializeMetrics));
|
||||||
|
INSTR_TIME_SET_ZERO(empty.timeSpent);
|
||||||
|
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if PG_VERSION_NUM >= PG_VERSION_17
|
||||||
/*
|
/*
|
||||||
* Return whether show_buffer_usage would have anything to print, if given
|
* Return whether show_buffer_usage would have anything to print, if given
|
||||||
* the same 'usage' data. Note that when the format is anything other than
|
* the same 'usage' data. Note that when the format is anything other than
|
||||||
|
|
@ -2747,24 +2795,6 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Indent a text-format line.
|
|
||||||
*
|
|
||||||
* We indent by two spaces per indentation level. However, when emitting
|
|
||||||
* data for a parallel worker there might already be data on the current line
|
|
||||||
* (cf. ExplainOpenWorker); in that case, don't indent any more.
|
|
||||||
*
|
|
||||||
* Copied from explain.c.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ExplainIndentText(ExplainState *es)
|
|
||||||
{
|
|
||||||
Assert(es->format == EXPLAIN_FORMAT_TEXT);
|
|
||||||
if (es->str->len == 0 || es->str->data[es->str->len - 1] == '\n')
|
|
||||||
appendStringInfoSpaces(es->str, es->indent * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show memory usage details.
|
* Show memory usage details.
|
||||||
*
|
*
|
||||||
|
|
@ -2850,28 +2880,4 @@ ExplainPrintSerialize(ExplainState *es, SerializeMetrics *metrics)
|
||||||
|
|
||||||
ExplainCloseGroup("Serialization", "Serialization", true, es);
|
ExplainCloseGroup("Serialization", "Serialization", true, es);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetSerializationMetrics - collect metrics
|
|
||||||
*
|
|
||||||
* We have to be careful here since the receiver could be an IntoRel
|
|
||||||
* receiver if the subject statement is CREATE TABLE AS. In that
|
|
||||||
* case, return all-zeroes stats.
|
|
||||||
*
|
|
||||||
* Copied from explain.c.
|
|
||||||
*/
|
|
||||||
static SerializeMetrics
|
|
||||||
GetSerializationMetrics(DestReceiver *dest)
|
|
||||||
{
|
|
||||||
SerializeMetrics empty;
|
|
||||||
|
|
||||||
if (dest->mydest == DestExplainSerialize)
|
|
||||||
return ((SerializeDestReceiver *) dest)->metrics;
|
|
||||||
|
|
||||||
memset(&empty, 0, sizeof(SerializeMetrics));
|
|
||||||
INSTR_TIME_SET_ZERO(empty.timeSpent);
|
|
||||||
|
|
||||||
return empty;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue