Files
openGauss-server/src/common/backend/nodes/outfuncs.cpp
2022-10-28 10:32:09 +08:00

6676 lines
201 KiB
C++
Executable File

/* -------------------------------------------------------------------------
*
* outfuncs.cpp
* Output functions for openGauss tree nodes.
*
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/common/backend/nodes/outfuncs.cpp
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
* have an output function defined here (as well as an input function
* in readfuncs.c). For use in debugging, we also provide output
* functions for nodes that appear in raw parsetrees, path, and plan trees.
* These nodes however need not have input functions.
*
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "knl/knl_variable.h"
#include "miscadmin.h"
#include "bulkload/dist_fdw.h"
#include "foreign/fdwapi.h"
#include "nodes/plannodes.h"
#include "nodes/relation.h"
#include "nodes/nodeFuncs.h"
#include "parser/parse_hint.h"
#include "parser/parser.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
#include "catalog/gs_opt_model.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_synonym.h"
#include "catalog/pg_type.h"
#include "optimizer/streamplan.h"
#include "storage/tcap.h"
#include "tcop/utility.h"
#ifdef PGXC
#include "optimizer/dataskew.h"
#include "optimizer/pgxcplan.h"
#include "optimizer/planner.h"
#include "access/transam.h"
#include "pgxc/groupmgr.h"
#include "pgxc/pgxc.h"
#include "pgxc/pgFdwRemote.h"
#endif
#include "db4ai/gd.h"
/*
* Macros to simplify output of different kinds of fields. Use these
* wherever possible to reduce the chance for silly typos. Note that these
* hard-wire conventions about the names of the local variables in an Out
* routine.
*/
/* Write the label for the node type */
#define WRITE_NODE_TYPE(nodelabel) appendStringInfoString(str, nodelabel)
/* Write an integer field (anything written as ":fldname %d") */
#define WRITE_INT_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
/* Write an unsigned integer field (anything written as ":fldname %u") */
#define WRITE_UINT_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
/* Write an 64bit unsigned integer field (anything written as ":fldname %lu") */
#define WRITE_UINT64_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %lu", node->fldname)
/* Write an OID field (don't hard-wire assumption that OID is same as uint) */
#define WRITE_OID_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %u", node->fldname)
/* Write a long-integer field */
#define WRITE_LONG_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %ld", node->fldname)
/* Write a char field (ie, one ascii character) */
#define WRITE_CHAR_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %c", node->fldname)
/* Write an enumerated-type field as an integer code */
#define WRITE_ENUM_FIELD(fldname, enumtype) appendStringInfo(str, " :" CppAsString(fldname) " %d", (int)node->fldname)
/* Write a float field --- caller must give format to define precision */
#define WRITE_FLOAT_FIELD(fldname, format) appendStringInfo(str, " :" CppAsString(fldname) " " format, node->fldname)
/* Write a boolean field */
#define WRITE_BOOL_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %s", booltostr(node->fldname))
/* Write a boolean expr */
#define WRITE_BOOL_EXPR(fldname, expr) appendStringInfo(str, " :" CppAsString(fldname) " %s", booltostr(expr))
/* Write a character-string (possibly NULL) field */
#define WRITE_STRING_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), _outToken(str, node->fldname))
/* Write a parse location field (actually same as INT case) */
#define WRITE_LOCATION_FIELD(fldname) appendStringInfo(str, " :" CppAsString(fldname) " %d", node->fldname)
/* Write a Node field */
#define WRITE_NODE_FIELD(fldname) (appendStringInfo(str, " :" CppAsString(fldname) " "), _outNode(str, node->fldname))
/* Write a Array field */
#define WRITE_ARRAY_FIELD(fldname, fldlen) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), _outArray(str, (void**)(node->fldname), fldlen))
/* Write a bitmapset field */
#define WRITE_BITMAPSET_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), _outBitmapset(str, node->fldname))
/* Write a cursor data */
#define WRITE_CURSORDATA_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), _outCursorData(str, &node->fldname))
#define IsStatisfyUpdateCompatibility(fldname) (!IsInitdb && !(isRestoreMode && (fldname) < FirstNormalObjectId))
/*
* For the new created type, we have to bind the typname and typnamespace information
* so that the data node can decode it.
*/
#define WRITE_TYPEINFO_WITHOID(typid) \
if ((typid) >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(typid)) { \
char* exprtypename = NULL; \
char* exprtypenamespace = NULL; \
appendStringInfo(str, " :exprtypename "); \
exprtypename = get_typename(typid); \
_outToken(str, exprtypename); \
pfree_ext(exprtypename); \
appendStringInfo(str, " :exprtypenamespace "); \
exprtypenamespace = get_typenamespace(typid); \
_outToken(str, exprtypenamespace); \
pfree_ext(exprtypenamespace); \
}
#define WRITE_TYPEINFO_FIELD(fldname) \
do { \
WRITE_TYPEINFO_WITHOID(node->fldname) \
} while (0)
#define WRITE_TYPEINFO_LIST(fldname) \
do { \
ListCell* cell = NULL; \
foreach (cell, node->fldname) { \
Oid typid = lfirst_oid(cell); \
WRITE_TYPEINFO_WITHOID(typid) \
} \
} while (0)
#define WRITE_TYPEINFO_ARRAY(fldname, size) \
do { \
for (int i = 0; i < node->size; i++) { \
Oid typid = node->fldname[i]; \
WRITE_TYPEINFO_WITHOID(typid) \
} \
} while (0)
/*
* Write full-text search configuration's name out of its oid
*
* openGauss defines a special type(regconfig) to express full-text search
* configuration type, and almost all the full-text search functions has a input
* para of type regconfig, and the value of the para indicates a user-defined
* full-text search configuration.
*
* In order to find the same full-text search configuration in datanode as in
* coordinator when the function is shipped to datanode from coordinator, we
* have to write full-text search configuration's name out of its oid
*/
#define WRITE_CFGINFO_FIELD(fldname1, fldname2) \
do { \
if (REGCONFIGOID == node->fldname1) { \
appendStringInfo(str, " :cfgname "); \
_outToken(str, get_cfgname(node->fldname2)); \
appendStringInfo(str, " :cfgnamespace "); \
_outToken(str, get_cfgnamespace(node->fldname2)); \
} \
} while (0)
#define WRITE_EXPRTYPEINFO_FIELD(fldname) \
do { \
if ((fldname) >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(fldname)) { \
appendStringInfo(str, " :exprtypename "); \
_outToken(str, get_typename(fldname)); \
appendStringInfo(str, " :exprtypenamespace "); \
_outToken(str, get_typenamespace(fldname)); \
} \
} while (0)
#define WRITE_FUNCINFO_FIELD(fldname) \
do { \
if (node->fldname >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->fldname)) { \
appendStringInfo(str, " :funcname "); \
_outToken(str, get_func_name(node->fldname)); \
appendStringInfo(str, " :funcnamespace "); \
_outToken(str, get_namespace_name(get_func_namespace(node->fldname))); \
} \
} while (0)
#define WRITE_PROCINFO_FIELD(fldname) \
do { \
if ((fldname) >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(fldname)) { \
appendStringInfo(str, " :funcname "); \
_outToken(str, get_func_name(fldname)); \
appendStringInfo(str, " :funcnamespace "); \
_outToken(str, get_namespace_name(get_func_namespace(fldname))); \
} \
} while (0)
#define WRITE_OPINFO_FEILD(fldname) \
; \
do { \
if (node->fldname >= FirstNormalObjectId) { \
char* oprname = NULL; \
char* nspname = NULL; \
Oid oprleft; \
Oid oprright; \
get_oper_name_namespace_oprs(node->fldname, &oprname, &nspname, &oprleft, &oprright); \
appendStringInfo(str, " :opname "); \
_outToken(str, oprname); \
appendStringInfo(str, " :opnamespace "); \
_outToken(str, nspname); \
appendStringInfo(str, " :oprleft "); \
_outToken(str, get_typename(oprleft)); \
appendStringInfo(str, " :oprright "); \
_outToken(str, get_typename(oprright)); \
pfree_ext(oprname); \
pfree_ext(nspname); \
} \
} while (0)
#define WRITE_GRPOP_FIELD(fldname, size) \
do { \
appendStringInfo(str, " :" CppAsString(fldname) " "); \
appendStringInfoChar(str, '('); \
char* oprname = NULL; \
char* nspname = NULL; \
Oid oprleft; \
Oid oprright; \
for (int i = 0; i < node->size; i++) { \
appendStringInfoChar(str, '{'); \
appendStringInfo(str, "OPERATOR "); \
appendStringInfo(str, " :opoid "); \
appendStringInfo(str, " %u", node->fldname[i]); \
if (node->fldname[i] >= FirstNormalObjectId) { \
get_oper_name_namespace_oprs(node->fldname[i], &oprname, &nspname, &oprleft, &oprright); \
appendStringInfo(str, " :oprname "); \
_outToken(str, oprname); \
appendStringInfo(str, " :oprnamespace "); \
_outToken(str, nspname); \
appendStringInfo(str, " :oprleft "); \
_outToken(str, get_typename(oprleft)); \
appendStringInfo(str, " :oprright "); \
_outToken(str, get_typename(oprright)); \
pfree_ext(oprname); \
pfree_ext(nspname); \
} \
appendStringInfoChar(str, '}'); \
} \
appendStringInfo(str, ") "); \
} while (0)
#define WRITE_SYNINFO_FIELD(fldname) \
do { \
if (OidIsValid(node->fldname)) { \
char* synName = NULL; \
char* synSchema = NULL; \
GetSynonymAndSchemaName(node->fldname, &synName, &synSchema); \
if (synName != NULL && synSchema != NULL) { \
appendStringInfo(str, " :synname "); \
_outToken(str, synName); \
appendStringInfo(str, " :synnamespace "); \
_outToken(str, synSchema); \
} \
} \
} while (0)
#define booltostr(x) ((x) ? "true" : "false")
static void _outPathInfo(StringInfo str, Path* node);
static void _outNode(StringInfo str, const void* obj);
static void out_mem_info(StringInfo str, OpMemInfo* node);
static void _outCursorData(StringInfo str, Cursor_Data* node);
static void getNameById(Oid objId, const char* context, char** objNamespace, char** objName);
/*
* _outToken
* Convert an ordinary string (eg, an identifier) into a form that
* will be decoded back to a plain token by read.c's functions.
*
* If a null or empty string is given, it is encoded as "<>".
*/
static void _outToken(StringInfo str, const char* s)
{
if (s == NULL || *s == '\0') {
appendStringInfo(str, "<>");
return;
}
/*
* Look for characters or patterns that are treated specially by read.c
* (either in pg_strtok() or in nodeRead()), and therefore need a
* protective backslash.
*/
/* These characters only need to be quoted at the start of the string */
if (*s == '<' || *s == '\"' || isdigit((unsigned char)*s) ||
((*s == '+' || *s == '-') && (isdigit((unsigned char)s[1]) || s[1] == '.'))) {
appendStringInfoChar(str, '\\');
}
while (*s) {
/* These chars must be backslashed anywhere in the string */
if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '(' || *s == ')' || *s == '{' || *s == '}' || *s == '\\') {
appendStringInfoChar(str, '\\');
}
appendStringInfoChar(str, *s++);
}
}
static void _outList(StringInfo str, List* node)
{
ListCell* lc = NULL;
appendStringInfoChar(str, '(');
if (IsA(node, IntList)) {
appendStringInfoChar(str, 'i');
} else if (IsA(node, OidList)) {
appendStringInfoChar(str, 'o');
}
foreach (lc, node) {
/*
* For the sake of backward compatibility, we emit a slightly
* different whitespace format for lists of nodes vs. other types of
* lists. XXX: is this necessary?
*/
if (IsA(node, List)) {
_outNode(str, lfirst(lc));
if (lnext(lc)) {
appendStringInfoChar(str, ' ');
}
} else if (IsA(node, IntList)) {
appendStringInfo(str, " %d", lfirst_int(lc));
} else if (IsA(node, OidList)) {
appendStringInfo(str, " %u", lfirst_oid(lc));
} else {
ereport(ERROR,
(errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("unrecognized list node type: %d", (int)node->type)));
}
}
appendStringInfoChar(str, ')');
}
/*
* _outArray
* output an array
*
* @param (in) str:
* target string to store information
* @param (in) node:
* the array node
* @param (in) len:
* the length of the array
*
* @return: void
*/
static void _outArray(StringInfo str, void** node, int len)
{
appendStringInfoChar(str, '(');
for (int i = 0; i < len; ++i) {
Node* item = (Node*)(node[i]);
if (NULL != item) {
if (IsA(item, List) || IsA(item, IntList) || IsA(item, OidList)) {
appendStringInfo(str, "{Item%d", i);
appendStringInfo(str, " :Content ");
}
_outNode(str, item);
if (IsA(item, List) || IsA(item, IntList) || IsA(item, OidList)) {
appendStringInfo(str, "}");
}
} else {
appendStringInfo(str, "{NULL");
appendStringInfo(str, "}");
}
if (i + 1 != len) {
appendStringInfoChar(str, ' ');
}
}
appendStringInfoChar(str, ')');
}
/*
* _outBitmapset -
* converts a bitmap set of integers
*
* Note: the output format is "(b int int ...)", similar to an integer List.
*/
void _outBitmapset(StringInfo str, Bitmapset* bms)
{
Bitmapset* tmpset = NULL;
int x;
appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'b');
tmpset = bms_copy(bms);
while ((x = bms_first_member(tmpset)) >= 0) {
appendStringInfo(str, " %d", x);
}
bms_free_ext(tmpset);
appendStringInfoChar(str, ')');
}
/**
* @Description: converts a array set of integers to string.
* @in str, store the the (a int int ...) format string in str.
* @in a, the given uint64 array.
* @in the length of the array.
* @return none.
* Note: the output format is "(a int int ...)", similar to an integer List.
*/
static void _outUint64Array(StringInfo str, uint64* a, int arrayLen)
{
appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'a');
for (int index = 0; index < arrayLen; index++) {
appendStringInfo(str, " %lu", a[index]);
}
appendStringInfoChar(str, ')');
}
/**
* @Description: converts a array set of integers to string.
* @in str, store the the (a int int ...) format string in str.
* @in a, the given uint16 array.
* @in the length of the array.
* @return none.
* Note: the output format is "(a int int ...)", similar to an integer List.
*/
static void _outUint16Array(StringInfo str, uint16* a, int arrayLen)
{
appendStringInfoChar(str, '(');
appendStringInfoChar(str, 'a');
for (int index = 0; index < arrayLen; index++) {
appendStringInfo(str, " %d", a[index]);
}
appendStringInfoChar(str, ')');
}
/*
* Print the value of a Datum given its type.
*/
static void _outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
{
Size length, i;
char* s = NULL;
length = datumGetSize(value, typbyval, typlen);
if (typbyval) {
s = (char*)(&value);
appendStringInfo(str, "%u [ ", (unsigned int)length);
for (i = 0; i < (Size)sizeof(Datum); i++) {
appendStringInfo(str, "%d ", (int)(s[i]));
}
appendStringInfo(str, "]");
} else {
s = (char*)DatumGetPointer(value);
if (!PointerIsValid(s)) {
appendStringInfo(str, "0 [ ]");
} else {
appendStringInfo(str, "%u [ ", (unsigned int)length);
for (i = 0; i < length; i++) {
appendStringInfo(str, "%d ", (int)(s[i]));
}
appendStringInfo(str, "]");
}
}
}
/*
* _outDistribution
* output a distribution contain node group information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the Distribution node
*
* @return: void
*/
static void _outDistribution(StringInfo str, Distribution* node)
{
WRITE_UINT_FIELD(group_oid);
WRITE_BITMAPSET_FIELD(bms_data_nodeids);
}
static void _outHDFSTableAnalyze(StringInfo str, HDFSTableAnalyze* node)
{
WRITE_NODE_TYPE("HDFSTABLEANALYZE");
WRITE_NODE_FIELD(DnWorkFlow);
WRITE_INT_FIELD(DnCnt);
WRITE_BOOL_FIELD(isHdfsStore);
appendStringInfo(str, " :sampleRate");
for (int i = 0; i < ANALYZE_MODE_MAX_NUM - 1; i++) {
appendStringInfo(str, " %.12f", node->sampleRate[i]);
}
WRITE_UINT_FIELD(orgCnNodeNo);
WRITE_BOOL_FIELD(isHdfsForeignTbl);
WRITE_BOOL_FIELD(sampleTableRequired);
WRITE_NODE_FIELD(tmpSampleTblNameList);
WRITE_ENUM_FIELD(disttype, DistributionType);
WRITE_INT_FIELD(memUsage.work_mem);
WRITE_INT_FIELD(memUsage.max_mem);
}
/*
* Stuff from plannodes.h
*/
static void _outPlannedStmt(StringInfo str, PlannedStmt* node)
{
WRITE_NODE_TYPE("PLANNEDSTMT");
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_UINT64_FIELD(queryId);
WRITE_BOOL_FIELD(hasReturning);
WRITE_BOOL_FIELD(hasModifyingCTE);
if (t_thrd.proc->workingVersionNum >= KEYWORD_IGNORE_COMPART_VERSION_NUM) {
WRITE_BOOL_FIELD(hasIgnore);
}
WRITE_BOOL_FIELD(canSetTag);
WRITE_BOOL_FIELD(transientPlan);
WRITE_BOOL_FIELD(dependsOnRole);
WRITE_NODE_FIELD(planTree);
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(utilityStmt);
WRITE_NODE_FIELD(subplans);
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_INT_FIELD(nParamExec);
WRITE_INT_FIELD(num_streams);
WRITE_INT_FIELD(max_push_sql_num);
WRITE_INT_FIELD(gather_count);
WRITE_INT_FIELD(num_nodes);
if (t_thrd.proc->workingVersionNum < 92097 || node->num_streams > 0) {
for (int i = 0; i < node->num_nodes; i++) {
/* Write the field name only one time and just append the value of each field */
appendStringInfo(str, " :nodesDefinition[%d]", i);
appendStringInfo(str, " %u", node->nodesDefinition[i].nodeoid);
appendStringInfo(str, " %s", node->nodesDefinition[i].nodename.data);
appendStringInfo(str, " %s", node->nodesDefinition[i].nodehost.data);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodeport);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodectlport);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodesctpport);
appendStringInfo(str, " %s", node->nodesDefinition[i].nodehost1.data);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodeport1);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodectlport1);
appendStringInfo(str, " %d", node->nodesDefinition[i].nodesctpport1);
appendStringInfo(str, " %s", booltostr(node->nodesDefinition[i].nodeisprimary));
appendStringInfo(str, " %s", booltostr(node->nodesDefinition[i].nodeispreferred));
}
}
WRITE_INT_FIELD(instrument_option);
WRITE_INT_FIELD(num_plannodes);
WRITE_INT_FIELD(query_mem[0]);
WRITE_INT_FIELD(query_mem[1]);
WRITE_INT_FIELD(assigned_query_mem[0]);
WRITE_INT_FIELD(assigned_query_mem[1]);
WRITE_INT_FIELD(num_bucketmaps);
for (int j = 0; j < node->num_bucketmaps; j++) {
if (t_thrd.proc->workingVersionNum >= SEGMENT_PAGE_VERSION_NUM) {
appendStringInfo(str, " :bucketCnt");
appendStringInfo(str, " %d", node->bucketCnt[j]);
}
appendStringInfo(str, " :bucketMap");
if (node->bucketMap[j]) {
for (int i = 0; i < node->bucketCnt[j]; i++) {
appendStringInfo(str, " %d", node->bucketMap[j][i]);
}
} else {
appendStringInfo(str, " <>");
}
}
WRITE_STRING_FIELD(query_string);
WRITE_NODE_FIELD(subplan_ids);
WRITE_NODE_FIELD(initPlan);
/* data redistribution for DFS table. */
WRITE_UINT_FIELD(dataDestRelIndex);
WRITE_INT_FIELD(MaxBloomFilterNum);
WRITE_INT_FIELD(query_dop);
WRITE_BOOL_FIELD(in_compute_pool);
WRITE_BOOL_FIELD(has_obsrel);
WRITE_INT_FIELD(ng_num);
for (int i = 0; i < node->ng_num; i++) {
appendStringInfo(str, " %s", node->ng_queryMem[i].nodegroup);
appendStringInfo(str, " %d", node->ng_queryMem[i].query_mem[0]);
appendStringInfo(str, " %d", node->ng_queryMem[i].query_mem[1]);
}
WRITE_BOOL_FIELD(isRowTriggerShippable);
WRITE_BOOL_FIELD(is_stream_plan);
}
/*
* print the basic stuff of all nodes that inherit from Plan
*/
static void _outPlanInfo(StringInfo str, Plan* node)
{
WRITE_INT_FIELD(plan_node_id);
WRITE_INT_FIELD(parent_node_id);
WRITE_ENUM_FIELD(exec_type, RemoteQueryExecType);
/* eliminate the statistics for plan hashkey generation. */
if (u_sess->opt_cxt.out_plan_stat) {
WRITE_FLOAT_FIELD(startup_cost, "%.2f");
WRITE_FLOAT_FIELD(total_cost, "%.2f");
/* When sending rows to dn, transfer to local rows before output. */
appendStringInfo(str, " :plan_rows %.0f", PLAN_LOCAL_ROWS(node));
WRITE_FLOAT_FIELD(multiple, "%.0f");
WRITE_INT_FIELD(plan_width);
}
WRITE_NODE_FIELD(targetlist);
WRITE_NODE_FIELD(qual);
WRITE_NODE_FIELD(lefttree);
WRITE_NODE_FIELD(righttree);
WRITE_BOOL_FIELD(ispwj);
WRITE_INT_FIELD(paramno);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_INT_FIELD(subparamno);
}
WRITE_NODE_FIELD(initPlan);
WRITE_NODE_FIELD(distributed_keys);
WRITE_NODE_FIELD(exec_nodes);
WRITE_BITMAPSET_FIELD(extParam);
WRITE_BITMAPSET_FIELD(allParam);
WRITE_BOOL_FIELD(vec_output);
WRITE_BOOL_FIELD(hasUniqueResults);
WRITE_BOOL_FIELD(isDeltaTable);
WRITE_INT_FIELD(operatorMemKB[0]);
WRITE_INT_FIELD(operatorMemKB[1]);
WRITE_INT_FIELD(operatorMaxMem);
WRITE_BOOL_FIELD(parallel_enabled);
WRITE_BOOL_FIELD(hasHashFilter);
WRITE_NODE_FIELD(var_list);
WRITE_NODE_FIELD(filterIndexList);
WRITE_INT_FIELD(dop);
WRITE_INT_FIELD(recursive_union_plan_nodeid);
WRITE_BOOL_FIELD(recursive_union_controller);
WRITE_INT_FIELD(control_plan_nodeid);
WRITE_BOOL_FIELD(is_sync_plannode);
if (t_thrd.proc->workingVersionNum >= ML_OPT_MODEL_VERSION_NUM) {
WRITE_FLOAT_FIELD(pred_rows, "%.0f");
WRITE_FLOAT_FIELD(pred_startup_time, "%.0f");
WRITE_FLOAT_FIELD(pred_total_time, "%.0f");
WRITE_FLOAT_FIELD(pred_max_memory, "%ld");
}
}
static void _outPruningResult(StringInfo str, PruningResult* node)
{
const int num = 92267;
WRITE_NODE_TYPE("PRUNINGRESULT");
WRITE_ENUM_FIELD(state, PruningResultState);
/* skip boundary info */
WRITE_BITMAPSET_FIELD(bm_rangeSelectedPartitions);
WRITE_INT_FIELD(intervalOffset);
WRITE_BITMAPSET_FIELD(intervalSelectedPartitions);
WRITE_NODE_FIELD(ls_rangeSelectedPartitions);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_NODE_FIELD(ls_selectedSubPartitions);
}
if (t_thrd.proc->workingVersionNum >= num) {
WRITE_NODE_FIELD(expr);
}
if (t_thrd.proc->workingVersionNum >= PBESINGLEPARTITION_VERSION_NUM) {
WRITE_BOOL_FIELD(isPbeSinlePartition);
}
/* skip PartitionMap */
}
static void _outSubPartitionPruningResult(StringInfo str, SubPartitionPruningResult* node)
{
WRITE_NODE_TYPE("SUBPARTITIONPRUNINGRESULT");
WRITE_INT_FIELD(partSeq);
WRITE_BITMAPSET_FIELD(bm_selectedSubPartitions);
WRITE_NODE_FIELD(ls_selectedSubPartitions);
}
/*
* print the basic stuff of all nodes that inherit from Scan
*/
static void _outScanInfo(StringInfo str, Scan* node)
{
_outPlanInfo(str, (Plan*)node);
WRITE_UINT_FIELD(scanrelid);
WRITE_BOOL_FIELD(isPartTbl);
WRITE_INT_FIELD(itrs);
WRITE_NODE_FIELD(pruningInfo);
if (t_thrd.proc->workingVersionNum >= 92063) {
WRITE_NODE_FIELD(bucketInfo);
}
WRITE_ENUM_FIELD(partScanDirection, ScanDirection);
WRITE_BOOL_FIELD(scan_qual_optimized);
WRITE_BOOL_FIELD(predicate_pushdown_optimized);
WRITE_NODE_FIELD(tablesample);
out_mem_info(str, &node->mem_info);
if (t_thrd.proc->workingVersionNum >= SCAN_BATCH_MODE_VERSION_NUM) {
WRITE_BOOL_FIELD(scanBatchMode);
}
if (t_thrd.proc->workingVersionNum >= 92753) {
WRITE_BOOL_FIELD(partition_iterator_elimination);
}
}
/*
* print the basic stuff of all nodes that inherit from Join
*/
static void _outJoinPlanInfo(StringInfo str, Join* node)
{
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_NODE_FIELD(joinqual);
WRITE_BOOL_FIELD(optimizable);
WRITE_NODE_FIELD(nulleqqual);
WRITE_UINT_FIELD(skewoptimize);
}
static void _outPlan(StringInfo str, Plan* node)
{
WRITE_NODE_TYPE("PLAN");
_outPlanInfo(str, (Plan*)node);
}
static void _outResult(StringInfo str, BaseResult* node)
{
WRITE_NODE_TYPE("RESULT");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(resconstantqual);
}
static void _outModifyTable(StringInfo str, ModifyTable* node)
{
WRITE_NODE_TYPE("MODIFYTABLE");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
WRITE_NODE_FIELD(plans);
WRITE_NODE_FIELD(returningLists);
WRITE_NODE_FIELD(fdwPrivLists);
WRITE_NODE_FIELD(rowMarks);
WRITE_INT_FIELD(epqParam);
WRITE_BOOL_FIELD(partKeyUpdated);
if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {
WRITE_BOOL_FIELD(isReplace);
}
#ifdef PGXC
WRITE_NODE_FIELD(remote_plans);
WRITE_NODE_FIELD(remote_insert_plans);
WRITE_NODE_FIELD(remote_update_plans);
WRITE_NODE_FIELD(remote_delete_plans);
#endif
WRITE_BOOL_FIELD(is_dist_insertselect);
WRITE_NODE_FIELD(cacheEnt);
WRITE_INT_FIELD(mergeTargetRelation);
WRITE_NODE_FIELD(mergeSourceTargetList);
WRITE_NODE_FIELD(mergeActionList);
#ifdef ENABLE_MULTIPLE_NODES
if (t_thrd.proc->workingVersionNum >= UPSERT_ROW_STORE_VERSION_NUM) {
WRITE_ENUM_FIELD(upsertAction, UpsertAction);
WRITE_NODE_FIELD(updateTlist);
WRITE_NODE_FIELD(exclRelTlist);
WRITE_INT_FIELD(exclRelRTIndex);
}
if (t_thrd.proc->workingVersionNum >= UPSERT_WHERE_VERSION_NUM) {
WRITE_NODE_FIELD(upsertWhere);
}
#else
WRITE_ENUM_FIELD(upsertAction, UpsertAction);
WRITE_NODE_FIELD(updateTlist);
WRITE_NODE_FIELD(exclRelTlist);
WRITE_INT_FIELD(exclRelRTIndex);
WRITE_NODE_FIELD(upsertWhere);
if (t_thrd.proc->workingVersionNum >= MULTI_MODIFY_VERSION_NUM) {
WRITE_NODE_FIELD(targetlists);
}
#endif
}
static void _outUpsertClause(StringInfo str, const UpsertClause* node)
{
WRITE_NODE_TYPE("UPSERTCLAUSE");
WRITE_NODE_FIELD(targetList);
WRITE_INT_FIELD(location);
if (t_thrd.proc->workingVersionNum >= UPSERT_WHERE_VERSION_NUM) {
WRITE_NODE_FIELD(whereClause);
}
}
static void _outUpsertExpr(StringInfo str, const UpsertExpr* node)
{
WRITE_NODE_TYPE("UPSERTEXPR");
WRITE_ENUM_FIELD(upsertAction, UpsertAction);
WRITE_NODE_FIELD(updateTlist);
WRITE_NODE_FIELD(exclRelTlist);
WRITE_INT_FIELD(exclRelIndex);
WRITE_NODE_FIELD(upsertWhere);
}
static void _outMergeWhenClause(StringInfo str, const MergeWhenClause* node)
{
WRITE_NODE_TYPE("MERGEWHENCLAUSE");
WRITE_BOOL_FIELD(matched);
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_NODE_FIELD(condition);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(cols);
WRITE_NODE_FIELD(values);
}
static void _outAppend(StringInfo str, Append* node)
{
WRITE_NODE_TYPE("APPEND");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(appendplans);
}
static void _outVecAppend(StringInfo str, Append* node)
{
WRITE_NODE_TYPE("VECAPPEND");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(appendplans);
}
static void _outMergeAppend(StringInfo str, MergeAppend* node)
{
int i;
WRITE_NODE_TYPE("MERGEAPPEND");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(mergeplans);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :sortColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->sortColIdx[i]);
}
WRITE_GRPOP_FIELD(sortOperators, numCols);
appendStringInfo(str, " :collations");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->collations[i]);
}
// We should use collcation name instead of colloid when
// node->collOid is user-defined, because DN and CN use different OID
// though the objection name is the same
// Note that if this function change, you must check function _readSort()
//
for (i = 0; i < node->numCols; i++) {
if (node->collations[i] >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->collations[i])) {
appendStringInfo(str, " :collname ");
_outToken(str, get_collation_name(node->collations[i]));
}
}
appendStringInfo(str, " :nullsFirst");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
}
}
static void _outStartWithOp(StringInfo str, StartWithOp *node)
{
WRITE_NODE_TYPE("STARTWITHOP");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(cteplan);
WRITE_NODE_FIELD(ruplan);
WRITE_NODE_FIELD(keyEntryList);
WRITE_NODE_FIELD(colEntryList);
WRITE_NODE_FIELD(internalEntryList);
WRITE_NODE_FIELD(fullEntryList);
WRITE_NODE_FIELD(swoptions);
}
static void _outStartWithOptions(StringInfo str, StartWithOptions* node)
{
WRITE_NODE_TYPE("STARTWITHOPTIONS");
WRITE_NODE_FIELD(siblings_orderby_clause);
WRITE_NODE_FIELD(prior_key_index);
WRITE_ENUM_FIELD(connect_by_type, StartWithConnectByType);
WRITE_NODE_FIELD(connect_by_level_quals);
WRITE_NODE_FIELD(connect_by_other_quals);
WRITE_BOOL_FIELD(nocycle);
}
static void _outRecursiveUnion(StringInfo str, RecursiveUnion* node)
{
int i;
WRITE_NODE_TYPE("RECURSIVEUNION");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(wtParam);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :dupColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->dupColIdx[i]);
}
WRITE_GRPOP_FIELD(dupOperators, numCols);
WRITE_LONG_FIELD(numGroups);
WRITE_BOOL_FIELD(has_inner_stream);
WRITE_BOOL_FIELD(has_outer_stream);
WRITE_BOOL_FIELD(is_used);
WRITE_BOOL_FIELD(is_correlated);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_NODE_FIELD(internalEntryList);
}
}
static void _outBitmapAnd(StringInfo str, BitmapAnd* node)
{
WRITE_NODE_TYPE("BITMAPAND");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(bitmapplans);
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
}
static void _outBitmapOr(StringInfo str, BitmapOr* node)
{
WRITE_NODE_TYPE("BITMAPOR");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(bitmapplans);
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
}
static void _outCStoreIndexOr(StringInfo str, CStoreIndexOr* node)
{
WRITE_NODE_TYPE("CSTOREINDEXOR");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(bitmapplans);
}
static void _outCStoreIndexAnd(StringInfo str, CStoreIndexAnd* node)
{
WRITE_NODE_TYPE("CSTOREINDEXAND");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(bitmapplans);
}
static void _outBucketInfo(StringInfo str, BucketInfo* node)
{
WRITE_NODE_TYPE("BUCKETINFO");
WRITE_NODE_FIELD(buckets);
}
static void _outScan(StringInfo str, Scan* node)
{
WRITE_NODE_TYPE("SCAN");
_outScanInfo(str, (Scan*)node);
}
static void _outSeqScan(StringInfo str, SeqScan* node)
{
WRITE_NODE_TYPE("SEQSCAN");
_outScanInfo(str, (Scan*)node);
}
template <typename T>
static void _outCommonIndexScanPart(StringInfo str, T* node)
{
_outScanInfo(str, (Scan*)node);
WRITE_OID_FIELD(indexid);
#ifdef STREAMPLAN
if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) {
appendStringInfo(str, " :indexname ");
_outToken(str, get_rel_name(node->indexid));
appendStringInfo(str, " :indexnamespace ");
_outToken(str, get_namespace_name(get_rel_namespace(node->indexid)));
}
#endif // STREAMPLAN
WRITE_NODE_FIELD(indexqual);
WRITE_NODE_FIELD(indexqualorig);
WRITE_NODE_FIELD(indexorderby);
WRITE_NODE_FIELD(indexorderbyorig);
WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
}
static void _outIndexScan(StringInfo str, IndexScan* node)
{
WRITE_NODE_TYPE("INDEXSCAN");
_outCommonIndexScanPart<IndexScan>(str, node);
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) {
WRITE_FLOAT_FIELD(selectivity, "%.4f");
WRITE_BOOL_FIELD(is_partial);
}
}
static void _outCStoreIndexScan(StringInfo str, CStoreIndexScan* node)
{
WRITE_NODE_TYPE("CSTOREINDEXSCAN");
_outCommonIndexScanPart<CStoreIndexScan>(str, node);
WRITE_NODE_FIELD(baserelcstorequal);
WRITE_NODE_FIELD(cstorequal);
WRITE_NODE_FIELD(indextlist);
WRITE_ENUM_FIELD(relStoreLocation, RelstoreType);
WRITE_BOOL_FIELD(indexonly);
}
static void _outStream(StringInfo str, Stream* node)
{
WRITE_NODE_TYPE("STREAM");
_outScanInfo(str, (Scan*)node);
WRITE_ENUM_FIELD(type, StreamType);
WRITE_STRING_FIELD(plan_statement);
WRITE_NODE_FIELD(consumer_nodes);
WRITE_NODE_FIELD(distribute_keys);
WRITE_BOOL_FIELD(is_sorted);
WRITE_NODE_FIELD(sort);
WRITE_BOOL_FIELD(is_dummy);
WRITE_INT_FIELD(smpDesc.consumerDop);
WRITE_INT_FIELD(smpDesc.producerDop);
WRITE_ENUM_FIELD(smpDesc.distriType, SmpStreamType);
WRITE_NODE_FIELD(skew_list);
WRITE_INT_FIELD(stream_level);
WRITE_NODE_FIELD(origin_consumer_nodes);
WRITE_BOOL_FIELD(is_recursive_local);
}
/*
* _outStreamPath
* output a StreamPath node
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the StreamPath node
*
* @return: void
*/
static void _outStreamPath(StringInfo str, StreamPath* node)
{
WRITE_NODE_TYPE("STREAMPATH");
_outPathInfo(str, (Path*)node);
WRITE_ENUM_FIELD(type, StreamType);
WRITE_NODE_FIELD(subpath);
_outDistribution(str, &(node->consumer_distribution));
}
#ifdef PGXC
template <typename T>
static void _outCommonRemoteQueryPart(StringInfo str, T* node)
{
int i;
_outScanInfo(str, (Scan*)node);
WRITE_ENUM_FIELD(exec_direct_type, ExecDirectType);
WRITE_STRING_FIELD(sql_statement);
WRITE_NODE_FIELD(exec_nodes);
WRITE_ENUM_FIELD(combine_type, CombineType);
WRITE_BOOL_FIELD(read_only);
WRITE_BOOL_FIELD(force_autocommit);
WRITE_STRING_FIELD(statement);
WRITE_STRING_FIELD(cursor);
WRITE_INT_FIELD(rq_num_params);
if (node->rq_num_params > 0) {
appendStringInfo(str, " :rq_param_types");
}
for (i = 0; i < node->rq_num_params; i++) {
appendStringInfo(str, " %d", node->rq_param_types[i]);
}
WRITE_BOOL_FIELD(rq_params_internal);
WRITE_ENUM_FIELD(exec_type, RemoteQueryExecType);
WRITE_BOOL_FIELD(is_temp);
WRITE_BOOL_FIELD(rq_finalise_aggs);
WRITE_BOOL_FIELD(rq_sortgroup_colno);
WRITE_NODE_FIELD(remote_query);
WRITE_NODE_FIELD(base_tlist);
WRITE_NODE_FIELD(coord_var_tlist);
WRITE_NODE_FIELD(query_var_tlist);
WRITE_BOOL_FIELD(has_row_marks);
WRITE_BOOL_FIELD(rq_save_command_id);
WRITE_BOOL_FIELD(is_simple);
WRITE_BOOL_FIELD(mergesort_required);
WRITE_BOOL_FIELD(spool_no_data);
WRITE_BOOL_FIELD(poll_multi_channel);
WRITE_INT_FIELD(num_stream);
WRITE_INT_FIELD(num_gather);
WRITE_NODE_FIELD(sort);
WRITE_NODE_FIELD(rte_ref);
WRITE_ENUM_FIELD(position, RemoteQueryType);
WRITE_TYPEINFO_ARRAY(rq_param_types, rq_num_params);
if (t_thrd.proc->workingVersionNum >= EXECUTE_DIRECT_ON_MULTI_VERSION_NUM) {
WRITE_BOOL_FIELD(is_remote_function_query);
}
if (t_thrd.proc->workingVersionNum >= FIX_PBE_CUSTOME_PLAN_BUG_VERSION_NUM) {
WRITE_BOOL_FIELD(isCustomPlan);
WRITE_BOOL_FIELD(isFQS);
}
if (t_thrd.proc->workingVersionNum >= FIX_SQL_ADD_RELATION_REF_COUNT) {
WRITE_NODE_FIELD(relationOids);
}
}
static void _outRemoteQuery(StringInfo str, RemoteQuery* node)
{
WRITE_NODE_TYPE("REMOTEQUERY");
_outCommonRemoteQueryPart<RemoteQuery>(str, node);
}
/*
* _outRemoteQueryPath
* output a RemoteQueryPath node's information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the RemoteQueryPath node
*
* @return: void
*/
static void _outRemoteQueryPath(StringInfo str, RemoteQueryPath* node)
{
WRITE_NODE_TYPE("REMOTEQUERYPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(rqpath_en);
WRITE_NODE_FIELD(leftpath);
WRITE_NODE_FIELD(rightpath);
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_NODE_FIELD(join_restrictlist);
WRITE_BOOL_FIELD(rqhas_unshippable_qual);
WRITE_BOOL_FIELD(rqhas_temp_rel);
WRITE_BOOL_FIELD(rqhas_unshippable_tlist);
}
static void _outSliceBoundary(StringInfo str, SliceBoundary* node)
{
WRITE_NODE_TYPE("SLICEBOUNDARY");
WRITE_INT_FIELD(nodeIdx);
WRITE_INT_FIELD(len);
WRITE_ARRAY_FIELD(boundary, node->len);
}
static void _outExecBoundary(StringInfo str, ExecBoundary* node)
{
WRITE_NODE_TYPE("EXECBOUNDARY");
WRITE_CHAR_FIELD(locatorType);
WRITE_INT_FIELD(count);
WRITE_ARRAY_FIELD(eles, node->count);
}
/*
* _outExecNodes
* output a ExecNodes node's information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the ExecNodes node
*
* @return: void
*/
static void _outExecNodes(StringInfo str, ExecNodes* node)
{
WRITE_NODE_TYPE("EXEC_NODES");
WRITE_NODE_FIELD(primarynodelist);
WRITE_NODE_FIELD(nodeList);
_outDistribution(str, &node->distribution);
if (node->baselocatortype != '\0') {
WRITE_CHAR_FIELD(baselocatortype);
}
WRITE_NODE_FIELD(en_expr);
WRITE_OID_FIELD(en_relid);
if (node->boundaries != NULL) {
WRITE_NODE_FIELD(boundaries);
}
WRITE_ENUM_FIELD(accesstype, RelationAccessType);
WRITE_NODE_FIELD(en_dist_vars);
WRITE_INT_FIELD(bucketmapIdx);
WRITE_BOOL_FIELD(nodelist_is_nil);
WRITE_NODE_FIELD(original_nodeList);
WRITE_NODE_FIELD(dynamic_en_expr);
if (t_thrd.proc->workingVersionNum >= 92106) {
WRITE_INT_FIELD(bucketid);
WRITE_NODE_FIELD(bucketexpr);
WRITE_OID_FIELD(bucketrelid);
/*
* shipping out for dn, relid will be different on dn,
* so relname and relnamespace string will be must.
*/
if (node->bucketrelid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->bucketrelid)) {
char* rte_relname = NULL;
char* rte_relnamespace = NULL;
getNameById(node->bucketrelid, "RTE", &rte_relnamespace, &rte_relname);
appendStringInfo(str, " :relname ");
_outToken(str, rte_relname);
appendStringInfo(str, " :relnamespace ");
_outToken(str, rte_relnamespace);
}
}
}
#endif
static void _outIndexOnlyScan(StringInfo str, IndexOnlyScan* node)
{
WRITE_NODE_TYPE("INDEXONLYSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_OID_FIELD(indexid);
if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) {
/*
* For inherit table, the relname will be different
*/
appendStringInfo(str, " :indexname ");
_outToken(str, get_rel_name(node->indexid));
appendStringInfo(str, " :indexnamespace ");
_outToken(str, get_namespace_name(get_rel_namespace(node->indexid)));
}
WRITE_NODE_FIELD(indexqual);
WRITE_NODE_FIELD(indexorderby);
WRITE_NODE_FIELD(indextlist);
WRITE_ENUM_FIELD(indexorderdir, ScanDirection);
if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) {
WRITE_FLOAT_FIELD(selectivity, "%.4f");
WRITE_BOOL_FIELD(is_partial);
}
}
static void _outBitmapIndexScan(StringInfo str, BitmapIndexScan* node)
{
WRITE_NODE_TYPE("BITMAPINDEXSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_OID_FIELD(indexid);
WRITE_NODE_FIELD(indexqual);
WRITE_NODE_FIELD(indexqualorig);
#ifdef STREAMPLAN
if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) {
appendStringInfo(str, " :indexname ");
_outToken(str, get_rel_name(node->indexid));
appendStringInfo(str, " :indexnamespace ");
_outToken(str, get_namespace_name(get_rel_namespace(node->indexid)));
}
#endif // STREAMPLAN
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) {
WRITE_FLOAT_FIELD(selectivity, "%.4f");
WRITE_BOOL_FIELD(is_partial);
}
}
static void _outBitmapHeapScan(StringInfo str, BitmapHeapScan* node)
{
WRITE_NODE_TYPE("BITMAPHEAPSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(bitmapqualorig);
}
static void _outCStoreIndexCtidScan(StringInfo str, CStoreIndexCtidScan* node)
{
WRITE_NODE_TYPE("CSTOREINDEXCTIDSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_OID_FIELD(indexid);
WRITE_NODE_FIELD(indexqual);
WRITE_NODE_FIELD(cstorequal);
WRITE_NODE_FIELD(indexqualorig);
#ifdef STREAMPLAN
if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) {
appendStringInfo(str, " :indexname ");
_outToken(str, get_rel_name(node->indexid));
appendStringInfo(str, " :indexnamespace ");
_outToken(str, get_namespace_name(get_rel_namespace(node->indexid)));
}
#endif // STREAMPLAN
WRITE_NODE_FIELD(indextlist);
}
static void _outCStoreIndexHeapScan(StringInfo str, CStoreIndexHeapScan* node)
{
WRITE_NODE_TYPE("CSTOREINDEXHEAPSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(bitmapqualorig);
}
static void _outTidScan(StringInfo str, TidScan* node)
{
WRITE_NODE_TYPE("TIDSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(tidquals);
}
static void _outPartIteratorParam(StringInfo str, PartIteratorParam* node)
{
WRITE_NODE_TYPE("PARTITERATORPARAM");
WRITE_INT_FIELD(paramno);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_INT_FIELD(subPartParamno);
}
}
static void _outPartIterator(StringInfo str, PartIterator* node)
{
WRITE_NODE_TYPE("PARTITERATOR");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(partType, PartitionType);
WRITE_INT_FIELD(itrs);
WRITE_ENUM_FIELD(direction, ScanDirection);
WRITE_NODE_FIELD(param);
}
static void _outSubqueryScan(StringInfo str, SubqueryScan* node)
{
WRITE_NODE_TYPE("SUBQUERYSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(subplan);
}
static void _outFunctionScan(StringInfo str, FunctionScan* node)
{
WRITE_NODE_TYPE("FUNCTIONSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(funcexpr);
WRITE_NODE_FIELD(funccolnames);
WRITE_NODE_FIELD(funccoltypes);
WRITE_NODE_FIELD(funccoltypmods);
WRITE_NODE_FIELD(funccolcollations);
WRITE_TYPEINFO_LIST(funccoltypes);
}
static void _outValuesScan(StringInfo str, ValuesScan* node)
{
WRITE_NODE_TYPE("VALUESSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(values_lists);
}
static void _outCteScan(StringInfo str, CteScan* node)
{
WRITE_NODE_TYPE("CTESCAN");
_outScanInfo(str, (Scan*)node);
WRITE_INT_FIELD(ctePlanId);
WRITE_INT_FIELD(cteParam);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_NODE_FIELD(cteRef);
WRITE_NODE_FIELD(internalEntryList);
}
}
static void _outWorkTableScan(StringInfo str, WorkTableScan* node)
{
WRITE_NODE_TYPE("WORKTABLESCAN");
_outScanInfo(str, (Scan*)node);
WRITE_INT_FIELD(wtParam);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_BOOL_FIELD(forStartWith);
}
}
template <typename T>
static void _outCommonForeignScanPart(StringInfo str, T* node)
{
_outScanInfo(str, (Scan*)node);
WRITE_OID_FIELD(scan_relid);
WRITE_NODE_FIELD(fdw_exprs);
WRITE_NODE_FIELD(fdw_private);
WRITE_BOOL_FIELD(fsSystemCol);
WRITE_BOOL_FIELD(needSaveError);
WRITE_NODE_FIELD(errCache);
WRITE_NODE_FIELD(prunningResult);
WRITE_NODE_FIELD(rel);
WRITE_NODE_FIELD(options);
WRITE_LONG_FIELD(objectNum);
WRITE_INT_FIELD(bfNum);
for (int i = 0; i < node->bfNum; i++) {
WRITE_NODE_FIELD(bloomFilterSet[i]);
}
WRITE_BOOL_FIELD(in_compute_pool);
}
static void _outForeignScan(StringInfo str, ForeignScan* node)
{
WRITE_NODE_TYPE("FOREIGNSCAN");
_outCommonForeignScanPart<ForeignScan>(str, node);
}
static void _outForeignPartState(StringInfo str, ForeignPartState* node)
{
WRITE_NODE_TYPE("FOREIGNPARTSTATE");
WRITE_NODE_FIELD(partitionKey);
}
static void _outExtensiblePlan(StringInfo str, ExtensiblePlan* node)
{
WRITE_NODE_TYPE("EXTENSIBLEPLAN");
_outScanInfo(str, (Scan*)node);
WRITE_UINT_FIELD(flags);
WRITE_NODE_FIELD(extensible_plans);
WRITE_NODE_FIELD(extensible_exprs);
WRITE_NODE_FIELD(extensible_private);
WRITE_NODE_FIELD(extensible_plan_tlist);
WRITE_BITMAPSET_FIELD(extensible_relids);
/* ExtensibleName is a key to lookup ExtensiblePlanMethods */
appendStringInfoString(str, " :methods ");
_outToken(str, node->methods->ExtensibleName);
}
static void _outJoin(StringInfo str, Join* node)
{
WRITE_NODE_TYPE("JOIN");
_outJoinPlanInfo(str, (Join*)node);
}
static void _outNestLoop(StringInfo str, NestLoop* node)
{
WRITE_NODE_TYPE("NESTLOOP");
_outJoinPlanInfo(str, (Join*)node);
WRITE_NODE_FIELD(nestParams);
WRITE_BOOL_FIELD(materialAll);
}
static void _outVecNestLoop(StringInfo str, VecNestLoop* node)
{
WRITE_NODE_TYPE("VECNESTLOOP");
_outJoinPlanInfo(str, (Join*)node);
WRITE_NODE_FIELD(nestParams);
WRITE_BOOL_FIELD(materialAll);
}
static void _outVecMaterial(StringInfo str, VecMaterial* node)
{
WRITE_NODE_TYPE("VECMATERIAL");
_outPlanInfo(str, (Plan*)node);
WRITE_BOOL_FIELD(materialize_all);
out_mem_info(str, &node->mem_info);
}
template <typename T>
static void _outCommonJoinPart(StringInfo str, T* node)
{
int numCols;
int i;
_outJoinPlanInfo(str, (Join*)node);
WRITE_NODE_FIELD(mergeclauses);
numCols = list_length(node->mergeclauses);
appendStringInfo(str, " :mergeFamilies");
for (i = 0; i < numCols; i++) {
appendStringInfo(str, " %u", node->mergeFamilies[i]);
}
appendStringInfo(str, " :mergeCollations");
for (i = 0; i < numCols; i++) {
appendStringInfo(str, " %u", node->mergeCollations[i]);
}
appendStringInfo(str, " :mergeStrategies");
for (i = 0; i < numCols; i++) {
appendStringInfo(str, " %d", node->mergeStrategies[i]);
}
appendStringInfo(str, " :mergeNullsFirst");
for (i = 0; i < numCols; i++) {
appendStringInfo(str, " %s", booltostr(node->mergeNullsFirst[i]));
}
}
static void _outMergeJoin(StringInfo str, MergeJoin* node)
{
WRITE_NODE_TYPE("MERGEJOIN");
_outCommonJoinPart<MergeJoin>(str, node);
}
static void _outVecMergeJoin(StringInfo str, VecMergeJoin* node)
{
WRITE_NODE_TYPE("VECMERGEJOIN");
_outCommonJoinPart<VecMergeJoin>(str, node);
}
static void _outHashJoin(StringInfo str, HashJoin* node)
{
WRITE_NODE_TYPE("HASHJOIN");
_outJoinPlanInfo(str, (Join*)node);
WRITE_NODE_FIELD(hashclauses);
WRITE_BOOL_FIELD(streamBothSides);
WRITE_BOOL_FIELD(transferFilterFlag);
WRITE_BOOL_FIELD(rebuildHashTable);
WRITE_BOOL_FIELD(isSonicHash);
out_mem_info(str, &node->mem_info);
}
static void _outVecHashJoin(StringInfo str, VecHashJoin* node)
{
WRITE_NODE_TYPE("VECHASHJOIN");
_outJoinPlanInfo(str, (Join*)node);
WRITE_NODE_FIELD(hashclauses);
WRITE_BOOL_FIELD(streamBothSides);
WRITE_BOOL_FIELD(transferFilterFlag);
WRITE_BOOL_FIELD(rebuildHashTable);
WRITE_BOOL_FIELD(isSonicHash);
out_mem_info(str, &node->mem_info);
}
static void _outVecHashAgg(StringInfo str, VecAgg* node)
{
int i;
WRITE_NODE_TYPE("VECAGG");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :grpColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->grpColIdx[i]);
}
appendStringInfo(str, " :grpOperators");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->grpOperators[i]);
}
WRITE_LONG_FIELD(numGroups);
WRITE_NODE_FIELD(groupingSets);
WRITE_NODE_FIELD(chain);
WRITE_BOOL_FIELD(is_final);
WRITE_BOOL_FIELD(single_node);
WRITE_BITMAPSET_FIELD(aggParams);
out_mem_info(str, &node->mem_info);
WRITE_BOOL_FIELD(is_sonichash);
WRITE_UINT_FIELD(skew_optimize);
if (t_thrd.proc->workingVersionNum >= SUBLINKPULLUP_VERSION_NUM) {
WRITE_BOOL_FIELD(unique_check);
}
}
static void _outAgg(StringInfo str, Agg* node)
{
int i;
WRITE_NODE_TYPE("AGG");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :grpColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->grpColIdx[i]);
}
WRITE_GRPOP_FIELD(grpOperators, numCols);
WRITE_LONG_FIELD(numGroups);
WRITE_NODE_FIELD(groupingSets);
WRITE_NODE_FIELD(chain);
WRITE_BOOL_FIELD(is_final);
WRITE_BOOL_FIELD(single_node);
WRITE_BITMAPSET_FIELD(aggParams);
out_mem_info(str, &node->mem_info);
WRITE_BOOL_FIELD(is_sonichash);
WRITE_BOOL_FIELD(is_dummy);
WRITE_UINT_FIELD(skew_optimize);
if (t_thrd.proc->workingVersionNum >= SUBLINKPULLUP_VERSION_NUM) {
WRITE_BOOL_FIELD(unique_check);
}
}
static void _outWindowAgg(StringInfo str, WindowAgg* node)
{
int i;
WRITE_NODE_TYPE("WINDOWAGG");
_outPlanInfo(str, (Plan*)node);
WRITE_UINT_FIELD(winref);
WRITE_INT_FIELD(partNumCols);
appendStringInfo(str, " :partColIdx");
for (i = 0; i < node->partNumCols; i++) {
appendStringInfo(str, " %d", node->partColIdx[i]);
}
WRITE_GRPOP_FIELD(partOperators, partNumCols);
WRITE_INT_FIELD(ordNumCols);
appendStringInfo(str, " :ordColIdx");
for (i = 0; i < node->ordNumCols; i++) {
appendStringInfo(str, " %d", node->ordColIdx[i]);
}
WRITE_GRPOP_FIELD(ordOperators, ordNumCols);
WRITE_INT_FIELD(frameOptions);
WRITE_NODE_FIELD(startOffset);
WRITE_NODE_FIELD(endOffset);
out_mem_info(str, &node->mem_info);
}
static void _outGroup(StringInfo str, Group* node)
{
int i;
WRITE_NODE_TYPE("GROUP");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :grpColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->grpColIdx[i]);
}
WRITE_GRPOP_FIELD(grpOperators, numCols);
}
static void _outVecGroup(StringInfo str, VecGroup* node)
{
int i;
WRITE_NODE_TYPE("VECGROUP");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :grpColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->grpColIdx[i]);
}
appendStringInfo(str, " :grpOperators");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->grpOperators[i]);
}
}
static void _outMaterial(StringInfo str, Material* node)
{
WRITE_NODE_TYPE("MATERIAL");
_outPlanInfo(str, (Plan*)node);
WRITE_BOOL_FIELD(materialize_all);
out_mem_info(str, &node->mem_info);
}
static void _outSimpleSort(StringInfo str, SimpleSort* node)
{
int i;
WRITE_NODE_TYPE("SIMPLESORT");
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :sortColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->sortColIdx[i]);
}
WRITE_GRPOP_FIELD(sortOperators, numCols);
appendStringInfo(str, " :collations");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->sortCollations[i]);
}
/*
* We should use collcation name instead of colloid when
* node->collOid is user-defined, because DN and CN use different OID
* though the objection name is the same
* Note that if this function change, you must check function _readSimpleSort()
*/
for (i = 0; i < node->numCols; i++) {
if (node->sortCollations[i] >= FirstBootstrapObjectId &&
IsStatisfyUpdateCompatibility(node->sortCollations[i])) {
appendStringInfo(str, " :collname ");
_outToken(str, get_collation_name(node->sortCollations[i]));
}
}
appendStringInfo(str, " :nullsFirst");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
}
WRITE_BOOL_FIELD(sortToStore);
}
static void _outSort(StringInfo str, Sort* node)
{
int i;
WRITE_NODE_TYPE("SORT");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :sortColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->sortColIdx[i]);
}
WRITE_GRPOP_FIELD(sortOperators, numCols);
appendStringInfo(str, " :collations");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->collations[i]);
}
/*
* We should use collcation name instead of colloid when
* node->collOid is user-defined, because DN and CN use different OID
* though the objection name is the same
* Note that if this function change, you must check function _readSort()
*/
for (i = 0; i < node->numCols; i++) {
if (node->collations[i] >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->collations[i])) {
appendStringInfo(str, " :collname ");
_outToken(str, get_collation_name(node->collations[i]));
}
}
appendStringInfo(str, " :nullsFirst");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
}
out_mem_info(str, &node->mem_info);
}
static void _outUnique(StringInfo str, Unique* node)
{
int i;
WRITE_NODE_TYPE("UNIQUE");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :uniqColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->uniqColIdx[i]);
}
WRITE_GRPOP_FIELD(uniqOperators, numCols);
}
static void _outVecUnique(StringInfo str, VecUnique* node)
{
int i;
WRITE_NODE_TYPE("VECUNIQUE");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :uniqColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->uniqColIdx[i]);
}
appendStringInfo(str, " :uniqOperators");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->uniqOperators[i]);
}
}
static void _outHash(StringInfo str, Hash* node)
{
WRITE_NODE_TYPE("HASH");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(skewColumn);
WRITE_BOOL_FIELD(skewInherit);
WRITE_OID_FIELD(skewColType);
WRITE_INT_FIELD(skewColTypmod);
WRITE_TYPEINFO_FIELD(skewColType);
}
static void _outSetOp(StringInfo str, SetOp* node)
{
int i;
WRITE_NODE_TYPE("SETOP");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(cmd, SetOpCmd);
WRITE_ENUM_FIELD(strategy, SetOpStrategy);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :dupColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->dupColIdx[i]);
}
WRITE_GRPOP_FIELD(dupOperators, numCols);
WRITE_INT_FIELD(flagColIdx);
WRITE_INT_FIELD(firstFlag);
WRITE_LONG_FIELD(numGroups);
}
static void _outVecSetOp(StringInfo str, VecSetOp* node)
{
int i;
WRITE_NODE_TYPE("VECSETOP");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(cmd, SetOpCmd);
WRITE_ENUM_FIELD(strategy, SetOpStrategy);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :dupColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->dupColIdx[i]);
}
appendStringInfo(str, " :dupOperators");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->dupOperators[i]);
}
WRITE_INT_FIELD(flagColIdx);
WRITE_INT_FIELD(firstFlag);
WRITE_LONG_FIELD(numGroups);
}
static void _outLockRows(StringInfo str, LockRows* node)
{
WRITE_NODE_TYPE("LOCKROWS");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(rowMarks);
WRITE_INT_FIELD(epqParam);
}
static void _outLimit(StringInfo str, Limit* node)
{
WRITE_NODE_TYPE("LIMIT");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(limitOffset);
WRITE_NODE_FIELD(limitCount);
}
static void _outNestLoopParam(StringInfo str, NestLoopParam* node)
{
WRITE_NODE_TYPE("NESTLOOPPARAM");
WRITE_INT_FIELD(paramno);
WRITE_NODE_FIELD(paramval);
}
static void _outPlanRowMark(StringInfo str, PlanRowMark* node)
{
WRITE_NODE_TYPE("PLANROWMARK");
WRITE_UINT_FIELD(rti);
WRITE_UINT_FIELD(prti);
WRITE_UINT_FIELD(rowmarkId);
WRITE_ENUM_FIELD(markType, RowMarkType);
if (t_thrd.proc->workingVersionNum >= SKIP_LOCKED_VERSION_NUM) {
WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
} else {
WRITE_BOOL_EXPR(noWait, (node->waitPolicy == LockWaitError ? true: false));
}
if (t_thrd.proc->workingVersionNum >= WAIT_N_TUPLE_LOCK_VERSION_NUM) {
WRITE_INT_FIELD(waitSec);
}
WRITE_BOOL_FIELD(isParent);
WRITE_INT_FIELD(numAttrs);
WRITE_BITMAPSET_FIELD(bms_nodeids);
}
static void _outPlanInvalItem(StringInfo str, PlanInvalItem* node)
{
WRITE_NODE_TYPE("PLANINVALITEM");
WRITE_INT_FIELD(cacheId);
WRITE_UINT_FIELD(hashValue);
}
/*****************************************************************************
*
* Stuff from primnodes.h.
*
*****************************************************************************/
static void _outAlias(StringInfo str, Alias* node)
{
WRITE_NODE_TYPE("ALIAS");
WRITE_STRING_FIELD(aliasname);
WRITE_NODE_FIELD(colnames);
}
static void _outRangeVar(StringInfo str, RangeVar* node)
{
WRITE_NODE_TYPE("RANGEVAR");
/*
* we deliberately ignore catalogname here, since it is presently not
* semantically meaningful
*/
WRITE_STRING_FIELD(schemaname);
WRITE_STRING_FIELD(relname);
WRITE_STRING_FIELD(partitionname);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_STRING_FIELD(subpartitionname);
}
WRITE_ENUM_FIELD(inhOpt, InhOption);
WRITE_CHAR_FIELD(relpersistence);
WRITE_NODE_FIELD(alias);
WRITE_LOCATION_FIELD(location);
WRITE_BOOL_FIELD(ispartition);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_BOOL_FIELD(issubpartition);
}
WRITE_NODE_FIELD(partitionKeyValuesList);
if (t_thrd.proc->workingVersionNum >= 92063) {
WRITE_BOOL_FIELD(isbucket);
WRITE_NODE_FIELD(buckets);
}
if (TcapFeatureAvail()) {
WRITE_BOOL_FIELD(withVerExpr);
}
if (t_thrd.proc->workingVersionNum >= MULTI_PARTITIONS_VERSION_NUM) {
WRITE_NODE_FIELD(partitionNameList);
}
}
static void _outIntoClause(StringInfo str, IntoClause* node)
{
WRITE_NODE_TYPE("INTOCLAUSE");
WRITE_NODE_FIELD(rel);
WRITE_NODE_FIELD(colNames);
WRITE_NODE_FIELD(options);
WRITE_ENUM_FIELD(onCommit, OnCommitAction);
WRITE_ENUM_FIELD(row_compress, RelCompressType);
WRITE_STRING_FIELD(tableSpaceName);
WRITE_BOOL_FIELD(skipData);
if (t_thrd.proc->workingVersionNum >= MATVIEW_VERSION_NUM) {
WRITE_BOOL_FIELD(ivm);
}
if (t_thrd.proc->workingVersionNum >= MATVIEW_VERSION_NUM) {
WRITE_CHAR_FIELD(relkind);
}
}
static void _outVar(StringInfo str, Var* node)
{
WRITE_NODE_TYPE("VAR");
WRITE_UINT_FIELD(varno);
WRITE_INT_FIELD(varattno);
WRITE_OID_FIELD(vartype);
WRITE_INT_FIELD(vartypmod);
WRITE_OID_FIELD(varcollid);
WRITE_UINT_FIELD(varlevelsup);
WRITE_UINT_FIELD(varnoold);
WRITE_INT_FIELD(varoattno);
WRITE_LOCATION_FIELD(location);
/*
* For the new created type, we have to bind the typname and
* typnamespace information, so that the data node can decode it.
*/
WRITE_TYPEINFO_FIELD(vartype);
}
static void _outConst(StringInfo str, Const* node)
{
WRITE_NODE_TYPE("CONST");
WRITE_OID_FIELD(consttype);
WRITE_INT_FIELD(consttypmod);
WRITE_OID_FIELD(constcollid);
WRITE_INT_FIELD(constlen);
WRITE_BOOL_FIELD(constbyval);
WRITE_BOOL_FIELD(constisnull);
WRITE_BOOL_FIELD(ismaxvalue);
WRITE_LOCATION_FIELD(location);
/*
* just translate type oid to type name, we must do this just for
* 1. we skip to translate datatype oid to name when const is
* maxvalue before this commit, which may lead to incorrect
* type oid if the type is a user-defined
* 2. we must use type oid to translate data string to Datum,
* we have to decode type name to data type oid first, or it
* may be an inncorrect type oid if it is user-defined
*/
WRITE_TYPEINFO_FIELD(consttype);
appendStringInfo(str, " :constvalue ");
if (node->ismaxvalue) {
/* max value wich is used in sql related to partition */
appendStringInfo(str, "<MAXVALUE>");
} else if (node->constisnull) {
/* null value */
appendStringInfo(str, "<>");
} else if (node->consttype < FirstBootstrapObjectId) {
/*
* For internal bootstrap type
*
* Just print the value of the datum since, since
* data type information is consistent across all instances
*/
_outDatum(str, node->constvalue, node->constlen, node->constbyval);
} else {
Oid typoutput;
bool typIsVarlena = false;
/*
* For user-define type
*
* decode datum to string with Output functions identified by
* datatype since data type oid may be inconsistent on different
* nodes. the string will be translated to datum with inputfunction
* when we read the node string
*/
appendStringInfo(str, " :udftypevalue ");
getTypeOutputInfo(node->consttype, &typoutput, &typIsVarlena);
_outToken(str, OidOutputFunctionCall(typoutput, node->constvalue));
}
WRITE_CFGINFO_FIELD(consttype, constvalue);
WRITE_CURSORDATA_FIELD(cursor_data);
}
static void _outParam(StringInfo str, Param* node)
{
WRITE_NODE_TYPE("PARAM");
WRITE_ENUM_FIELD(paramkind, ParamKind);
WRITE_INT_FIELD(paramid);
WRITE_OID_FIELD(paramtype);
WRITE_INT_FIELD(paramtypmod);
WRITE_OID_FIELD(paramcollid);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(paramtype);
if (t_thrd.proc->workingVersionNum >= COMMENT_ROWTYPE_TABLEOF_VERSION_NUM) {
WRITE_OID_FIELD(tableOfIndexType);
}
if (t_thrd.proc->workingVersionNum >= COMMENT_RECORD_PARAM_VERSION_NUM) {
WRITE_OID_FIELD(recordVarTypOid);
}
if (t_thrd.proc->workingVersionNum >= COMMENT_ROWTYPE_NEST_TABLEOF_VERSION_NUM) {
WRITE_NODE_FIELD(tableOfIndexTypeList);
}
}
static void _outRownum(StringInfo str, const Rownum* node)
{
WRITE_NODE_TYPE("ROWNUM");
WRITE_OID_FIELD(rownumcollid);
WRITE_LOCATION_FIELD(location);
}
static void _outAggref(StringInfo str, Aggref* node)
{
WRITE_NODE_TYPE("AGGREF");
WRITE_OID_FIELD(aggfnoid);
#ifdef ENABLE_MULTIPLE_NODES
if (node->aggfnoid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->aggfnoid) &&
t_thrd.proc->workingVersionNum >= FUNCNAME_PUSHDOWN_VERSION_NUM) {
// shipping out for dn, oid will be different on dn, so proname and pronamespace string will be must.
char* proname = NULL;
char* pronamespace = NULL;
char* rettypenamespace = NULL;
char* rettypename = NULL;
Oid pronamespaceoid = get_func_namespace(node->aggfnoid);
Oid rettype = 0;
int nargs = 0;
Oid* argtypes = NULL;
proname = get_func_name(node->aggfnoid);
pronamespace = get_namespace_name(pronamespaceoid);
rettype = get_func_signature(node->aggfnoid, &argtypes, &nargs);
appendStringInfo(str, " :pronamespace ");
_outToken(str, pronamespace);
appendStringInfo(str, " :proname ");
_outToken(str, proname);
rettypenamespace = get_typenamespace(rettype);
appendStringInfo(str, " :rettypenamespace ");
_outToken(str, rettypenamespace);
rettypename = get_typename(rettype);
appendStringInfo(str, " :rettypename ");
_outToken(str, rettypename);
appendStringInfo(str, " :pronargs %d", nargs);
appendStringInfo(str, " :proargs ");
for (int index = 0; index < nargs; index++) {
char* argtypenamespace = NULL;
char* argtypename = NULL;
argtypenamespace = get_typenamespace(argtypes[index]);
_outToken(str, argtypenamespace);
appendStringInfo(str, " ");
argtypename = get_typename(argtypes[index]);
_outToken(str, argtypename);
}
}
#endif
WRITE_OID_FIELD(aggtype);
#ifdef PGXC
WRITE_OID_FIELD(aggtrantype);
WRITE_BOOL_FIELD(agghas_collectfn);
WRITE_INT_FIELD(aggstage);
#endif /* PGXC */
WRITE_OID_FIELD(aggcollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(aggdirectargs);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(aggorder);
WRITE_NODE_FIELD(aggdistinct);
WRITE_BOOL_FIELD(aggstar);
WRITE_CHAR_FIELD(aggkind);
WRITE_BOOL_FIELD(aggvariadic);
WRITE_UINT_FIELD(agglevelsup);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(aggtype);
WRITE_TYPEINFO_FIELD(aggtrantype);
}
static void _outGroupingFunc(StringInfo str, const GroupingFunc* node)
{
WRITE_NODE_TYPE("GROUPINGFUNC");
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(refs);
WRITE_NODE_FIELD(cols);
WRITE_UINT_FIELD(agglevelsup);
WRITE_LOCATION_FIELD(location);
}
static void _outGroupingId(StringInfo str, const GroupingId* node)
{
WRITE_NODE_TYPE("GROUPINGID");
}
static void _outWindowFunc(StringInfo str, WindowFunc* node)
{
WRITE_NODE_TYPE("WINDOWFUNC");
WRITE_OID_FIELD(winfnoid);
WRITE_OID_FIELD(wintype);
WRITE_OID_FIELD(wincollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
WRITE_UINT_FIELD(winref);
WRITE_BOOL_FIELD(winstar);
WRITE_BOOL_FIELD(winagg);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(wintype);
WRITE_FUNCINFO_FIELD(winfnoid);
}
static void _outArrayRef(StringInfo str, ArrayRef* node)
{
WRITE_NODE_TYPE("ARRAYREF");
WRITE_OID_FIELD(refarraytype);
WRITE_OID_FIELD(refelemtype);
WRITE_INT_FIELD(reftypmod);
WRITE_OID_FIELD(refcollid);
WRITE_NODE_FIELD(refupperindexpr);
WRITE_NODE_FIELD(reflowerindexpr);
WRITE_NODE_FIELD(refexpr);
WRITE_NODE_FIELD(refassgnexpr);
WRITE_TYPEINFO_FIELD(refarraytype);
WRITE_TYPEINFO_FIELD(refelemtype);
}
/*
* Brief : get the object name and namespace by id
* Input : objId - Object ID
* : contex - Object Kind
* Output : objNamespace - object namespace
* : objName - object name
* Return Value : None.
* Notes : None.
*/
static void getNameById(Oid objId, const char* context, char** objNamespace, char** objName)
{
*objName = get_rel_name(objId);
if ((*objName) == NULL) {
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("name for %s %u not found", context, objId)));
}
Oid namespaceOid = get_rel_namespace(objId);
if (!OidIsValid(namespaceOid)) {
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("namespace for %s %u not found", context, objId)));
}
*objNamespace = get_namespace_name(namespaceOid);
if ((*objNamespace) == NULL) {
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("namespace for %s %u not found", context, objId)));
}
}
static void _outFuncExpr(StringInfo str, FuncExpr* node)
{
WRITE_NODE_TYPE("FUNCEXPR");
WRITE_OID_FIELD(funcid);
WRITE_OID_FIELD(funcresulttype);
if (t_thrd.proc->workingVersionNum >= CLIENT_ENCRYPTION_PROC_VERSION_NUM) {
WRITE_INT_FIELD(funcresulttype_orig);
}
WRITE_BOOL_FIELD(funcretset);
WRITE_ENUM_FIELD(funcformat, CoercionForm);
WRITE_OID_FIELD(funccollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
/*
* If we decide to push the nextval call to DN, we can not
* pass the sequence id, because they don't share the same id
* we need to serialize the namespace and sequence name instead of id
*/
if (node->funcid == NEXTVALFUNCOID) {
char* seqName = NULL;
char* seqNameSpace = NULL;
Const* firstArg = (Const*)linitial(node->args);
if (firstArg == NULL) {
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE), errmsg("seqname of nextval() is not found")));
}
if (!IsA(firstArg, Const)) {
ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),
errmsg("argument of nextval() must be plain const value")));
}
Oid seqId = DatumGetObjectId(firstArg->constvalue);
getNameById(seqId, "SEQUENCE", &seqNameSpace, &seqName);
appendStringInfo(str, " :seqName ");
_outToken(str, seqName);
appendStringInfo(str, " :seqNameSpace ");
_outToken(str, seqNameSpace);
}
WRITE_LOCATION_FIELD(location);
if (t_thrd.proc->workingVersionNum >= SYNONYM_VERSION_NUM) {
WRITE_OID_FIELD(refSynOid);
}
WRITE_TYPEINFO_FIELD(funcresulttype);
WRITE_FUNCINFO_FIELD(funcid);
/*
* Same reason as above,
* we need to serialize the namespace and synonym name instead of refSynOid
* when function name is referenced from one synonym,
*/
if (t_thrd.proc->workingVersionNum >= SYNONYM_VERSION_NUM) {
WRITE_SYNINFO_FIELD(refSynOid);
}
}
static void _outNamedArgExpr(StringInfo str, NamedArgExpr* node)
{
WRITE_NODE_TYPE("NAMEDARGEXPR");
WRITE_NODE_FIELD(arg);
WRITE_STRING_FIELD(name);
WRITE_INT_FIELD(argnumber);
WRITE_LOCATION_FIELD(location);
}
template <typename T>
static void _outCommonOpExprPart(StringInfo str, T* node)
{
WRITE_OID_FIELD(opno);
WRITE_OPINFO_FEILD(opno);
WRITE_OID_FIELD(opfuncid);
WRITE_FUNCINFO_FIELD(opfuncid);
WRITE_OID_FIELD(opresulttype);
WRITE_BOOL_FIELD(opretset);
WRITE_OID_FIELD(opcollid);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(opresulttype);
}
static void _outOpExpr(StringInfo str, OpExpr* node)
{
WRITE_NODE_TYPE("OPEXPR");
_outCommonOpExprPart<OpExpr>(str, node);
}
static void _outDistinctExpr(StringInfo str, DistinctExpr* node)
{
WRITE_NODE_TYPE("DISTINCTEXPR");
_outCommonOpExprPart<DistinctExpr>(str, node);
}
static void _outNullIfExpr(StringInfo str, NullIfExpr* node)
{
WRITE_NODE_TYPE("NULLIFEXPR");
_outCommonOpExprPart<NullIfExpr>(str, node);
}
static void _outScalarArrayOpExpr(StringInfo str, ScalarArrayOpExpr* node)
{
WRITE_NODE_TYPE("SCALARARRAYOPEXPR");
WRITE_OID_FIELD(opno);
WRITE_OPINFO_FEILD(opno);
WRITE_OID_FIELD(opfuncid);
WRITE_FUNCINFO_FIELD(opfuncid);
WRITE_BOOL_FIELD(useOr);
WRITE_OID_FIELD(inputcollid);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
}
static void _outBoolExpr(StringInfo str, BoolExpr* node)
{
char* opstr = NULL;
WRITE_NODE_TYPE("BOOLEXPR");
/* do-it-yourself enum representation */
switch (node->boolop) {
case AND_EXPR:
opstr = "and";
break;
case OR_EXPR:
opstr = "or";
break;
case NOT_EXPR:
opstr = "not";
break;
default:
break;
}
appendStringInfo(str, " :boolop ");
_outToken(str, opstr);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
}
static void _outSubLink(StringInfo str, SubLink* node)
{
WRITE_NODE_TYPE("SUBLINK");
WRITE_ENUM_FIELD(subLinkType, SubLinkType);
WRITE_NODE_FIELD(testexpr);
WRITE_NODE_FIELD(operName);
WRITE_NODE_FIELD(subselect);
WRITE_LOCATION_FIELD(location);
}
static void _outSubPlan(StringInfo str, SubPlan* node)
{
WRITE_NODE_TYPE("SUBPLAN");
WRITE_ENUM_FIELD(subLinkType, SubLinkType);
WRITE_NODE_FIELD(testexpr);
WRITE_NODE_FIELD(paramIds);
WRITE_INT_FIELD(plan_id);
WRITE_STRING_FIELD(plan_name);
WRITE_OID_FIELD(firstColType);
WRITE_INT_FIELD(firstColTypmod);
WRITE_OID_FIELD(firstColCollation);
WRITE_BOOL_FIELD(useHashTable);
WRITE_BOOL_FIELD(unknownEqFalse);
WRITE_NODE_FIELD(setParam);
WRITE_NODE_FIELD(parParam);
WRITE_NODE_FIELD(args);
WRITE_FLOAT_FIELD(startup_cost, "%.2f");
WRITE_FLOAT_FIELD(per_call_cost, "%.2f");
WRITE_TYPEINFO_FIELD(firstColType);
}
static void _outAlternativeSubPlan(StringInfo str, AlternativeSubPlan* node)
{
WRITE_NODE_TYPE("ALTERNATIVESUBPLAN");
WRITE_NODE_FIELD(subplans);
}
static void _outFieldSelect(StringInfo str, FieldSelect* node)
{
WRITE_NODE_TYPE("FIELDSELECT");
WRITE_NODE_FIELD(arg);
WRITE_INT_FIELD(fieldnum);
WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod);
WRITE_OID_FIELD(resultcollid);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outFieldStore(StringInfo str, FieldStore* node)
{
WRITE_NODE_TYPE("FIELDSTORE");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(newvals);
WRITE_NODE_FIELD(fieldnums);
WRITE_OID_FIELD(resulttype);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outRelabelType(StringInfo str, RelabelType* node)
{
WRITE_NODE_TYPE("RELABELTYPE");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod);
WRITE_OID_FIELD(resultcollid);
WRITE_ENUM_FIELD(relabelformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outCoerceViaIO(StringInfo str, CoerceViaIO* node)
{
WRITE_NODE_TYPE("COERCEVIAIO");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype);
WRITE_OID_FIELD(resultcollid);
WRITE_ENUM_FIELD(coerceformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outArrayCoerceExpr(StringInfo str, ArrayCoerceExpr* node)
{
WRITE_NODE_TYPE("ARRAYCOERCEEXPR");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(elemfuncid);
WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod);
WRITE_OID_FIELD(resultcollid);
WRITE_BOOL_FIELD(isExplicit);
WRITE_ENUM_FIELD(coerceformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(resulttype);
WRITE_FUNCINFO_FIELD(elemfuncid);
}
static void _outConvertRowtypeExpr(StringInfo str, ConvertRowtypeExpr* node)
{
WRITE_NODE_TYPE("CONVERTROWTYPEEXPR");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype);
WRITE_ENUM_FIELD(convertformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outCollateExpr(StringInfo str, CollateExpr* node)
{
WRITE_NODE_TYPE("COLLATE");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(collOid);
WRITE_LOCATION_FIELD(location);
/*
* We should use collcation name instead of colloid when
* node->collOid is user-defined, because DN and CN use
* different OID, though the objection name is the same
*/
if (node->collOid > FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->collOid)) {
appendStringInfo(str, " :collname ");
_outToken(str, get_collation_name(node->collOid));
}
}
static void _outCaseExpr(StringInfo str, CaseExpr* node)
{
WRITE_NODE_TYPE("CASE");
WRITE_OID_FIELD(casetype);
WRITE_OID_FIELD(casecollid);
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(defresult);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(casetype);
}
static void _outCaseWhen(StringInfo str, CaseWhen* node)
{
WRITE_NODE_TYPE("WHEN");
WRITE_NODE_FIELD(expr);
WRITE_NODE_FIELD(result);
WRITE_LOCATION_FIELD(location);
}
static void _outCaseTestExpr(StringInfo str, CaseTestExpr* node)
{
WRITE_NODE_TYPE("CASETESTEXPR");
WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod);
WRITE_OID_FIELD(collation);
WRITE_TYPEINFO_FIELD(typeId);
}
static void _outArrayExpr(StringInfo str, ArrayExpr* node)
{
WRITE_NODE_TYPE("ARRAY");
WRITE_OID_FIELD(array_typeid);
WRITE_OID_FIELD(array_collid);
WRITE_OID_FIELD(element_typeid);
WRITE_NODE_FIELD(elements);
WRITE_BOOL_FIELD(multidims);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(array_typeid);
WRITE_TYPEINFO_FIELD(element_typeid);
}
static void _outRowExpr(StringInfo str, RowExpr* node)
{
WRITE_NODE_TYPE("ROW");
WRITE_NODE_FIELD(args);
WRITE_OID_FIELD(row_typeid);
WRITE_ENUM_FIELD(row_format, CoercionForm);
WRITE_NODE_FIELD(colnames);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(row_typeid);
}
static void _outRowCompareExpr(StringInfo str, RowCompareExpr* node)
{
WRITE_NODE_TYPE("ROWCOMPARE");
WRITE_ENUM_FIELD(rctype, RowCompareType);
WRITE_NODE_FIELD(opnos);
WRITE_NODE_FIELD(opfamilies);
WRITE_NODE_FIELD(inputcollids);
WRITE_NODE_FIELD(largs);
WRITE_NODE_FIELD(rargs);
}
static void _outCoalesceExpr(StringInfo str, CoalesceExpr* node)
{
WRITE_NODE_TYPE("COALESCE");
WRITE_OID_FIELD(coalescetype);
WRITE_OID_FIELD(coalescecollid);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
WRITE_BOOL_FIELD(isnvl);
WRITE_TYPEINFO_FIELD(coalescetype);
}
static void _outMinMaxExpr(StringInfo str, MinMaxExpr* node)
{
WRITE_NODE_TYPE("MINMAX");
WRITE_OID_FIELD(minmaxtype);
WRITE_OID_FIELD(minmaxcollid);
WRITE_OID_FIELD(inputcollid);
WRITE_ENUM_FIELD(op, MinMaxOp);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(minmaxtype);
}
static void _outXmlExpr(StringInfo str, XmlExpr* node)
{
WRITE_NODE_TYPE("XMLEXPR");
WRITE_ENUM_FIELD(op, XmlExprOp);
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(named_args);
WRITE_NODE_FIELD(arg_names);
WRITE_NODE_FIELD(args);
WRITE_ENUM_FIELD(xmloption, XmlOptionType);
WRITE_OID_FIELD(type);
WRITE_INT_FIELD(typmod);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(type);
}
static void _outNullTest(StringInfo str, NullTest* node)
{
WRITE_NODE_TYPE("NULLTEST");
WRITE_NODE_FIELD(arg);
WRITE_ENUM_FIELD(nulltesttype, NullTestType);
WRITE_BOOL_FIELD(argisrow);
}
static void _outSetVariableExpr(StringInfo str, SetVariableExpr* node)
{
WRITE_NODE_TYPE("SetVariableExpr");
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(value);
WRITE_BOOL_FIELD(is_session);
WRITE_BOOL_FIELD(is_global);
}
static void _outHashFilter(StringInfo str, HashFilter* node)
{
WRITE_NODE_TYPE("HASHFILTER");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(typeOids);
WRITE_NODE_FIELD(nodeList);
WRITE_TYPEINFO_LIST(typeOids);
}
static void _outBooleanTest(StringInfo str, BooleanTest* node)
{
WRITE_NODE_TYPE("BOOLEANTEST");
WRITE_NODE_FIELD(arg);
WRITE_ENUM_FIELD(booltesttype, BoolTestType);
}
static void _outCoerceToDomain(StringInfo str, CoerceToDomain* node)
{
WRITE_NODE_TYPE("COERCETODOMAIN");
WRITE_NODE_FIELD(arg);
WRITE_OID_FIELD(resulttype);
WRITE_INT_FIELD(resulttypmod);
WRITE_OID_FIELD(resultcollid);
WRITE_ENUM_FIELD(coercionformat, CoercionForm);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(resulttype);
}
static void _outCoerceToDomainValue(StringInfo str, CoerceToDomainValue* node)
{
WRITE_NODE_TYPE("COERCETODOMAINVALUE");
WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod);
WRITE_OID_FIELD(collation);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(typeId);
}
static void _outSetToDefault(StringInfo str, SetToDefault* node)
{
WRITE_NODE_TYPE("SETTODEFAULT");
WRITE_OID_FIELD(typeId);
WRITE_INT_FIELD(typeMod);
WRITE_OID_FIELD(collation);
WRITE_LOCATION_FIELD(location);
WRITE_TYPEINFO_FIELD(typeId);
}
static void _outCurrentOfExpr(StringInfo str, CurrentOfExpr* node)
{
WRITE_NODE_TYPE("CURRENTOFEXPR");
WRITE_UINT_FIELD(cvarno);
WRITE_STRING_FIELD(cursor_name);
WRITE_INT_FIELD(cursor_param);
}
static void _outTargetEntry(StringInfo str, TargetEntry* node)
{
WRITE_NODE_TYPE("TARGETENTRY");
WRITE_NODE_FIELD(expr);
WRITE_INT_FIELD(resno);
WRITE_STRING_FIELD(resname);
WRITE_UINT_FIELD(ressortgroupref);
WRITE_OID_FIELD(resorigtbl);
WRITE_INT_FIELD(resorigcol);
WRITE_BOOL_FIELD(resjunk);
if (t_thrd.proc->workingVersionNum >= MULTI_MODIFY_VERSION_NUM) {
WRITE_UINT_FIELD(rtindex);
}
}
static void _outPseudoTargetEntry(StringInfo str, PseudoTargetEntry* node)
{
WRITE_NODE_TYPE("PSEUDOTARGETENTRY");
WRITE_NODE_FIELD(tle);
WRITE_NODE_FIELD(srctle);
}
static void _outRangeTblRef(StringInfo str, RangeTblRef* node)
{
WRITE_NODE_TYPE("RANGETBLREF");
WRITE_INT_FIELD(rtindex);
}
static void _outJoinExpr(StringInfo str, JoinExpr* node)
{
WRITE_NODE_TYPE("JOINEXPR");
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_BOOL_FIELD(isNatural);
WRITE_NODE_FIELD(larg);
WRITE_NODE_FIELD(rarg);
WRITE_NODE_FIELD(usingClause);
WRITE_NODE_FIELD(quals);
WRITE_NODE_FIELD(alias);
WRITE_INT_FIELD(rtindex);
}
static void _outFromExpr(StringInfo str, FromExpr* node)
{
WRITE_NODE_TYPE("FROMEXPR");
WRITE_NODE_FIELD(fromlist);
WRITE_NODE_FIELD(quals);
}
static void _outMergeAction(StringInfo str, const MergeAction* node)
{
WRITE_NODE_TYPE("MERGEACTION");
WRITE_BOOL_FIELD(matched);
WRITE_NODE_FIELD(qual);
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(pulluped_targetList);
}
/*****************************************************************************
*
* Stuff from relation.h.
*
*****************************************************************************/
/*
* print the basic stuff of all nodes that inherit from Path
*
* Note we do NOT print the parent, else we'd be in infinite recursion.
* We can print the parent's relids for identification purposes, though.
* We also do not print the whole of param_info, since it's printed by
* _outRelOptInfo; it's sufficient and less cluttering to print just the
* required outer relids.
*/
static void _outPathInfo(StringInfo str, Path* node)
{
WRITE_ENUM_FIELD(pathtype, NodeTag);
appendStringInfo(str, " :parent_relids ");
_outBitmapset(str, node->parent->relids);
appendStringInfo(str, " :required_outer ");
if (node->param_info) {
_outBitmapset(str, node->param_info->ppi_req_outer);
} else {
_outBitmapset(str, NULL);
}
WRITE_FLOAT_FIELD(rows, "%.0f");
WRITE_FLOAT_FIELD(multiple, "%.0f");
WRITE_FLOAT_FIELD(startup_cost, "%.2f");
WRITE_FLOAT_FIELD(total_cost, "%.2f");
WRITE_NODE_FIELD(pathkeys);
WRITE_NODE_FIELD(distribute_keys);
if (node->locator_type != '\0') {
WRITE_CHAR_FIELD(locator_type);
}
WRITE_INT_FIELD(dop);
_outDistribution(str, &(node->distribution));
WRITE_INT_FIELD(hint_value);
}
/*
* print the basic stuff of all nodes that inherit from JoinPath
*/
static void _outJoinPathInfo(StringInfo str, JoinPath* node)
{
_outPathInfo(str, (Path*)node);
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_NODE_FIELD(outerjoinpath);
WRITE_NODE_FIELD(innerjoinpath);
WRITE_NODE_FIELD(joinrestrictinfo);
}
static void _outPath(StringInfo str, Path* node)
{
WRITE_NODE_TYPE("PATH");
_outPathInfo(str, (Path*)node);
}
static void _outIndexPath(StringInfo str, IndexPath* node)
{
WRITE_NODE_TYPE("INDEXPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(indexinfo);
WRITE_NODE_FIELD(indexclauses);
WRITE_NODE_FIELD(indexquals);
WRITE_NODE_FIELD(indexqualcols);
WRITE_NODE_FIELD(indexorderbys);
WRITE_NODE_FIELD(indexorderbycols);
WRITE_ENUM_FIELD(indexscandir, ScanDirection);
WRITE_FLOAT_FIELD(indextotalcost, "%.2f");
WRITE_FLOAT_FIELD(indexselectivity, "%.4f");
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
}
static void _outBitmapHeapPath(StringInfo str, BitmapHeapPath* node)
{
WRITE_NODE_TYPE("BITMAPHEAPPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(bitmapqual);
}
static void _outBitmapAndPath(StringInfo str, BitmapAndPath* node)
{
WRITE_NODE_TYPE("BITMAPANDPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(bitmapquals);
WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
}
static void _outBitmapOrPath(StringInfo str, BitmapOrPath* node)
{
WRITE_NODE_TYPE("BITMAPORPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(bitmapquals);
WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
}
static void _outTidPath(StringInfo str, TidPath* node)
{
WRITE_NODE_TYPE("TIDPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(tidquals);
}
static void _outPartIteratorPath(StringInfo str, PartIteratorPath* node)
{
WRITE_NODE_TYPE("PARTITERATORPATH");
_outPathInfo(str, (Path*)node);
WRITE_INT_FIELD(itrs);
WRITE_BOOL_FIELD(direction);
WRITE_ENUM_FIELD(partType, PartitionType);
WRITE_NODE_FIELD(subPath);
WRITE_BOOL_FIELD(ispwj);
WRITE_NODE_FIELD(upperboundary);
WRITE_NODE_FIELD(lowerboundary);
WRITE_BOOL_FIELD(needSortNode);
}
static void _outForeignPath(StringInfo str, ForeignPath* node)
{
WRITE_NODE_TYPE("FOREIGNPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(fdw_private);
}
static void _outAppendPath(StringInfo str, AppendPath* node)
{
WRITE_NODE_TYPE("APPENDPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(subpaths);
}
static void _outMergeAppendPath(StringInfo str, MergeAppendPath* node)
{
WRITE_NODE_TYPE("MERGEAPPENDPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(subpaths);
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
}
/*
* _outResultPath
* output a ResultPath node's information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the ResultPath node
*
* @return: void
*/
static void _outResultPath(StringInfo str, ResultPath* node)
{
WRITE_NODE_TYPE("RESULTPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(quals);
WRITE_NODE_FIELD(subpath);
}
/*
* _outMaterialPath
* output a MaterialPath node's information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the MaterialPath node
*
* @return: void
*/
static void _outMaterialPath(StringInfo str, MaterialPath* node)
{
WRITE_NODE_TYPE("MATERIALPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(subpath);
WRITE_BOOL_FIELD(materialize_all);
}
static void _outUniquePath(StringInfo str, UniquePath* node)
{
WRITE_NODE_TYPE("UNIQUEPATH");
_outPathInfo(str, (Path*)node);
WRITE_NODE_FIELD(subpath);
WRITE_ENUM_FIELD(umethod, UniquePathMethod);
WRITE_NODE_FIELD(in_operators);
WRITE_NODE_FIELD(uniq_exprs);
WRITE_BOOL_FIELD(both_method);
WRITE_BOOL_FIELD(hold_tlist);
}
static void _outNestPath(StringInfo str, NestPath* node)
{
WRITE_NODE_TYPE("NESTPATH");
_outJoinPathInfo(str, (JoinPath*)node);
}
static void _outMergePath(StringInfo str, MergePath* node)
{
WRITE_NODE_TYPE("MERGEPATH");
_outJoinPathInfo(str, (JoinPath*)node);
WRITE_NODE_FIELD(path_mergeclauses);
WRITE_NODE_FIELD(outersortkeys);
WRITE_NODE_FIELD(innersortkeys);
WRITE_BOOL_FIELD(materialize_inner);
}
static void _outHashPath(StringInfo str, HashPath* node)
{
WRITE_NODE_TYPE("HASHPATH");
_outJoinPathInfo(str, (JoinPath*)node);
WRITE_NODE_FIELD(path_hashclauses);
WRITE_INT_FIELD(num_batches);
}
static void _outPlannerGlobal(StringInfo str, PlannerGlobal* node)
{
WRITE_NODE_TYPE("PLANNERGLOBAL");
/* NB: this isn't a complete set of fields */
WRITE_NODE_FIELD(paramlist);
WRITE_NODE_FIELD(subplans);
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(finalrtable);
WRITE_NODE_FIELD(finalrowmarks);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_INT_FIELD(nParamExec);
WRITE_UINT_FIELD(lastPHId);
WRITE_UINT_FIELD(lastRowMarkId);
WRITE_BOOL_FIELD(transientPlan);
WRITE_BOOL_FIELD(dependsOnRole);
}
/*
* _outPlannerInfo
* output a PlannerInfo node's information
*
* @param (in) str:
* the string to store information
* @param (in) node:
* the PlannerInfo node
*
* @return: void
*/
static void _outPlannerInfo(StringInfo str, PlannerInfo* node)
{
WRITE_NODE_TYPE("PLANNERINFO");
/* NB: this isn't a complete set of fields */
WRITE_NODE_FIELD(parse);
WRITE_NODE_FIELD(glob);
WRITE_UINT_FIELD(query_level);
WRITE_NODE_FIELD(plan_params);
WRITE_ARRAY_FIELD(simple_rel_array, node->simple_rel_array_size);
WRITE_ARRAY_FIELD(simple_rte_array, node->simple_rel_array_size);
WRITE_BITMAPSET_FIELD(all_baserels);
WRITE_NODE_FIELD(join_rel_list);
if (node->join_cur_level >= 1 && node->join_rel_level != NULL) {
WRITE_ARRAY_FIELD(join_rel_level, (node->join_cur_level + 1));
}
WRITE_INT_FIELD(join_cur_level);
WRITE_NODE_FIELD(init_plans);
WRITE_NODE_FIELD(cte_plan_ids);
WRITE_NODE_FIELD(eq_classes);
WRITE_NODE_FIELD(canon_pathkeys);
WRITE_NODE_FIELD(left_join_clauses);
WRITE_NODE_FIELD(right_join_clauses);
WRITE_NODE_FIELD(full_join_clauses);
WRITE_NODE_FIELD(join_info_list);
WRITE_NODE_FIELD(lateral_info_list);
WRITE_NODE_FIELD(append_rel_list);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(placeholder_list);
WRITE_NODE_FIELD(query_pathkeys);
WRITE_NODE_FIELD(group_pathkeys);
WRITE_NODE_FIELD(window_pathkeys);
WRITE_NODE_FIELD(distinct_pathkeys);
WRITE_NODE_FIELD(sort_pathkeys);
WRITE_NODE_FIELD(minmax_aggs);
WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
WRITE_BOOL_FIELD(hasInheritedTarget);
WRITE_BOOL_FIELD(hasJoinRTEs);
WRITE_BOOL_FIELD(hasLateralRTEs);
WRITE_BOOL_FIELD(hasHavingQual);
WRITE_BOOL_FIELD(hasPseudoConstantQuals);
WRITE_BOOL_FIELD(hasRecursion);
#ifdef PGXC
WRITE_INT_FIELD(rs_alias_index);
WRITE_NODE_FIELD(xc_rowMarks);
#endif
WRITE_INT_FIELD(wt_param_id);
WRITE_BITMAPSET_FIELD(curOuterRels);
WRITE_NODE_FIELD(curOuterParams);
WRITE_UINT_FIELD(curIteratorParamIndex);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_UINT_FIELD(curSubPartIteratorParamIndex);
}
WRITE_BOOL_FIELD(isPartIteratorPlanning);
WRITE_INT_FIELD(curItrs);
WRITE_NODE_FIELD(subqueryRestrictInfo);
}
static void _outRelOptInfo(StringInfo str, RelOptInfo* node)
{
WRITE_NODE_TYPE("RELOPTINFO");
/* NB: this isn't a complete set of fields */
WRITE_ENUM_FIELD(reloptkind, RelOptKind);
WRITE_BITMAPSET_FIELD(relids);
WRITE_BOOL_FIELD(isPartitionedTable);
WRITE_ENUM_FIELD(partflag, PartitionFlag);
WRITE_FLOAT_FIELD(rows, "%.0f");
WRITE_INT_FIELD(width);
WRITE_NODE_FIELD(reltargetlist);
WRITE_NODE_FIELD(pathlist);
WRITE_NODE_FIELD(ppilist);
WRITE_NODE_FIELD(cheapest_startup_path);
WRITE_NODE_FIELD(cheapest_total_path);
WRITE_NODE_FIELD(cheapest_unique_path);
WRITE_NODE_FIELD(cheapest_parameterized_paths);
WRITE_UINT_FIELD(relid);
WRITE_UINT_FIELD(reltablespace);
WRITE_ENUM_FIELD(rtekind, RTEKind);
WRITE_INT_FIELD(min_attr);
WRITE_INT_FIELD(max_attr);
WRITE_NODE_FIELD(lateral_vars);
WRITE_BITMAPSET_FIELD(lateral_relids);
WRITE_NODE_FIELD(indexlist);
#ifndef ENABLE_MULTIPLE_NODES
WRITE_NODE_FIELD(statlist);
#endif
WRITE_FLOAT_FIELD(pages, "%.0f");
WRITE_FLOAT_FIELD(tuples, "%.0f");
WRITE_FLOAT_FIELD(multiple, "%.0f");
WRITE_FLOAT_FIELD(allvisfrac, "%.6f");
WRITE_NODE_FIELD(pruning_result);
WRITE_INT_FIELD(partItrs);
WRITE_NODE_FIELD(subplan);
WRITE_NODE_FIELD(subroot);
/* we don't try to print fdwroutine or fdw_private */
WRITE_NODE_FIELD(baserestrictinfo);
WRITE_UINT_FIELD(baserestrict_min_security);
WRITE_NODE_FIELD(joininfo);
WRITE_BOOL_FIELD(has_eclass_joins);
WRITE_UINT_FIELD(num_data_nodes);
}
static void _outIndexOptInfo(StringInfo str, IndexOptInfo* node)
{
WRITE_NODE_TYPE("INDEXOPTINFO");
/* NB: this isn't a complete set of fields */
WRITE_OID_FIELD(indexoid);
/* Do NOT print rel field, else infinite recursion */
WRITE_BOOL_FIELD(ispartitionedindex);
WRITE_OID_FIELD(partitionindex);
WRITE_FLOAT_FIELD(pages, "%.0f");
WRITE_FLOAT_FIELD(tuples, "%.0f");
WRITE_INT_FIELD(ncolumns);
WRITE_OID_FIELD(relam);
WRITE_NODE_FIELD(indexprs);
WRITE_NODE_FIELD(indpred);
WRITE_NODE_FIELD(indextlist);
WRITE_BOOL_FIELD(predOK);
WRITE_BOOL_FIELD(unique);
WRITE_BOOL_FIELD(immediate);
WRITE_BOOL_FIELD(hypothetical);
}
static void _outEquivalenceClass(StringInfo str, EquivalenceClass* node)
{
/*
* To simplify reading, we just chase up to the topmost merged EC and
* print that, without bothering to show the merge-ees separately.
*/
while (node->ec_merged) {
node = node->ec_merged;
}
WRITE_NODE_TYPE("EQUIVALENCECLASS");
WRITE_NODE_FIELD(ec_opfamilies);
WRITE_OID_FIELD(ec_collation);
WRITE_NODE_FIELD(ec_members);
WRITE_NODE_FIELD(ec_sources);
WRITE_NODE_FIELD(ec_derives);
WRITE_BITMAPSET_FIELD(ec_relids);
WRITE_BOOL_FIELD(ec_has_const);
WRITE_BOOL_FIELD(ec_has_volatile);
WRITE_BOOL_FIELD(ec_below_outer_join);
WRITE_BOOL_FIELD(ec_group_set);
WRITE_BOOL_FIELD(ec_broken);
WRITE_UINT_FIELD(ec_sortref);
WRITE_UINT_FIELD(ec_min_security);
WRITE_UINT_FIELD(ec_max_security);
}
static void _outEquivalenceMember(StringInfo str, EquivalenceMember* node)
{
WRITE_NODE_TYPE("EQUIVALENCEMEMBER");
WRITE_NODE_FIELD(em_expr);
WRITE_BITMAPSET_FIELD(em_relids);
WRITE_BITMAPSET_FIELD(em_nullable_relids);
WRITE_BOOL_FIELD(em_is_const);
WRITE_BOOL_FIELD(em_is_child);
WRITE_OID_FIELD(em_datatype);
WRITE_TYPEINFO_FIELD(em_datatype);
}
static void _outPathKey(StringInfo str, PathKey* node)
{
WRITE_NODE_TYPE("PATHKEY");
WRITE_NODE_FIELD(pk_eclass);
WRITE_OID_FIELD(pk_opfamily);
WRITE_INT_FIELD(pk_strategy);
WRITE_BOOL_FIELD(pk_nulls_first);
}
static void _outParamPathInfo(StringInfo str, const ParamPathInfo* node)
{
WRITE_NODE_TYPE("PARAMPATHINFO");
WRITE_BITMAPSET_FIELD(ppi_req_outer);
WRITE_FLOAT_FIELD(ppi_rows, "%.0f");
WRITE_NODE_FIELD(ppi_clauses);
WRITE_BITMAPSET_FIELD(ppi_req_upper);
}
static void _outRestrictInfo(StringInfo str, const RestrictInfo* node)
{
WRITE_NODE_TYPE("RESTRICTINFO");
/* NB: this isn't a complete set of fields */
WRITE_NODE_FIELD(clause);
WRITE_BOOL_FIELD(is_pushed_down);
WRITE_BOOL_FIELD(outerjoin_delayed);
WRITE_BOOL_FIELD(can_join);
WRITE_BOOL_FIELD(pseudoconstant);
WRITE_BOOL_FIELD(leakproof);
WRITE_UINT_FIELD(security_level);
WRITE_BITMAPSET_FIELD(clause_relids);
WRITE_BITMAPSET_FIELD(required_relids);
WRITE_BITMAPSET_FIELD(outer_relids);
WRITE_BITMAPSET_FIELD(nullable_relids);
WRITE_BITMAPSET_FIELD(left_relids);
WRITE_BITMAPSET_FIELD(right_relids);
WRITE_NODE_FIELD(orclause);
/* don't write parent_ec, leads to infinite recursion in plan tree dump */
WRITE_FLOAT_FIELD(norm_selec, "%.4f");
WRITE_FLOAT_FIELD(outer_selec, "%.4f");
WRITE_NODE_FIELD(mergeopfamilies);
/* don't write left_ec, leads to infinite recursion in plan tree dump */
/* don't write right_ec, leads to infinite recursion in plan tree dump */
WRITE_NODE_FIELD(left_em);
WRITE_NODE_FIELD(right_em);
WRITE_BOOL_FIELD(outer_is_left);
WRITE_OID_FIELD(hashjoinoperator);
}
static void _outPlaceHolderVar(StringInfo str, PlaceHolderVar* node)
{
WRITE_NODE_TYPE("PLACEHOLDERVAR");
WRITE_NODE_FIELD(phexpr);
WRITE_BITMAPSET_FIELD(phrels);
WRITE_UINT_FIELD(phid);
WRITE_UINT_FIELD(phlevelsup);
}
static void _outSpecialJoinInfo(StringInfo str, SpecialJoinInfo* node)
{
WRITE_NODE_TYPE("SPECIALJOININFO");
WRITE_BITMAPSET_FIELD(min_lefthand);
WRITE_BITMAPSET_FIELD(min_righthand);
WRITE_BITMAPSET_FIELD(syn_lefthand);
WRITE_BITMAPSET_FIELD(syn_righthand);
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_BOOL_FIELD(lhs_strict);
WRITE_BOOL_FIELD(delay_upper_joins);
WRITE_NODE_FIELD(join_quals);
}
static void
_outLateralJoinInfo(StringInfo str, const LateralJoinInfo *node)
{
WRITE_NODE_TYPE("LATERALJOININFO");
WRITE_UINT_FIELD(lateral_rhs);
WRITE_BITMAPSET_FIELD(lateral_lhs);
}
static void _outAppendRelInfo(StringInfo str, AppendRelInfo* node)
{
WRITE_NODE_TYPE("APPENDRELINFO");
WRITE_UINT_FIELD(parent_relid);
WRITE_UINT_FIELD(child_relid);
WRITE_OID_FIELD(parent_reltype);
WRITE_OID_FIELD(child_reltype);
WRITE_NODE_FIELD(translated_vars);
WRITE_OID_FIELD(parent_reloid);
WRITE_TYPEINFO_FIELD(parent_reltype);
WRITE_TYPEINFO_FIELD(child_reltype);
}
static void _outPlaceHolderInfo(StringInfo str, PlaceHolderInfo* node)
{
WRITE_NODE_TYPE("PLACEHOLDERINFO");
WRITE_UINT_FIELD(phid);
WRITE_NODE_FIELD(ph_var);
WRITE_BITMAPSET_FIELD(ph_eval_at);
WRITE_BITMAPSET_FIELD(ph_needed);
WRITE_INT_FIELD(ph_width);
}
static void _outMinMaxAggInfo(StringInfo str, MinMaxAggInfo* node)
{
WRITE_NODE_TYPE("MINMAXAGGINFO");
WRITE_OID_FIELD(aggfnoid);
WRITE_OID_FIELD(aggsortop);
WRITE_NODE_FIELD(target);
/* We intentionally omit subroot --- too large, not interesting enough */
WRITE_NODE_FIELD(path);
WRITE_FLOAT_FIELD(pathcost, "%.2f");
WRITE_NODE_FIELD(param);
}
static void _outPlannerParamItem(StringInfo str, PlannerParamItem* node)
{
WRITE_NODE_TYPE("PLANNERPARAMITEM");
WRITE_NODE_FIELD(item);
WRITE_INT_FIELD(paramId);
}
/*****************************************************************************
*
* Stuff from parsenodes.h.
*
*****************************************************************************/
/*
* print the basic stuff of all nodes that inherit from CreateStmt
*/
static void _outCreateStmtInfo(StringInfo str, const CreateStmt* node)
{
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(tableElts);
WRITE_NODE_FIELD(inhRelations);
WRITE_NODE_FIELD(ofTypename);
WRITE_NODE_FIELD(constraints);
WRITE_NODE_FIELD(options);
WRITE_NODE_FIELD(clusterKeys);
WRITE_ENUM_FIELD(oncommit, OnCommitAction);
WRITE_STRING_FIELD(tablespacename);
WRITE_BOOL_FIELD(if_not_exists);
if (t_thrd.proc->workingVersionNum >= MATVIEW_VERSION_NUM) {
WRITE_BOOL_FIELD(ivm);
}
WRITE_NODE_FIELD(partTableState);
if (t_thrd.proc->workingVersionNum >= COMMENT_SUPPORT_VERSION_NUM) {
WRITE_NODE_FIELD(tableOptions);
}
WRITE_NODE_FIELD(uuids);
if (t_thrd.proc->workingVersionNum >= MATVIEW_VERSION_NUM) {
WRITE_CHAR_FIELD(relkind);
}
WRITE_NODE_FIELD(autoIncStart);
}
static void _outRangePartitionDefState(StringInfo str, RangePartitionDefState* node)
{
WRITE_NODE_TYPE("RANGEPARTITIONDEFSTATE");
WRITE_STRING_FIELD(partitionName);
WRITE_NODE_FIELD(boundary);
WRITE_STRING_FIELD(tablespacename);
}
static void _outListPartitionDefState(StringInfo str, ListPartitionDefState* node)
{
WRITE_NODE_TYPE("LISTPARTITIONDEFSTATE");
WRITE_STRING_FIELD(partitionName);
WRITE_NODE_FIELD(boundary);
WRITE_STRING_FIELD(tablespacename);
}
static void _outHashPartitionDefState(StringInfo str, HashPartitionDefState* node)
{
WRITE_NODE_TYPE("HASHPARTITIONDEFSTATE");
WRITE_STRING_FIELD(partitionName);
WRITE_NODE_FIELD(boundary);
WRITE_STRING_FIELD(tablespacename);
}
static void _outIntervalPartitionDefState(StringInfo str, IntervalPartitionDefState* node)
{
WRITE_NODE_TYPE("INTERVALPARTITIONDEFSTATE");
WRITE_NODE_FIELD(partInterval);
WRITE_NODE_FIELD(intervalTablespaces);
}
static void _outPartitionState(StringInfo str, PartitionState* node)
{
WRITE_NODE_TYPE("PARTITIONSTATE");
if (node->partitionStrategy == 0) {
appendStringInfo(str, " :partitionStrategy 0");
} else {
WRITE_CHAR_FIELD(partitionStrategy);
}
WRITE_NODE_FIELD(intervalPartDef);
WRITE_NODE_FIELD(partitionKey);
WRITE_NODE_FIELD(partitionList);
WRITE_ENUM_FIELD(rowMovement, RowMovementValue);
WRITE_NODE_FIELD(subPartitionState);
WRITE_NODE_FIELD(partitionNameList);
}
static void _outRangePartitionindexDefState(StringInfo str, RangePartitionindexDefState* node)
{
WRITE_NODE_TYPE("RANGEPARTITIONINDEXDEFSTATE");
WRITE_STRING_FIELD(name);
WRITE_STRING_FIELD(tablespace);
WRITE_NODE_FIELD(sublist);
}
static void _outRangePartitionStartEndDefState(StringInfo str, RangePartitionStartEndDefState* node)
{
WRITE_NODE_TYPE("RANGEPARTITIONSTARTENDDEFSTATE");
WRITE_STRING_FIELD(partitionName);
WRITE_NODE_FIELD(startValue);
WRITE_NODE_FIELD(endValue);
WRITE_NODE_FIELD(everyValue);
WRITE_STRING_FIELD(tableSpaceName);
}
static void _outAddPartitionState(StringInfo str, AddPartitionState* node)
{
WRITE_NODE_TYPE("ADDPARTITIONSTATE");
WRITE_NODE_FIELD(partitionList);
WRITE_BOOL_FIELD(isStartEnd);
}
static void _outAddSubPartitionState(StringInfo str, const AddSubPartitionState* node)
{
WRITE_NODE_TYPE("ADDSUBPARTITIONSTATE");
WRITE_STRING_FIELD(partitionName);
WRITE_NODE_FIELD(subPartitionList);
}
static void _outCreateStmt(StringInfo str, const CreateStmt* node)
{
WRITE_NODE_TYPE("CREATESTMT");
_outCreateStmtInfo(str, (const CreateStmt*)node);
}
static void _outCreateForeignTableStmt(StringInfo str, const CreateForeignTableStmt* node)
{
WRITE_NODE_TYPE("CREATEFOREIGNTABLESTMT");
_outCreateStmtInfo(str, (const CreateStmt*)node);
WRITE_STRING_FIELD(servername);
WRITE_NODE_FIELD(options);
WRITE_BOOL_FIELD(write_only);
WRITE_NODE_FIELD(part_state);
}
static void _outIndexStmt(StringInfo str, IndexStmt* node)
{
WRITE_NODE_TYPE("INDEXSTMT");
WRITE_STRING_FIELD(schemaname);
WRITE_STRING_FIELD(idxname);
WRITE_NODE_FIELD(relation);
WRITE_STRING_FIELD(accessMethod);
WRITE_STRING_FIELD(tableSpace);
WRITE_NODE_FIELD(indexParams);
if (t_thrd.proc->workingVersionNum >= SUPPORT_GPI_VERSION_NUM) {
WRITE_NODE_FIELD(indexIncludingParams);
WRITE_BOOL_FIELD(isGlobal);
}
WRITE_NODE_FIELD(options);
WRITE_NODE_FIELD(whereClause);
WRITE_NODE_FIELD(excludeOpNames);
WRITE_STRING_FIELD(idxcomment);
WRITE_OID_FIELD(indexOid);
WRITE_OID_FIELD(oldNode);
WRITE_NODE_FIELD(partClause);
if (t_thrd.proc->workingVersionNum >= COMMENT_SUPPORT_VERSION_NUM) {
WRITE_NODE_FIELD(indexOptions);
}
WRITE_BOOL_FIELD(isPartitioned);
WRITE_BOOL_FIELD(unique);
WRITE_BOOL_FIELD(primary);
WRITE_BOOL_FIELD(isconstraint);
WRITE_BOOL_FIELD(deferrable);
WRITE_BOOL_FIELD(initdeferred);
WRITE_BOOL_FIELD(concurrent);
WRITE_NODE_FIELD(inforConstraint);
}
static void _outNotifyStmt(StringInfo str, NotifyStmt* node)
{
WRITE_NODE_TYPE("NOTIFY");
WRITE_STRING_FIELD(conditionname);
WRITE_STRING_FIELD(payload);
}
static void _outAlterTableStmt(StringInfo str, AlterTableStmt* node)
{
WRITE_NODE_TYPE("ALTERTABLE");
WRITE_NODE_FIELD(relation);
}
static void _outCopyStmt(StringInfo str, CopyStmt* node)
{
WRITE_NODE_TYPE("COPY");
WRITE_NODE_FIELD(relation);
}
static void _outDeclareCursorStmt(StringInfo str, DeclareCursorStmt* node)
{
WRITE_NODE_TYPE("DECLARECURSOR");
WRITE_STRING_FIELD(portalname);
WRITE_INT_FIELD(options);
WRITE_NODE_FIELD(query);
}
static void _outMergeStmt(StringInfo str, MergeStmt* node)
{
WRITE_NODE_TYPE("MERGEINTO");
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(source_relation);
WRITE_NODE_FIELD(join_condition);
WRITE_NODE_FIELD(mergeWhenClauses);
WRITE_BOOL_FIELD(is_insert_update);
WRITE_NODE_FIELD(insert_stmt);
WRITE_NODE_FIELD(hintState);
}
static void _outInsertStmt(StringInfo str, InsertStmt* node)
{
WRITE_NODE_TYPE("INSERT");
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(cols);
WRITE_NODE_FIELD(selectStmt);
WRITE_NODE_FIELD(returningList);
WRITE_NODE_FIELD(withClause);
if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {
WRITE_NODE_FIELD(targetList);
}
#ifdef ENABLE_MULTIPLE_NODES
if (t_thrd.proc->workingVersionNum >= UPSERT_ROW_STORE_VERSION_NUM) {
WRITE_NODE_FIELD(upsertClause);
}
#else
WRITE_NODE_FIELD(upsertClause);
#endif
WRITE_NODE_FIELD(hintState);
if (t_thrd.proc->workingVersionNum >= KEYWORD_IGNORE_COMPART_VERSION_NUM) {
WRITE_BOOL_FIELD(hasIgnore);
}
}
static void _outUpdateStmt(StringInfo str, UpdateStmt* node)
{
WRITE_NODE_TYPE("UPDATE");
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(whereClause);
WRITE_NODE_FIELD(fromClause);
WRITE_NODE_FIELD(returningList);
WRITE_NODE_FIELD(withClause);
WRITE_NODE_FIELD(hintState);
if (t_thrd.proc->workingVersionNum >= KEYWORD_IGNORE_COMPART_VERSION_NUM) {
WRITE_BOOL_FIELD(hasIgnore);
}
WRITE_NODE_FIELD(sortClause);
WRITE_NODE_FIELD(limitClause);
WRITE_NODE_FIELD(relationClause);
}
static void _outSelectStmt(StringInfo str, SelectStmt* node)
{
WRITE_NODE_TYPE("SELECT");
WRITE_NODE_FIELD(distinctClause);
WRITE_NODE_FIELD(intoClause);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(fromClause);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_NODE_FIELD(startWithClause);
}
WRITE_NODE_FIELD(whereClause);
WRITE_NODE_FIELD(groupClause);
WRITE_NODE_FIELD(havingClause);
WRITE_NODE_FIELD(windowClause);
WRITE_NODE_FIELD(withClause);
WRITE_NODE_FIELD(valuesLists);
WRITE_NODE_FIELD(sortClause);
WRITE_NODE_FIELD(limitOffset);
WRITE_NODE_FIELD(limitCount);
WRITE_NODE_FIELD(lockingClause);
WRITE_ENUM_FIELD(op, SetOperation);
WRITE_BOOL_FIELD(all);
WRITE_NODE_FIELD(larg);
WRITE_NODE_FIELD(rarg);
WRITE_BOOL_FIELD(hasPlus);
WRITE_NODE_FIELD(hintState);
}
static void _outFuncCall(StringInfo str, FuncCall* node)
{
WRITE_NODE_TYPE("FUNCCALL");
WRITE_NODE_FIELD(funcname);
WRITE_STRING_FIELD(colname);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(agg_order);
WRITE_BOOL_FIELD(agg_within_group);
WRITE_BOOL_FIELD(agg_star);
WRITE_BOOL_FIELD(agg_distinct);
WRITE_BOOL_FIELD(func_variadic);
WRITE_NODE_FIELD(over);
WRITE_LOCATION_FIELD(location);
WRITE_BOOL_FIELD(call_func);
}
static void _outTableLikeClause(StringInfo str, const TableLikeClause* node)
{
WRITE_NODE_TYPE("TABLELIKECLAUSE");
WRITE_NODE_FIELD(relation);
WRITE_UINT_FIELD(options);
}
static void _outLockingClause(StringInfo str, LockingClause* node)
{
WRITE_NODE_TYPE("LOCKINGCLAUSE");
WRITE_NODE_FIELD(lockedRels);
WRITE_BOOL_FIELD(forUpdate);
if (t_thrd.proc->workingVersionNum >= SKIP_LOCKED_VERSION_NUM) {
WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
} else {
WRITE_BOOL_EXPR(noWait, (node->waitPolicy == LockWaitError ? true: false));
}
if (t_thrd.proc->workingVersionNum >= ENHANCED_TUPLE_LOCK_VERSION_NUM) {
WRITE_ENUM_FIELD(strength, LockClauseStrength);
}
if (t_thrd.proc->workingVersionNum >= WAIT_N_TUPLE_LOCK_VERSION_NUM) {
WRITE_BOOL_FIELD(waitSec);
}
}
static void _outXmlSerialize(StringInfo str, XmlSerialize* node)
{
WRITE_NODE_TYPE("XMLSERIALIZE");
WRITE_ENUM_FIELD(xmloption, XmlOptionType);
WRITE_NODE_FIELD(expr);
WRITE_NODE_FIELD(typname);
WRITE_LOCATION_FIELD(location);
}
static void _outColumnDef(StringInfo str, ColumnDef* node)
{
WRITE_NODE_TYPE("COLUMNDEF");
WRITE_STRING_FIELD(colname);
WRITE_NODE_FIELD(typname);
WRITE_INT_FIELD(kvtype);
WRITE_INT_FIELD(inhcount);
WRITE_BOOL_FIELD(is_local);
WRITE_BOOL_FIELD(is_not_null);
WRITE_BOOL_FIELD(is_from_type);
WRITE_BOOL_FIELD(is_serial);
if (node->storage == 0) {
appendStringInfo(str, " :storage 0");
} else {
WRITE_CHAR_FIELD(storage);
}
/* because the ENUM type is not used, so void is passed in */
WRITE_ENUM_FIELD(cmprs_mode, void);
WRITE_NODE_FIELD(raw_default);
WRITE_NODE_FIELD(cooked_default);
WRITE_NODE_FIELD(collClause);
WRITE_OID_FIELD(collOid);
WRITE_NODE_FIELD(constraints);
WRITE_NODE_FIELD(fdwoptions);
if (t_thrd.proc->workingVersionNum >= COMMENT_SUPPORT_VERSION_NUM) {
WRITE_NODE_FIELD(columnOptions);
}
WRITE_NODE_FIELD(clientLogicColumnRef);
if (t_thrd.proc->workingVersionNum >= GENERATED_COL_VERSION_NUM) {
if (node->generatedCol)
WRITE_CHAR_FIELD(generatedCol);
}
if (t_thrd.proc->workingVersionNum >= ON_UPDATE_TIMESTAMP_VERSION_NUM) {
WRITE_NODE_FIELD(update_default);
}
}
static void _outTypeName(StringInfo str, TypeName* node)
{
WRITE_NODE_TYPE("TYPENAME");
WRITE_NODE_FIELD(names);
WRITE_OID_FIELD(typeOid);
WRITE_BOOL_FIELD(setof);
WRITE_BOOL_FIELD(pct_type);
WRITE_NODE_FIELD(typmods);
WRITE_INT_FIELD(typemod);
WRITE_NODE_FIELD(arrayBounds);
WRITE_LOCATION_FIELD(location);
if (t_thrd.proc->workingVersionNum >= COMMENT_ROWTYPE_TABLEOF_VERSION_NUM)
{
WRITE_BOOL_FIELD(pct_rowtype);
}
if (t_thrd.proc->workingVersionNum >= COMMENT_PCT_TYPE_VERSION_NUM)
{
WRITE_LOCATION_FIELD(end_location);
}
WRITE_TYPEINFO_FIELD(typeOid);
}
static void _outTypeCast(StringInfo str, TypeCast* node)
{
WRITE_NODE_TYPE("TYPECAST");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(typname);
WRITE_LOCATION_FIELD(location);
}
static void _outCollateClause(StringInfo str, CollateClause* node)
{
WRITE_NODE_TYPE("COLLATECLAUSE");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(collname);
WRITE_LOCATION_FIELD(location);
}
static void _outColumnParam (StringInfo str, ClientLogicColumnParam* node)
{
WRITE_NODE_TYPE("COLUMNPARAM");
WRITE_ENUM_FIELD(key, ClientLogicColumnProperty);
WRITE_STRING_FIELD(value);
WRITE_UINT_FIELD(len);
WRITE_LOCATION_FIELD(location);
}
static void _outGlobalParam (StringInfo str, ClientLogicGlobalParam* node)
{
WRITE_NODE_TYPE("GLOBALPARAM");
WRITE_ENUM_FIELD(key, ClientLogicGlobalProperty);
WRITE_STRING_FIELD(value);
WRITE_UINT_FIELD(len);
WRITE_LOCATION_FIELD(location);
}
static void _outGlobalSetting (StringInfo str, CreateClientLogicGlobal* node)
{
WRITE_NODE_TYPE("GLOBALSETTING");
WRITE_NODE_FIELD(global_key_name);
WRITE_NODE_FIELD(global_setting_params);
}
static void _outColumnSetting (StringInfo str, CreateClientLogicColumn* node)
{
WRITE_NODE_TYPE("COLUMNSETTING");
WRITE_NODE_FIELD(column_key_name);
WRITE_NODE_FIELD(column_setting_params);
}
static void
_outClientLogicColumnRef(StringInfo str, ClientLogicColumnRef *node)
{
WRITE_NODE_TYPE("CLIENTLOGICCOLUMNREF");
WRITE_NODE_FIELD(column_key_name);
WRITE_NODE_FIELD(orig_typname);
WRITE_NODE_FIELD(dest_typname);
WRITE_LOCATION_FIELD(location);
}
static void _outIndexElem(StringInfo str, IndexElem* node)
{
WRITE_NODE_TYPE("INDEXELEM");
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(expr);
WRITE_STRING_FIELD(indexcolname);
WRITE_NODE_FIELD(collation);
WRITE_NODE_FIELD(opclass);
WRITE_ENUM_FIELD(ordering, SortByDir);
WRITE_ENUM_FIELD(nulls_ordering, SortByNulls);
}
static void _outUserSetElem(StringInfo str, UserSetElem* node)
{
WRITE_NODE_TYPE("USERSETELEM");
WRITE_NODE_FIELD(name);
WRITE_NODE_FIELD(val);
}
static void _outUserVar(StringInfo str, UserVar* node)
{
WRITE_NODE_TYPE("USERVAR");
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(value);
}
static void _outDefElem(StringInfo str, DefElem* node)
{
WRITE_NODE_TYPE("DEFELEM");
WRITE_STRING_FIELD(defnamespace);
WRITE_STRING_FIELD(defname);
WRITE_NODE_FIELD(arg);
WRITE_ENUM_FIELD(defaction, DefElemAction);
if (t_thrd.proc->workingVersionNum >= COPY_TRANSFORM_VERSION_NUM) {
WRITE_INT_FIELD(begin_location);
WRITE_INT_FIELD(end_location);
}
}
static void _outPLDebug_variable(StringInfo str, PLDebug_variable* node)
{
WRITE_NODE_TYPE("PLDEBUG_VARIABLE");
WRITE_STRING_FIELD(name);
WRITE_STRING_FIELD(var_type);
WRITE_STRING_FIELD(value);
WRITE_STRING_FIELD(pkgname);
WRITE_BOOL_FIELD(isconst);
}
static void _outPLDebug_breakPoint(StringInfo str, PLDebug_breakPoint* node)
{
WRITE_NODE_TYPE("PLDEBUG_BREAKPOINT");
WRITE_INT_FIELD(bpIndex);
WRITE_OID_FIELD(funcoid);
WRITE_INT_FIELD(lineno);
WRITE_STRING_FIELD(query);
WRITE_BOOL_FIELD(active);
}
static void _outPLDebug_frame(StringInfo str, PLDebug_frame* node)
{
WRITE_NODE_TYPE("PLDEBUG_FRAME");
WRITE_INT_FIELD(frameno);
WRITE_STRING_FIELD(funcname);
WRITE_INT_FIELD(lineno);
WRITE_STRING_FIELD(query);
WRITE_INT_FIELD(funcoid);
}
/*
* @Description: Write hint node to string.
* @out str: String buf.
* @in node: Hint struct.
*/
static void _outBaseHint(StringInfo str, Hint* node)
{
WRITE_NODE_FIELD(relnames);
WRITE_ENUM_FIELD(hint_keyword, HintKeyword);
WRITE_ENUM_FIELD(state, HintStatus);
}
/*
* @Description: No GPC hint node to string.
* @out str: String buf.
* @in node: No GPC hint struct.
*/
static void _outNoGPCHint(StringInfo str, const NoGPCHint* node)
{
WRITE_NODE_TYPE("NOGPCHINT");
_outBaseHint(str, (Hint*)node);
}
/*
* @Description: No Expand hint node to string.
* @out str: String buf.
* @in node: No Expand hint struct.
*/
static void _outNoExpandHint(StringInfo str, const NoExpandHint* node)
{
WRITE_NODE_TYPE("NOEXPANDHINT");
_outBaseHint(str, (Hint*)node);
}
/*
* @Description: Set hint node to string.
* @out str: String buf.
* @in node: Set hint struct.
*/
static void _outSetHint(StringInfo str, const SetHint* node)
{
WRITE_NODE_TYPE("SETHINT");
_outBaseHint(str, (Hint*)node);
WRITE_STRING_FIELD(name);
WRITE_STRING_FIELD(value);
}
/*
* @Description: Plancache hint node to string.
* @out str: String buf.
* @in node: Plancache hint struct.
*/
static void _outPlanCacheHint(StringInfo str, const PlanCacheHint* node)
{
WRITE_NODE_TYPE("PLANCACHEHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(chooseCustomPlan);
/* Not write locator_type in accordance with old version. */
if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) {
WRITE_ENUM_FIELD(method, GplanSelectionMethod);
}
}
/*
* @Description: Leading hint node to string.
* @out str: String buf.
* @in node: Leading hint struct.
*/
static void _outLeadingHint(StringInfo str, LeadingHint* node)
{
WRITE_NODE_TYPE("LEADINGHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(join_order_hint);
}
/*
* @Description: Predpush hint node to string.
* @out str: String buf.
* @in node: Predpush hint struct.
*/
static void _outPredpushHint(StringInfo str, PredpushHint* node)
{
WRITE_NODE_TYPE("PREDPUSHHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(negative);
WRITE_STRING_FIELD(dest_name);
WRITE_INT_FIELD(dest_id);
WRITE_BITMAPSET_FIELD(candidates);
}
/*
* @Description: Predpush same level hint node to string.
* @out str: String buf.
* @in node: Predpush same level hint struct.
*/
static void _outPredpushSameLevelHint(StringInfo str, PredpushSameLevelHint* node)
{
WRITE_NODE_TYPE("PREDPUSHSAMELEVELHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(negative);
WRITE_STRING_FIELD(dest_name);
WRITE_INT_FIELD(dest_id);
WRITE_BITMAPSET_FIELD(candidates);
}
/*
* @Description: Rewrite hint node to string.
* @out str: String buf.
* @in node: Rewrite hint struct.
*/
static void _outRewriteHint(StringInfo str, RewriteHint* node)
{
WRITE_NODE_TYPE("REWRITEHINT");
_outBaseHint(str, (Hint*)node);
WRITE_NODE_FIELD(param_names);
WRITE_UINT_FIELD(param_bits);
}
/*
* @Description: Gather hint node to string.
* @out str: String buf.
* @in node: Gather hint struct.
*/
static void _outGatherHint(StringInfo str, GatherHint* node)
{
WRITE_NODE_TYPE("GATHERHINT");
_outBaseHint(str, (Hint*)node);
WRITE_ENUM_FIELD(source, GatherSource);
}
/*
* @Description: Write join hint node to string.
* @out str: String buf.
* @in node: Join hint struct.
*/
static void _outJoinHint(StringInfo str, JoinMethodHint* node)
{
WRITE_NODE_TYPE("JOINHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(negative);
WRITE_BITMAPSET_FIELD(joinrelids);
WRITE_BITMAPSET_FIELD(inner_joinrelids);
}
/*
* @Description: Write rows hint node to string.
* @out str: String buf.
* @in node: Rows hint struct.
*/
static void _outRowsHint(StringInfo str, RowsHint* node)
{
WRITE_NODE_TYPE("ROWSHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BITMAPSET_FIELD(joinrelids);
WRITE_STRING_FIELD(rows_str);
WRITE_ENUM_FIELD(value_type, RowsValueType);
WRITE_FLOAT_FIELD(rows, "%f");
}
/*
* @Description: Write stream hint node to string.
* @out str: String buf.
* @in node: Stream hint struct.
*/
static void _outStreamHint(StringInfo str, StreamHint* node)
{
WRITE_NODE_TYPE("STREAMHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(negative);
WRITE_BITMAPSET_FIELD(joinrelids);
WRITE_ENUM_FIELD(stream_type, StreamType);
}
/*
* @Description: Write BlockName hint node to string.
* @out str: String buf.
* @in node: BlockName hint struct.
*/
static void _outBlockNameHint(StringInfo str, BlockNameHint* node)
{
WRITE_NODE_TYPE("BLOCKNAMEHINT");
_outBaseHint(str, (Hint*)node);
}
/*
* @Description: Write scan hint node to string.
* @out str: String buf.
* @in node: Scan hint struct.
*/
static void _outScanMethodHint(StringInfo str, ScanMethodHint* node)
{
WRITE_NODE_TYPE("SCANHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BOOL_FIELD(negative);
WRITE_BITMAPSET_FIELD(relid);
WRITE_NODE_FIELD(indexlist);
}
/*
* @Description: Write gc_fdw remote information node to string.
* @out str: String buf.
* @in node: gc_fdw remote informantion.
*/
static void _outPgFdwRemoteInfo(StringInfo str, PgFdwRemoteInfo* node)
{
WRITE_NODE_TYPE("PGFDWREMOTEINFO");
WRITE_CHAR_FIELD(reltype);
WRITE_INT_FIELD(datanodenum);
WRITE_FLOAT_FIELD(snapsize, "%lu");
/* Write the field name only one time and just append the value of each field */
appendStringInfo(str, " :snapshot");
Assert(node->snapsize % 2 == 0);
_outUint16Array(str, (uint16*)node->snapshot, node->snapsize / 2);
}
/*
* @Description: Write skew hint node to string.
* @out str: String buf.
* @in node: Skew hint struct.
*/
static void _outSkewHint(StringInfo str, SkewHint* node)
{
WRITE_NODE_TYPE("SKEWHINT");
_outBaseHint(str, (Hint*)node);
WRITE_BITMAPSET_FIELD(relid);
WRITE_NODE_FIELD(column_list);
WRITE_NODE_FIELD(value_list);
}
/*
* @Description: Write skew hint info node to string.
* @out str: String buf.
* @in node: SkewRelInfo struct.
*/
static void _outSkewRelInfo(StringInfo str, SkewRelInfo* node)
{
WRITE_NODE_TYPE("SKEWRELINFO");
WRITE_STRING_FIELD(relation_name);
WRITE_OID_FIELD(relation_oid);
WRITE_NODE_FIELD(rte);
WRITE_NODE_FIELD(parent_rte);
}
/*
* @Description: Write skew hint node to string.
* @out str: String buf.
* @in node: SkewColumnInfo struct.
*/
static void _outSkewColumnInfo(StringInfo str, SkewColumnInfo* node)
{
WRITE_NODE_TYPE("SKEWCOLUMNINFO");
WRITE_OID_FIELD(relation_Oid);
WRITE_STRING_FIELD(column_name);
WRITE_UINT_FIELD(attnum);
WRITE_OID_FIELD(column_typid);
WRITE_NODE_FIELD(expr);
WRITE_TYPEINFO_FIELD(column_typid);
}
/*
* @Description: Write skew hint node to string.
* @out str: String buf.
* @in node: SkewValueInfo struct.
*/
static void _outSkewValueInfo(StringInfo str, SkewValueInfo* node)
{
WRITE_NODE_TYPE("SKEWVALUEINFO");
WRITE_BOOL_FIELD(support_redis);
WRITE_NODE_FIELD(const_value);
}
/*
* @Description: Write skew hint node to string.
* @out str: String buf.
* @in node: Skew hint struct.
*/
static void _outSkewHintTransf(StringInfo str, SkewHintTransf* node)
{
WRITE_NODE_TYPE("SKEWHINTTRANSF");
WRITE_NODE_FIELD(before);
WRITE_NODE_FIELD(rel_info_list);
WRITE_NODE_FIELD(column_info_list);
WRITE_NODE_FIELD(value_info_list);
}
/*
* @Description: Write join hint state node to string.
* @out str: String buf.
* @in node: Hint state struct.
*/
static void _outHintState(StringInfo str, HintState* node)
{
WRITE_NODE_TYPE("HINTSTATE");
WRITE_INT_FIELD(nall_hints);
WRITE_NODE_FIELD(join_hint);
WRITE_NODE_FIELD(leading_hint);
WRITE_NODE_FIELD(row_hint);
WRITE_NODE_FIELD(stream_hint);
WRITE_NODE_FIELD(block_name_hint);
WRITE_NODE_FIELD(scan_hint);
WRITE_NODE_FIELD(skew_hint);
if (t_thrd.proc->workingVersionNum >= PREDPUSH_VERSION_NUM) {
WRITE_NODE_FIELD(predpush_hint);
}
if (t_thrd.proc->workingVersionNum >= EXECUTE_DIRECT_ON_MULTI_VERSION_NUM) {
WRITE_NODE_FIELD(rewrite_hint);
}
if (t_thrd.proc->workingVersionNum >= HINT_ENHANCEMENT_VERSION_NUM) {
WRITE_NODE_FIELD(gather_hint);
WRITE_NODE_FIELD(no_expand_hint);
WRITE_NODE_FIELD(set_hint);
WRITE_NODE_FIELD(cache_plan_hint);
WRITE_NODE_FIELD(no_gpc_hint);
}
if (t_thrd.proc->workingVersionNum >= PREDPUSH_SAME_LEVEL_VERSION_NUM) {
WRITE_NODE_FIELD(predpush_same_level_hint);
}
if (t_thrd.proc->workingVersionNum >= SQL_PATCH_VERSION_NUM) {
WRITE_BOOL_FIELD(from_sql_patch);
}
}
static void _outQuery(StringInfo str, Query* node)
{
WRITE_NODE_TYPE("QUERY");
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_ENUM_FIELD(querySource, QuerySource);
/* we intentionally do not print the queryId field */
WRITE_BOOL_FIELD(canSetTag);
/*
* Hack to work around missing outfuncs routines for a lot of the
* utility-statement node types. (The only one we actually *need* for
* rules support is NotifyStmt.) Someday we ought to support 'em all, but
* for the meantime do this to avoid getting lots of warnings when running
* with debug_print_parse on.
*/
if (node->utilityStmt) {
switch (nodeTag(node->utilityStmt)) {
case T_CreateStmt:
case T_IndexStmt:
case T_NotifyStmt:
case T_DeclareCursorStmt:
case T_CopyStmt:
case T_AlterTableStmt:
WRITE_NODE_FIELD(utilityStmt);
break;
default:
appendStringInfo(str, " :utilityStmt ?");
break;
}
} else {
appendStringInfo(str, " :utilityStmt <>");
}
WRITE_INT_FIELD(resultRelation);
WRITE_BOOL_FIELD(hasAggs);
WRITE_BOOL_FIELD(hasWindowFuncs);
WRITE_BOOL_FIELD(hasSubLinks);
WRITE_BOOL_FIELD(hasDistinctOn);
WRITE_BOOL_FIELD(hasRecursive);
WRITE_BOOL_FIELD(hasModifyingCTE);
WRITE_BOOL_FIELD(hasForUpdate);
WRITE_BOOL_FIELD(hasRowSecurity);
if (t_thrd.proc->workingVersionNum >= SYNONYM_VERSION_NUM) {
WRITE_BOOL_FIELD(hasSynonyms);
}
if (t_thrd.proc->workingVersionNum >= KEYWORD_IGNORE_COMPART_VERSION_NUM) {
WRITE_BOOL_FIELD(hasIgnore);
}
WRITE_NODE_FIELD(cteList);
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(jointree);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(starStart);
WRITE_NODE_FIELD(starEnd);
WRITE_NODE_FIELD(starOnly);
WRITE_NODE_FIELD(returningList);
WRITE_NODE_FIELD(groupClause);
WRITE_NODE_FIELD(groupingSets);
WRITE_NODE_FIELD(havingQual);
WRITE_NODE_FIELD(windowClause);
WRITE_NODE_FIELD(distinctClause);
WRITE_NODE_FIELD(sortClause);
WRITE_NODE_FIELD(limitOffset);
WRITE_NODE_FIELD(limitCount);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(setOperations);
WRITE_NODE_FIELD(constraintDeps);
WRITE_NODE_FIELD(hintState);
#ifdef PGXC
WRITE_STRING_FIELD(sql_statement);
WRITE_BOOL_FIELD(is_local);
WRITE_BOOL_FIELD(has_to_save_cmd_id);
WRITE_BOOL_FIELD(vec_output);
if (t_thrd.proc->workingVersionNum >= TRUNCAST_VERSION_NUM) {
WRITE_ENUM_FIELD(tdTruncCastStatus, TdTruncCastStatus);
} else {
appendStringInfo(str, " :" CppAsString(isTruncationCastAdded) " %s", booltostr(node->tdTruncCastStatus == NOT_CAST_BECAUSEOF_GUC));
}
WRITE_NODE_FIELD(equalVars);
#endif
WRITE_INT_FIELD(mergeTarget_relation);
WRITE_NODE_FIELD(mergeSourceTargetList);
WRITE_NODE_FIELD(mergeActionList);
#ifdef ENABLE_MULTIPLE_NODES
if (t_thrd.proc->workingVersionNum >= UPSERT_TO_MERGE_VERSION_NUM) {
WRITE_NODE_FIELD(upsertQuery);
}
if (t_thrd.proc->workingVersionNum >= UPSERT_ROW_STORE_VERSION_NUM) {
WRITE_NODE_FIELD(upsertClause);
}
#else
WRITE_NODE_FIELD(upsertQuery);
WRITE_NODE_FIELD(upsertClause);
#endif
WRITE_BOOL_FIELD(isRowTriggerShippable);
WRITE_BOOL_FIELD(use_star_targets);
WRITE_BOOL_FIELD(is_from_full_join_rewrite);
if (t_thrd.proc->workingVersionNum >= PARTIALPUSH_VERSION_NUM) {
WRITE_BOOL_FIELD(can_push);
}
if (t_thrd.proc->workingVersionNum >= SUBLINKPULLUP_VERSION_NUM) {
WRITE_BOOL_FIELD(unique_check);
}
if (t_thrd.proc->workingVersionNum >= MULTI_MODIFY_VERSION_NUM) {
WRITE_NODE_FIELD(resultRelations);
}
}
static void _outSortGroupClause(StringInfo str, SortGroupClause* node)
{
WRITE_NODE_TYPE("SORTGROUPCLAUSE");
WRITE_UINT_FIELD(tleSortGroupRef);
WRITE_OID_FIELD(eqop);
WRITE_OPINFO_FEILD(eqop);
WRITE_OID_FIELD(sortop);
WRITE_OPINFO_FEILD(sortop);
WRITE_BOOL_FIELD(nulls_first);
WRITE_BOOL_FIELD(hashable);
WRITE_BOOL_FIELD(groupSet);
}
static void _outGroupingSet(StringInfo str, const GroupingSet* node)
{
WRITE_NODE_TYPE("GROUPINGSET");
WRITE_ENUM_FIELD(kind, GroupingSetKind);
WRITE_NODE_FIELD(content);
WRITE_LOCATION_FIELD(location);
}
static void _outWindowClause(StringInfo str, WindowClause* node)
{
WRITE_NODE_TYPE("WINDOWCLAUSE");
WRITE_STRING_FIELD(name);
WRITE_STRING_FIELD(refname);
WRITE_NODE_FIELD(partitionClause);
WRITE_NODE_FIELD(orderClause);
WRITE_INT_FIELD(frameOptions);
WRITE_NODE_FIELD(startOffset);
WRITE_NODE_FIELD(endOffset);
WRITE_UINT_FIELD(winref);
WRITE_BOOL_FIELD(copiedOrder);
}
static void _outRowMarkClause(StringInfo str, RowMarkClause* node)
{
WRITE_NODE_TYPE("ROWMARKCLAUSE");
WRITE_UINT_FIELD(rti);
WRITE_BOOL_FIELD(forUpdate);
if (t_thrd.proc->workingVersionNum >= SKIP_LOCKED_VERSION_NUM) {
WRITE_ENUM_FIELD(waitPolicy, LockWaitPolicy);
} else {
WRITE_BOOL_EXPR(noWait, (node->waitPolicy == LockWaitError ? true: false));
}
if (t_thrd.proc->workingVersionNum >= WAIT_N_TUPLE_LOCK_VERSION_NUM) {
WRITE_INT_FIELD(waitSec);
}
WRITE_BOOL_FIELD(pushedDown);
if (t_thrd.proc->workingVersionNum >= ENHANCED_TUPLE_LOCK_VERSION_NUM) {
WRITE_ENUM_FIELD(strength, LockClauseStrength);
}
}
static void _outWithClause(StringInfo str, WithClause* node)
{
WRITE_NODE_TYPE("WITHCLAUSE");
WRITE_NODE_FIELD(ctes);
WRITE_BOOL_FIELD(recursive);
WRITE_LOCATION_FIELD(location);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_NODE_FIELD(sw_clause);
}
}
static void _outStartWithClause(StringInfo str, StartWithClause* node)
{
WRITE_NODE_TYPE("STARTWITHCLAUSE");
WRITE_NODE_FIELD(startWithExpr);
WRITE_NODE_FIELD(connectByExpr);
WRITE_NODE_FIELD(siblingsOrderBy);
WRITE_BOOL_FIELD(priorDirection);
WRITE_BOOL_FIELD(nocycle);
WRITE_BOOL_FIELD(opt);
}
static void _outCommonTableExpr(StringInfo str, CommonTableExpr* node)
{
WRITE_NODE_TYPE("COMMONTABLEEXPR");
WRITE_STRING_FIELD(ctename);
WRITE_NODE_FIELD(aliascolnames);
if (t_thrd.proc->workingVersionNum >= MATERIALIZED_CTE_NUM) {
WRITE_ENUM_FIELD(ctematerialized, CTEMaterialize);
}
WRITE_NODE_FIELD(ctequery);
WRITE_LOCATION_FIELD(location);
WRITE_BOOL_FIELD(cterecursive);
WRITE_INT_FIELD(cterefcount);
WRITE_NODE_FIELD(ctecolnames);
WRITE_NODE_FIELD(ctecoltypes);
WRITE_NODE_FIELD(ctecoltypmods);
WRITE_NODE_FIELD(ctecolcollations);
WRITE_TYPEINFO_LIST(ctecoltypes);
/* Not write locator_type in accordance with old version. */
if (t_thrd.proc->workingVersionNum >= MATERIALIZED_CTE_NUM) {
WRITE_BOOL_FIELD(self_reference);
}
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_NODE_FIELD(swoptions);
}
if (t_thrd.proc->workingVersionNum >= DEFAULT_MAT_CTE_NUM) {
WRITE_BOOL_FIELD(referenced_by_subquery);
}
}
static void _outStartWithTargetRelInfo(StringInfo str, StartWithTargetRelInfo* node)
{
WRITE_NODE_TYPE("STARTWITHTARGETRELINFO");
WRITE_STRING_FIELD(relname);
WRITE_STRING_FIELD(aliasname);
WRITE_STRING_FIELD(ctename);
WRITE_NODE_FIELD(columns);
WRITE_NODE_FIELD(tblstmt);
WRITE_ENUM_FIELD(rtekind, RTEKind);
WRITE_NODE_FIELD(rte);
WRITE_NODE_FIELD(rtr);
}
static void _outSetOperationStmt(StringInfo str, SetOperationStmt* node)
{
WRITE_NODE_TYPE("SETOPERATIONSTMT");
WRITE_ENUM_FIELD(op, SetOperation);
WRITE_BOOL_FIELD(all);
WRITE_NODE_FIELD(larg);
WRITE_NODE_FIELD(rarg);
WRITE_NODE_FIELD(colTypes);
WRITE_NODE_FIELD(colTypmods);
WRITE_NODE_FIELD(colCollations);
WRITE_NODE_FIELD(groupClauses);
WRITE_TYPEINFO_LIST(colTypes);
}
static void _outRteRelation(StringInfo str, const RangeTblEntry *node)
{
WRITE_OID_FIELD(relid);
WRITE_CHAR_FIELD(relkind);
if (t_thrd.proc->workingVersionNum >= MATVIEW_VERSION_NUM) {
WRITE_BOOL_FIELD(isResultRel);
}
WRITE_NODE_FIELD(tablesample);
if (TcapFeatureAvail()) {
WRITE_NODE_FIELD(timecapsule);
}
WRITE_OID_FIELD(partitionOid);
WRITE_BOOL_FIELD(isContainPartition);
if (t_thrd.proc->workingVersionNum >= SUBPARTITION_VERSION_NUM) {
WRITE_OID_FIELD(subpartitionOid);
WRITE_BOOL_FIELD(isContainSubPartition);
}
if (t_thrd.proc->workingVersionNum >= SYNONYM_VERSION_NUM) {
WRITE_OID_FIELD(refSynOid);
}
WRITE_BOOL_FIELD(ispartrel);
WRITE_BOOL_FIELD(ignoreResetRelid);
WRITE_NODE_FIELD(pname);
WRITE_NODE_FIELD(partid_list);
WRITE_NODE_FIELD(plist);
if (node->relid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->relid) &&
node->mainRelName == NULL) {
/*
* For inherit table, the relname will be different
*/
// shipping out for dn, relid will be different on dn, so relname and relnamespace string will be must.
char *rteRelname = NULL;
char *rteRelnamespace = NULL;
getNameById(node->relid, "RTE", &rteRelnamespace, &rteRelname);
appendStringInfo(str, " :relname ");
_outToken(str, rteRelname);
appendStringInfo(str, " :relnamespace ");
_outToken(str, rteRelnamespace);
/*
* Same reason as above,
* we need to serialize the namespace and synonym name instead of refSynOid
* when relation name is referenced from one synonym,
*/
if (t_thrd.proc->workingVersionNum >= SYNONYM_VERSION_NUM) {
WRITE_SYNINFO_FIELD(refSynOid);
}
}
}
static void _outRangeTblEntry(StringInfo str, RangeTblEntry* node)
{
WRITE_NODE_TYPE("RTE");
/* put alias + eref first to make dump more legible */
WRITE_NODE_FIELD(alias);
WRITE_NODE_FIELD(eref);
WRITE_ENUM_FIELD(rtekind, RTEKind);
#ifdef PGXC
WRITE_STRING_FIELD(relname);
WRITE_NODE_FIELD(partAttrNum);
#endif
if (node->mainRelName != NULL) {
WRITE_STRING_FIELD(mainRelName);
WRITE_STRING_FIELD(mainRelNameSpace);
}
switch (node->rtekind) {
case RTE_RELATION:
_outRteRelation(str, node);
break;
case RTE_SUBQUERY:
WRITE_NODE_FIELD(subquery);
WRITE_BOOL_FIELD(security_barrier);
break;
case RTE_JOIN:
WRITE_ENUM_FIELD(jointype, JoinType);
WRITE_NODE_FIELD(joinaliasvars);
break;
case RTE_FUNCTION:
WRITE_NODE_FIELD(funcexpr);
WRITE_NODE_FIELD(funccoltypes);
WRITE_NODE_FIELD(funccoltypmods);
WRITE_NODE_FIELD(funccolcollations);
WRITE_TYPEINFO_LIST(funccoltypes);
break;
case RTE_VALUES:
WRITE_NODE_FIELD(values_lists);
WRITE_NODE_FIELD(values_collations);
break;
case RTE_CTE:
WRITE_STRING_FIELD(ctename);
WRITE_UINT_FIELD(ctelevelsup);
WRITE_BOOL_FIELD(self_reference);
if (t_thrd.proc->workingVersionNum >= MATERIALIZED_CTE_NUM) {
WRITE_BOOL_FIELD(cterecursive);
}
WRITE_NODE_FIELD(ctecoltypes);
WRITE_NODE_FIELD(ctecoltypmods);
WRITE_NODE_FIELD(ctecolcollations);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_BOOL_FIELD(swConverted);
WRITE_NODE_FIELD(origin_index);
WRITE_BOOL_FIELD(swAborted);
WRITE_BOOL_FIELD(swSubExist);
}
WRITE_TYPEINFO_LIST(ctecoltypes);
break;
#ifdef PGXC
case RTE_REMOTE_DUMMY:
/* Everything relevant already copied */
break;
#endif /* PGXC */
case RTE_RESULT:
/* no extra fields */
break;
default:
ereport(ERROR,
(errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("unrecognized RTE kind: %d", (int)node->rtekind)));
break;
}
if (t_thrd.proc->workingVersionNum >= PREDPUSH_VERSION_NUM) {
WRITE_BOOL_FIELD(lateral);
}
WRITE_BOOL_FIELD(inh);
WRITE_BOOL_FIELD(inFromCl);
WRITE_UINT_FIELD(requiredPerms);
WRITE_OID_FIELD(checkAsUser);
WRITE_BITMAPSET_FIELD(selectedCols);
WRITE_BITMAPSET_FIELD(modifiedCols);
WRITE_BITMAPSET_FIELD(insertedCols);
WRITE_BITMAPSET_FIELD(updatedCols);
WRITE_ENUM_FIELD(orientation, RelOrientation);
WRITE_NODE_FIELD(securityQuals);
WRITE_BOOL_FIELD(subquery_pull_up);
WRITE_BOOL_FIELD(correlated_with_recursive_cte);
if (t_thrd.proc->workingVersionNum >= 92063) {
WRITE_BOOL_FIELD(relhasbucket);
WRITE_BOOL_FIELD(isbucket);
if (t_thrd.proc->workingVersionNum >= SEGMENT_PAGE_VERSION_NUM) {
WRITE_INT_FIELD(bucketmapsize);
}
WRITE_NODE_FIELD(buckets);
}
if (t_thrd.proc->workingVersionNum >= UPSERT_ROW_STORE_VERSION_NUM) {
WRITE_BOOL_FIELD(isexcluded);
}
if (t_thrd.proc->workingVersionNum >= SUBLINKPULLUP_VERSION_NUM) {
WRITE_BOOL_FIELD(sublink_pull_up);
}
if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) {
WRITE_BOOL_FIELD(is_ustore);
}
if (t_thrd.proc->workingVersionNum >= GENERATED_COL_VERSION_NUM) {
WRITE_BITMAPSET_FIELD(extraUpdatedCols);
}
if (t_thrd.proc->workingVersionNum >= MULTI_PARTITIONS_VERSION_NUM) {
WRITE_NODE_FIELD(partitionOidList);
WRITE_NODE_FIELD(subpartitionOidList);
}
}
/*
* Description: Write TableSampleClause struct to string.
*
* Parameters:
* @in node: tableSampleClause node.
* @out str: tableSampleClause string.
*
* Return: void
*/
static void _outTableSampleClause(StringInfo str, const TableSampleClause* node)
{
WRITE_NODE_TYPE("TABLESAMPLECLAUSE");
WRITE_ENUM_FIELD(sampleType, TableSampleType);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(repeatable);
}
/*
* Description: Write TimeCapsuleClause struct to string.
*
* Parameters: @in node: TimeCapsuleClause node.
* @out str: TimeCapsuleClause string.
*
* Return: void
*/
static void OutTimeCapsuleClause(StringInfo str, const TimeCapsuleClause* node)
{
WRITE_NODE_TYPE("TIMECAPSULECLAUSE");
WRITE_ENUM_FIELD(tvtype, TvVersionType);
WRITE_NODE_FIELD(tvver);
}
static void _outAExpr(StringInfo str, A_Expr* node)
{
WRITE_NODE_TYPE("AEXPR");
switch (node->kind) {
case AEXPR_OP:
appendStringInfo(str, " ");
WRITE_NODE_FIELD(name);
break;
case AEXPR_AND:
appendStringInfo(str, " AND");
break;
case AEXPR_OR:
appendStringInfo(str, " OR");
break;
case AEXPR_NOT:
appendStringInfo(str, " NOT");
break;
case AEXPR_OP_ANY:
appendStringInfo(str, " ");
WRITE_NODE_FIELD(name);
appendStringInfo(str, " ANY ");
break;
case AEXPR_OP_ALL:
appendStringInfo(str, " ");
WRITE_NODE_FIELD(name);
appendStringInfo(str, " ALL ");
break;
case AEXPR_DISTINCT:
appendStringInfo(str, " DISTINCT ");
WRITE_NODE_FIELD(name);
break;
case AEXPR_NULLIF:
appendStringInfo(str, " NULLIF ");
WRITE_NODE_FIELD(name);
break;
case AEXPR_OF:
appendStringInfo(str, " OF ");
WRITE_NODE_FIELD(name);
break;
case AEXPR_IN:
appendStringInfo(str, " IN ");
WRITE_NODE_FIELD(name);
break;
default:
appendStringInfo(str, " ??");
break;
}
WRITE_NODE_FIELD(lexpr);
WRITE_NODE_FIELD(rexpr);
WRITE_LOCATION_FIELD(location);
}
static void _outValue(StringInfo str, Value* value)
{
switch (value->type) {
case T_Integer:
appendStringInfo(str, "%ld", value->val.ival);
break;
case T_Float:
/*
* We assume the value is a valid numeric literal and so does not
* need quoting.
*/
appendStringInfoString(str, value->val.str);
break;
case T_String:
appendStringInfoChar(str, '"');
_outToken(str, value->val.str);
appendStringInfoChar(str, '"');
break;
case T_BitString:
/* internal representation already has leading 'b' */
appendStringInfoString(str, value->val.str);
break;
case T_Null:
/* this is seen only within A_Const, not in transformed trees */
appendStringInfoString(str, "NULL");
break;
default:
ereport(ERROR,
(errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("unrecognized node type: %d", (int)value->type)));
break;
}
}
static void _outColumnRef(StringInfo str, ColumnRef* node)
{
WRITE_NODE_TYPE("COLUMNREF");
WRITE_NODE_FIELD(fields);
if (t_thrd.proc->workingVersionNum >= SWCB_VERSION_NUM) {
WRITE_BOOL_FIELD(prior);
}
if (t_thrd.proc->workingVersionNum >= FUNC_PARAM_COL_VERSION_NUM) {
WRITE_INT_FIELD(indnum);
}
WRITE_LOCATION_FIELD(location);
}
static void _outParamRef(StringInfo str, ParamRef* node)
{
WRITE_NODE_TYPE("PARAMREF");
WRITE_INT_FIELD(number);
WRITE_LOCATION_FIELD(location);
}
static void _outAConst(StringInfo str, A_Const* node)
{
WRITE_NODE_TYPE("A_CONST");
appendStringInfo(str, " :val ");
_outValue(str, &(node->val));
WRITE_LOCATION_FIELD(location);
}
static void _outA_Star(StringInfo str, A_Star* node)
{
WRITE_NODE_TYPE("A_STAR");
}
static void _outA_Indices(StringInfo str, A_Indices* node)
{
WRITE_NODE_TYPE("A_INDICES");
WRITE_NODE_FIELD(lidx);
WRITE_NODE_FIELD(uidx);
}
static void _outA_Indirection(StringInfo str, A_Indirection* node)
{
WRITE_NODE_TYPE("A_INDIRECTION");
WRITE_NODE_FIELD(arg);
WRITE_NODE_FIELD(indirection);
}
static void _outA_ArrayExpr(StringInfo str, A_ArrayExpr* node)
{
WRITE_NODE_TYPE("A_ARRAYEXPR");
WRITE_NODE_FIELD(elements);
WRITE_LOCATION_FIELD(location);
}
static void _outResTarget(StringInfo str, ResTarget* node)
{
WRITE_NODE_TYPE("RESTARGET");
WRITE_STRING_FIELD(name);
WRITE_NODE_FIELD(indirection);
WRITE_NODE_FIELD(val);
WRITE_LOCATION_FIELD(location);
}
static void _outSortBy(StringInfo str, SortBy* node)
{
WRITE_NODE_TYPE("SORTBY");
WRITE_NODE_FIELD(node);
WRITE_ENUM_FIELD(sortby_dir, SortByDir);
WRITE_ENUM_FIELD(sortby_nulls, SortByNulls);
WRITE_NODE_FIELD(useOp);
WRITE_LOCATION_FIELD(location);
}
static void _outWindowDef(StringInfo str, WindowDef* node)
{
WRITE_NODE_TYPE("WINDOWDEF");
WRITE_STRING_FIELD(name);
WRITE_STRING_FIELD(refname);
WRITE_NODE_FIELD(partitionClause);
WRITE_NODE_FIELD(orderClause);
WRITE_INT_FIELD(frameOptions);
WRITE_NODE_FIELD(startOffset);
WRITE_NODE_FIELD(endOffset);
WRITE_LOCATION_FIELD(location);
}
static void _outRangeSubselect(StringInfo str, RangeSubselect* node)
{
WRITE_NODE_TYPE("RANGESUBSELECT");
WRITE_BOOL_FIELD(lateral);
WRITE_NODE_FIELD(subquery);
WRITE_NODE_FIELD(alias);
}
static void _outRangeFunction(StringInfo str, RangeFunction* node)
{
WRITE_NODE_TYPE("RANGEFUNCTION");
WRITE_BOOL_FIELD(lateral);
WRITE_NODE_FIELD(funccallnode);
WRITE_NODE_FIELD(alias);
WRITE_NODE_FIELD(coldeflist);
}
/*
* Description: Write node RangeTableSample to string.
*
* Parameters: @in node: RangeTableSample node.
* @out str: RangeTableSample string.
*
* Return: void
*/
static void _outRangeTableSample(StringInfo str, RangeTableSample* node)
{
WRITE_NODE_TYPE("RANGETABLESAMPLE");
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(method);
WRITE_NODE_FIELD(args);
WRITE_NODE_FIELD(repeatable);
WRITE_LOCATION_FIELD(location);
}
/*
* Description: Write node RangeTimeCapsule to string.
*
* Parameters:
* @in node: RangeTimeCapsule node.
* @out str: RangeTimeCapsule string.
*
* Return: void
*/
static void OutRangeTimeCapsule(StringInfo str, RangeTimeCapsule* node)
{
WRITE_NODE_TYPE("RANGETIMECAPSULE");
WRITE_NODE_FIELD(relation);
WRITE_ENUM_FIELD(tvtype, TvVersionType);
WRITE_NODE_FIELD(tvver);
WRITE_LOCATION_FIELD(location);
}
static void _outConstraint(StringInfo str, Constraint* node)
{
WRITE_NODE_TYPE("CONSTRAINT");
WRITE_STRING_FIELD(conname);
WRITE_BOOL_FIELD(deferrable);
WRITE_BOOL_FIELD(initdeferred);
WRITE_LOCATION_FIELD(location);
appendStringInfo(str, " :contype ");
switch (node->contype) {
case CONSTR_NULL:
appendStringInfo(str, "NULL");
break;
case CONSTR_NOTNULL:
appendStringInfo(str, "NOT_NULL");
break;
case CONSTR_DEFAULT:
appendStringInfo(str, "DEFAULT");
WRITE_NODE_FIELD(raw_expr);
if (t_thrd.proc->workingVersionNum >= ON_UPDATE_TIMESTAMP_VERSION_NUM) {
WRITE_NODE_FIELD(update_expr);
}
WRITE_STRING_FIELD(cooked_expr);
break;
case CONSTR_CHECK:
appendStringInfo(str, "CHECK");
WRITE_BOOL_FIELD(is_no_inherit);
WRITE_NODE_FIELD(raw_expr);
WRITE_STRING_FIELD(cooked_expr);
break;
case CONSTR_PRIMARY:
appendStringInfo(str, "PRIMARY_KEY");
WRITE_NODE_FIELD(keys);
if (t_thrd.proc->workingVersionNum >= SUPPORT_GPI_VERSION_NUM) {
WRITE_NODE_FIELD(including);
}
WRITE_NODE_FIELD(options);
WRITE_STRING_FIELD(indexname);
WRITE_STRING_FIELD(indexspace);
/* access_method and where_clause not currently used */
break;
case CONSTR_UNIQUE:
appendStringInfo(str, "UNIQUE");
WRITE_NODE_FIELD(keys);
if (t_thrd.proc->workingVersionNum >= SUPPORT_GPI_VERSION_NUM) {
WRITE_NODE_FIELD(including);
}
WRITE_NODE_FIELD(options);
WRITE_STRING_FIELD(indexname);
WRITE_STRING_FIELD(indexspace);
/* access_method and where_clause not currently used */
break;
case CONSTR_EXCLUSION:
appendStringInfo(str, "EXCLUSION");
WRITE_NODE_FIELD(exclusions);
if (t_thrd.proc->workingVersionNum >= SUPPORT_GPI_VERSION_NUM) {
WRITE_NODE_FIELD(including);
}
WRITE_NODE_FIELD(options);
WRITE_STRING_FIELD(indexname);
WRITE_STRING_FIELD(indexspace);
WRITE_STRING_FIELD(access_method);
WRITE_NODE_FIELD(where_clause);
break;
case CONSTR_FOREIGN:
appendStringInfo(str, "FOREIGN_KEY");
WRITE_NODE_FIELD(pktable);
WRITE_NODE_FIELD(fk_attrs);
WRITE_NODE_FIELD(pk_attrs);
WRITE_CHAR_FIELD(fk_matchtype);
WRITE_CHAR_FIELD(fk_upd_action);
WRITE_CHAR_FIELD(fk_del_action);
WRITE_NODE_FIELD(old_conpfeqop);
WRITE_OID_FIELD(old_pktable_oid);
WRITE_BOOL_FIELD(skip_validation);
WRITE_BOOL_FIELD(initially_valid);
break;
case CONSTR_CLUSTER:
appendStringInfo(str, "CLUSTER");
WRITE_NODE_FIELD(keys);
break;
case CONSTR_ATTR_DEFERRABLE:
appendStringInfo(str, "ATTR_DEFERRABLE");
break;
case CONSTR_ATTR_NOT_DEFERRABLE:
appendStringInfo(str, "ATTR_NOT_DEFERRABLE");
break;
case CONSTR_ATTR_DEFERRED:
appendStringInfo(str, "ATTR_DEFERRED");
break;
case CONSTR_ATTR_IMMEDIATE:
appendStringInfo(str, "ATTR_IMMEDIATE");
break;
default:
appendStringInfo(str, "<unrecognized_constraint %d>", (int)node->contype);
break;
}
if (t_thrd.proc->workingVersionNum >= COMMENT_SUPPORT_VERSION_NUM) {
WRITE_NODE_FIELD(constraintOptions);
}
}
static void _outDistFdwDataNodeTask(StringInfo str, DistFdwDataNodeTask* node)
{
WRITE_NODE_TYPE("DISTFDWDATANODETASK");
WRITE_STRING_FIELD(dnName);
WRITE_NODE_FIELD(task);
}
static void _outDistFdwFileSegment(StringInfo str, DistFdwFileSegment* node)
{
WRITE_NODE_TYPE("DISTFDWFILESEGMENT");
WRITE_STRING_FIELD(filename);
WRITE_LONG_FIELD(begin);
WRITE_LONG_FIELD(end);
WRITE_LONG_FIELD(ObjectSize);
}
static void _outSplitInfo(StringInfo str, SplitInfo* node)
{
WRITE_NODE_TYPE("SPLITINFO");
WRITE_STRING_FIELD(filePath);
WRITE_STRING_FIELD(fileName);
WRITE_NODE_FIELD(partContentList);
WRITE_LONG_FIELD(ObjectSize);
WRITE_STRING_FIELD(eTag);
WRITE_INT_FIELD(prefixSlashNum);
}
static void _outSplitMap(StringInfo str, SplitMap* node)
{
WRITE_NODE_TYPE("SPLITMAP");
WRITE_INT_FIELD(nodeId);
WRITE_CHAR_FIELD(locatorType);
WRITE_LONG_FIELD(totalSize);
WRITE_INT_FIELD(fileNums);
WRITE_STRING_FIELD(downDiskFilePath);
WRITE_NODE_FIELD(lengths);
WRITE_NODE_FIELD(splits);
}
static void _outErrorCacheEntry(StringInfo str, ErrorCacheEntry* node)
{
WRITE_NODE_TYPE("ERRORCACHEENTRY");
WRITE_NODE_FIELD(rte);
WRITE_STRING_FIELD(filename);
}
/* @hdfs */
static void _outDfsPrivateItem(StringInfo str, DfsPrivateItem* node)
{
int i;
WRITE_NODE_TYPE("DFSPRIVATEITEM");
WRITE_NODE_FIELD(columnList);
WRITE_NODE_FIELD(targetList);
WRITE_NODE_FIELD(restrictColList);
WRITE_NODE_FIELD(partList);
WRITE_NODE_FIELD(opExpressionList);
WRITE_NODE_FIELD(dnTask);
WRITE_NODE_FIELD(hdfsQual);
WRITE_INT_FIELD(colNum);
appendStringInfo(str, " :selectivity");
for (i = 0; i < node->colNum; i++) {
appendStringInfo(str, " %f", node->selectivity[i]);
}
}
/*
* Vector Plan Node
*/
static void _outRowToVec(StringInfo str, RowToVec* node)
{
WRITE_NODE_TYPE("ROWTOVEC");
_outPlanInfo(str, (Plan*)node);
}
static void _outVecToRow(StringInfo str, VecToRow* node)
{
WRITE_NODE_TYPE("VECTOROW");
_outPlanInfo(str, (Plan*)node);
}
static void _outVecSort(StringInfo str, VecSort* node)
{
int i;
WRITE_NODE_TYPE("VECSORT");
_outPlanInfo(str, (Plan*)node);
WRITE_INT_FIELD(numCols);
appendStringInfo(str, " :sortColIdx");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %d", node->sortColIdx[i]);
}
appendStringInfo(str, " :sortOperators");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->sortOperators[i]);
}
appendStringInfo(str, " :collations");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %u", node->collations[i]);
}
appendStringInfo(str, " :nullsFirst");
for (i = 0; i < node->numCols; i++) {
appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
}
out_mem_info(str, &node->mem_info);
}
static void _outVecResult(StringInfo str, VecResult* node)
{
WRITE_NODE_TYPE("VECRESULT");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(resconstantqual);
}
static void _outCStoreScan(StringInfo str, CStoreScan* node)
{
WRITE_NODE_TYPE("CSTORESCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(cstorequal);
WRITE_NODE_FIELD(minMaxInfo);
WRITE_ENUM_FIELD(relStoreLocation, RelstoreType);
WRITE_BOOL_FIELD(is_replica_table);
}
#ifdef ENABLE_MULTIPLE_NODES
static void
_outTsStoreScan(StringInfo str, TsStoreScan *node)
{
WRITE_NODE_TYPE("TSSTORESCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(tsstorequal);
WRITE_NODE_FIELD(minMaxInfo);
WRITE_ENUM_FIELD(relStoreLocation, RelstoreType);
WRITE_BOOL_FIELD(is_replica_table);
WRITE_INT_FIELD(sort_by_time_colidx);
WRITE_INT_FIELD(limit);
WRITE_BOOL_FIELD(is_simple_scan);
WRITE_BOOL_FIELD(has_sort);
WRITE_INT_FIELD(series_func_calls);
WRITE_INT_FIELD(top_key_func_arg);
}
#endif /* ENABLE_MULTIPLE_NODES */
static void _outVecSubqueryScan(StringInfo str, VecSubqueryScan* node)
{
WRITE_NODE_TYPE("VECSUBQUERYSCAN");
_outScanInfo(str, (Scan*)node);
WRITE_NODE_FIELD(subplan);
}
static void _outVecPartIterator(StringInfo str, VecPartIterator* node)
{
WRITE_NODE_TYPE("VECPARTITERATOR");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(partType, PartitionType);
WRITE_INT_FIELD(itrs);
WRITE_ENUM_FIELD(direction, ScanDirection);
WRITE_NODE_FIELD(param);
}
static void _outVecLimit(StringInfo str, VecLimit* node)
{
WRITE_NODE_TYPE("VECLIMIT");
_outPlanInfo(str, (Plan*)node);
WRITE_NODE_FIELD(limitOffset);
WRITE_NODE_FIELD(limitCount);
}
static void _outVecModifyTable(StringInfo str, VecModifyTable* node)
{
WRITE_NODE_TYPE("VECMODIFYTABLE");
_outPlanInfo(str, (Plan*)node);
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
WRITE_NODE_FIELD(plans);
WRITE_NODE_FIELD(returningLists);
WRITE_NODE_FIELD(rowMarks);
WRITE_INT_FIELD(epqParam);
WRITE_BOOL_FIELD(partKeyUpdated);
#ifdef PGXC
WRITE_NODE_FIELD(remote_plans);
WRITE_NODE_FIELD(remote_insert_plans);
WRITE_NODE_FIELD(remote_update_plans);
WRITE_NODE_FIELD(remote_delete_plans);
#endif
WRITE_NODE_FIELD(cacheEnt);
WRITE_INT_FIELD(mergeTargetRelation);
WRITE_NODE_FIELD(mergeSourceTargetList);
WRITE_NODE_FIELD(mergeActionList);
out_mem_info(str, &node->mem_info);
}
static void _outVecForeignScan(StringInfo str, VecForeignScan* node)
{
WRITE_NODE_TYPE("VECFOREIGNSCAN");
_outCommonForeignScanPart<VecForeignScan>(str, node);
}
static void _outVecStream(StringInfo str, VecStream* node)
{
WRITE_NODE_TYPE("VECSTREAM");
_outScanInfo(str, (Scan*)node);
WRITE_ENUM_FIELD(type, StreamType);
WRITE_STRING_FIELD(plan_statement);
WRITE_NODE_FIELD(consumer_nodes);
WRITE_NODE_FIELD(distribute_keys);
WRITE_BOOL_FIELD(is_sorted);
WRITE_NODE_FIELD(sort);
WRITE_BOOL_FIELD(is_dummy);
WRITE_INT_FIELD(smpDesc.consumerDop);
WRITE_INT_FIELD(smpDesc.producerDop);
WRITE_INT_FIELD(smpDesc.distriType);
WRITE_NODE_FIELD(skew_list);
WRITE_INT_FIELD(stream_level);
WRITE_NODE_FIELD(origin_consumer_nodes);
WRITE_BOOL_FIELD(is_recursive_local);
}
#ifdef PGXC
static void _outVecRemoteQuery(StringInfo str, VecRemoteQuery* node)
{
WRITE_NODE_TYPE("VECREMOTEQUERY");
_outCommonRemoteQueryPart<VecRemoteQuery>(str, node);
}
#endif
static void _outVecWindowAgg(StringInfo str, VecWindowAgg* node)
{
int i;
WRITE_NODE_TYPE("VECWINDOWAGG");
_outPlanInfo(str, (Plan*)node);
WRITE_UINT_FIELD(winref);
WRITE_INT_FIELD(partNumCols);
appendStringInfo(str, " :partColIdx");
for (i = 0; i < node->partNumCols; i++) {
appendStringInfo(str, " %d", node->partColIdx[i]);
}
appendStringInfo(str, " :partOperations");
for (i = 0; i < node->partNumCols; i++) {
appendStringInfo(str, " %u", node->partOperators[i]);
}
WRITE_INT_FIELD(ordNumCols);
appendStringInfo(str, " :ordColIdx");
for (i = 0; i < node->ordNumCols; i++) {
appendStringInfo(str, " %d", node->ordColIdx[i]);
}
appendStringInfo(str, " :ordOperations");
for (i = 0; i < node->ordNumCols; i++) {
appendStringInfo(str, " %u", node->ordOperators[i]);
}
WRITE_INT_FIELD(frameOptions);
WRITE_NODE_FIELD(startOffset);
WRITE_NODE_FIELD(endOffset);
out_mem_info(str, &node->mem_info);
}
static void _outInformationalConstraint(StringInfo str, InformationalConstraint* node)
{
WRITE_NODE_TYPE("SOFTCONSTRAINT");
WRITE_STRING_FIELD(constrname);
WRITE_CHAR_FIELD(contype);
WRITE_BOOL_FIELD(nonforced);
WRITE_BOOL_FIELD(enableOpt);
}
static void _outAttrMetaData(StringInfo str, AttrMetaData* node)
{
WRITE_NODE_TYPE("ATTRMETADATA");
WRITE_STRING_FIELD(attname);
WRITE_OID_FIELD(atttypid);
WRITE_OID_FIELD(attlen);
WRITE_OID_FIELD(attnum);
WRITE_OID_FIELD(atttypmod);
WRITE_BOOL_FIELD(attbyval);
WRITE_CHAR_FIELD(attstorage);
WRITE_CHAR_FIELD(attalign);
WRITE_BOOL_FIELD(attnotnull);
WRITE_BOOL_FIELD(atthasdef);
WRITE_BOOL_FIELD(attisdropped);
WRITE_BOOL_FIELD(attislocal);
WRITE_INT_FIELD(attcmprmode);
WRITE_INT_FIELD(attinhcount);
WRITE_OID_FIELD(attcollation);
WRITE_TYPEINFO_FIELD(atttypid);
}
static void _outRelationMetaData(StringInfo str, RelationMetaData* node)
{
WRITE_NODE_TYPE("RELATIONMETADATA");
WRITE_OID_FIELD(rd_id);
WRITE_OID_FIELD(spcNode);
WRITE_OID_FIELD(dbNode);
WRITE_OID_FIELD(relNode);
if (t_thrd.proc->workingVersionNum >= 92063) {
WRITE_INT_FIELD(bucketNode);
}
WRITE_STRING_FIELD(relname);
WRITE_CHAR_FIELD(relkind);
WRITE_CHAR_FIELD(parttype);
WRITE_INT_FIELD(natts);
WRITE_NODE_FIELD(attrs);
}
static void _outForeignOptions(StringInfo str, ForeignOptions* node)
{
WRITE_NODE_TYPE("FOREIGNOPTIONS");
WRITE_ENUM_FIELD(stype, ServerTypeOption);
WRITE_NODE_FIELD(fOptions);
}
/**
* @Description: serialze the BloomFilterSet struct.
* @in str, store serialized string.
* @in node, the node to be serialize.
* @return none.
*/
static void _outBloomFilterSet(StringInfo str, BloomFilterSet* node)
{
uint64 len = str->len;
WRITE_NODE_TYPE("BLOOMFILTERSET");
WRITE_FLOAT_FIELD(length, "%lu");
_outUint64Array(str, node->data, node->length);
WRITE_FLOAT_FIELD(numBits, "%lu");
WRITE_FLOAT_FIELD(numHashFunctions, "%lu");
WRITE_FLOAT_FIELD(numValues, "%lu");
WRITE_FLOAT_FIELD(maxNumValues, "%lu");
WRITE_FLOAT_FIELD(startupEntries, "%lu");
if (node->startupEntries > 0) {
for (uint64 cell = 0; cell < node->startupEntries; cell++) {
_outUint16Array(str, node->valuePositions[cell].position, MAX_HASH_FUNCTIONS);
}
}
WRITE_FLOAT_FIELD(minIntValue, "%lu");
WRITE_FLOAT_FIELD(minFloatValue, "%f");
WRITE_STRING_FIELD(minStringValue);
WRITE_FLOAT_FIELD(maxIntValue, "%lu");
WRITE_FLOAT_FIELD(maxFloatValue, "%f");
WRITE_STRING_FIELD(maxStringValue);
WRITE_BOOL_FIELD(addMinMax);
WRITE_BOOL_FIELD(hasMM);
WRITE_ENUM_FIELD(bfType, BloomFilterType);
WRITE_OID_FIELD(dataType);
WRITE_INT_FIELD(typeMod);
WRITE_OID_FIELD(collation);
WRITE_TYPEINFO_FIELD(dataType);
elog(DEBUG1, "outfuncs:%s", str->data + len);
}
/*
* @Description: serialze PurgeStmt
* @out str: String buf.
* @in node: PurgeStmt struct.
*/
static void OutPurgeStmt(StringInfo str, PurgeStmt* node)
{
WRITE_NODE_TYPE("PURGESTMT");
WRITE_ENUM_FIELD(purtype, PurgeType);
WRITE_NODE_FIELD(purobj);
}
/*
* @Description: serialze TimeCapsuleStmt
* @out str: String buf.
* @in node: TimeCapsuleStmt struct.
*/
static void OutTimeCapsuleStmt(StringInfo str, TimeCapsuleStmt* node)
{
WRITE_NODE_TYPE("TIMECAPSULESTME");
WRITE_ENUM_FIELD(tcaptype, TimeCapsuleType);
WRITE_NODE_FIELD(relation);
WRITE_STRING_FIELD(new_relname);
WRITE_NODE_FIELD(tvver);
WRITE_ENUM_FIELD(tvtype, TvVersionType);
}
/*
* @Description: serialze CommentStmt
* @out str: String buf.
* @in node: CommentStmt struct.
*/
static void _outCommentStmt(StringInfo str, CommentStmt* node)
{
WRITE_NODE_TYPE("COMMENTSTMT");
WRITE_ENUM_FIELD(objtype, ObjectType);
WRITE_NODE_FIELD(objname);
WRITE_NODE_FIELD(objargs);
WRITE_STRING_FIELD(comment);
}
/**
* @Description: serialze the TableLikeCtx struct.
* @in str, store serialized string.
* @in node, the node to be serialize.
* @return none.
*/
static void _outTableLikeCtx(StringInfo str, TableLikeCtx* node)
{
WRITE_NODE_TYPE("TABLELIKECTX");
WRITE_UINT_FIELD(options);
WRITE_BOOL_FIELD(temp_table);
WRITE_BOOL_FIELD(hasoids);
WRITE_NODE_FIELD(columns);
WRITE_NODE_FIELD(ckconstraints);
WRITE_NODE_FIELD(comments);
WRITE_NODE_FIELD(cluster_keys);
WRITE_NODE_FIELD(partition);
WRITE_NODE_FIELD(inh_indexes);
WRITE_NODE_FIELD(reloptions);
}
static void _outQualSkewInfo(StringInfo str, QualSkewInfo* node)
{
WRITE_NODE_TYPE("QUALSKEWINFO");
WRITE_ENUM_FIELD(skew_stream_type, SkewStreamType);
WRITE_NODE_FIELD(skew_quals);
WRITE_FLOAT_FIELD(qual_cost.startup, "%.2f");
WRITE_FLOAT_FIELD(qual_cost.per_tuple, "%.2f");
WRITE_FLOAT_FIELD(broadcast_ratio, "%.2f");
}
static void _outIndexVar(StringInfo str, IndexVar* node)
{
WRITE_NODE_TYPE("INDEXVAR");
WRITE_OID_FIELD(relid);
WRITE_UINT_FIELD(attno);
WRITE_STRING_FIELD(relname);
WRITE_STRING_FIELD(attname);
WRITE_BOOL_FIELD(indexcol);
WRITE_NODE_FIELD(indexoids);
WRITE_BOOL_FIELD(indexpath);
}
static void _outTrainModel(StringInfo str, TrainModel* node)
{
AlgorithmAPI *api = get_algorithm_api(node->algorithm);
int num_hyperp;
const HyperparameterDefinition* definition = api->get_hyperparameters_definitions(api, &num_hyperp);
if (node->configurations != 1)
elog(ERROR, "TODO_DB4AI_API: more than one hyperparameter configuration");
WRITE_NODE_TYPE("TrainModel");
_outPlanInfo(str, (Plan*)node);
appendStringInfoString(str, " :algorithm ");
appendStringInfoString(str, api->name);
HyperparametersGD *hyperp = (HyperparametersGD *)node->hyperparameters[0];
while (num_hyperp-- > 0) {
switch (definition->type) {
case INT4OID: {
int32_t *value_addr = (int32_t *)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %d", definition->name, *value_addr);
break;
}
case INT8OID: {
int64_t *value_addr = (int64_t *)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %ld", definition->name, *value_addr);
break;
}
case FLOAT8OID: {
double *value_addr = (double *)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %.16g", definition->name, *value_addr);
break;
}
case BOOLOID: {
bool *value_addr = (bool *)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %s", definition->name, booltostr(*value_addr));
break;
}
case CSTRINGOID: {
char **value_addr = (char **)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %s", definition->name, *value_addr);
break;
}
case ANYENUMOID: {
void *value_addr = (void *)((char *)hyperp + definition->offset);
appendStringInfo(str, " : %s %s", definition->name, definition->validation.enum_getter(value_addr));
break;
}
default:
break;
}
definition++;
}
}
static void _outAutoIncrement(StringInfo str, AutoIncrement* node)
{
WRITE_NODE_TYPE("AUTO_INCREMENT");
WRITE_NODE_FIELD(expr);
WRITE_OID_FIELD(autoincin_funcid);
WRITE_OID_FIELD(autoincout_funcid);
}
static void _outPrefixKey(StringInfo str, PrefixKey* node)
{
WRITE_NODE_TYPE("PREFIXKEY");
WRITE_NODE_FIELD(arg);
WRITE_INT_FIELD(length);
}
/*
* _outNode -
* converts a Node into ascii string and append it to 'str'
*/
static void _outNode(StringInfo str, const void* obj)
{
/* Guard against stack overflow due to overly complex expressions */
check_stack_depth();
if (obj == NULL) {
appendStringInfo(str, "<>");
} else if (IsA(obj, List) || IsA(obj, IntList) || IsA(obj, OidList)) {
_outList(str, (List*)obj);
} else if (IsA(obj, Integer) || IsA(obj, Float) || IsA(obj, String) || IsA(obj, BitString)) {
/* nodeRead does not want to see { } around these! */
_outValue(str, (Value*)obj);
} else {
appendStringInfoChar(str, '{');
switch (nodeTag(obj)) {
case T_PlannedStmt:
_outPlannedStmt(str, (PlannedStmt*)obj);
break;
case T_HDFSTableAnalyze:
_outHDFSTableAnalyze(str, (HDFSTableAnalyze*)obj);
break;
case T_Plan:
_outPlan(str, (Plan*)obj);
break;
case T_BaseResult:
_outResult(str, (BaseResult*)obj);
break;
case T_ModifyTable:
_outModifyTable(str, (ModifyTable*)obj);
break;
case T_MergeWhenClause:
_outMergeWhenClause(str, (MergeWhenClause*)obj);
break;
case T_Append:
_outAppend(str, (Append*)obj);
break;
case T_MergeAppend:
_outMergeAppend(str, (MergeAppend*)obj);
break;
case T_RecursiveUnion:
_outRecursiveUnion(str, (RecursiveUnion*)obj);
break;
case T_StartWithOptions:
_outStartWithOptions(str, (StartWithOptions*)obj);
break;
case T_StartWithOp:
_outStartWithOp(str, (StartWithOp*)obj);
break;
case T_BitmapAnd:
_outBitmapAnd(str, (BitmapAnd*)obj);
break;
case T_BitmapOr:
_outBitmapOr(str, (BitmapOr*)obj);
break;
case T_Scan:
_outScan(str, (Scan*)obj);
break;
case T_BucketInfo:
_outBucketInfo(str, (BucketInfo*)obj);
break;
case T_SeqScan:
_outSeqScan(str, (SeqScan*)obj);
break;
#ifdef PGXC
case T_RemoteQuery:
_outRemoteQuery(str, (RemoteQuery*)obj);
break;
case T_RemoteQueryPath:
_outRemoteQueryPath(str, (RemoteQueryPath*)obj);
break;
#endif
case T_Stream:
_outStream(str, (Stream*)obj);
break;
case T_StreamPath:
_outStreamPath(str, (StreamPath*)obj);
break;
case T_IndexScan:
_outIndexScan(str, (IndexScan*)obj);
break;
case T_IndexOnlyScan:
_outIndexOnlyScan(str, (IndexOnlyScan*)obj);
break;
case T_CStoreIndexScan:
_outCStoreIndexScan(str, (CStoreIndexScan*)obj);
break;
case T_BitmapIndexScan:
_outBitmapIndexScan(str, (BitmapIndexScan*)obj);
break;
case T_BitmapHeapScan:
_outBitmapHeapScan(str, (BitmapHeapScan*)obj);
break;
case T_CStoreIndexCtidScan:
_outCStoreIndexCtidScan(str, (CStoreIndexCtidScan*)obj);
break;
case T_CStoreIndexHeapScan:
_outCStoreIndexHeapScan(str, (CStoreIndexHeapScan*)obj);
break;
case T_CStoreIndexAnd:
_outCStoreIndexAnd(str, (CStoreIndexAnd*)obj);
break;
case T_CStoreIndexOr:
_outCStoreIndexOr(str, (CStoreIndexOr*)obj);
break;
case T_TidScan:
_outTidScan(str, (TidScan*)obj);
break;
case T_PartIteratorParam:
_outPartIteratorParam(str, (PartIteratorParam*)obj);
break;
case T_PartIterator:
_outPartIterator(str, (PartIterator*)obj);
break;
case T_SubqueryScan:
_outSubqueryScan(str, (SubqueryScan*)obj);
break;
case T_FunctionScan:
_outFunctionScan(str, (FunctionScan*)obj);
break;
case T_ValuesScan:
_outValuesScan(str, (ValuesScan*)obj);
break;
case T_CteScan:
_outCteScan(str, (CteScan*)obj);
break;
case T_WorkTableScan:
_outWorkTableScan(str, (WorkTableScan*)obj);
break;
case T_ForeignScan:
_outForeignScan(str, (ForeignScan*)obj);
break;
case T_ForeignPartState:
_outForeignPartState(str, (ForeignPartState*)obj);
break;
case T_ExtensiblePlan:
_outExtensiblePlan(str, (ExtensiblePlan*)obj);
break;
case T_Join:
_outJoin(str, (Join*)obj);
break;
case T_NestLoop:
_outNestLoop(str, (NestLoop*)obj);
break;
case T_MergeJoin:
_outMergeJoin(str, (MergeJoin*)obj);
break;
case T_HashJoin:
_outHashJoin(str, (HashJoin*)obj);
break;
case T_Agg:
_outAgg(str, (Agg*)obj);
break;
case T_WindowAgg:
_outWindowAgg(str, (WindowAgg*)obj);
break;
case T_Group:
_outGroup(str, (Group*)obj);
break;
case T_Material:
_outMaterial(str, (Material*)obj);
break;
case T_Sort:
_outSort(str, (Sort*)obj);
break;
case T_Unique:
_outUnique(str, (Unique*)obj);
break;
case T_Hash:
_outHash(str, (Hash*)obj);
break;
case T_SetOp:
_outSetOp(str, (SetOp*)obj);
break;
case T_LockRows:
_outLockRows(str, (LockRows*)obj);
break;
case T_Limit:
_outLimit(str, (Limit*)obj);
break;
case T_NestLoopParam:
_outNestLoopParam(str, (NestLoopParam*)obj);
break;
case T_PlanRowMark:
_outPlanRowMark(str, (PlanRowMark*)obj);
break;
case T_PlanInvalItem:
_outPlanInvalItem(str, (PlanInvalItem*)obj);
break;
case T_Alias:
_outAlias(str, (Alias*)obj);
break;
case T_RangeVar:
_outRangeVar(str, (RangeVar*)obj);
break;
case T_IntoClause:
_outIntoClause(str, (IntoClause*)obj);
break;
case T_Var:
_outVar(str, (Var*)obj);
break;
case T_Const:
_outConst(str, (Const*)obj);
break;
case T_Param:
_outParam(str, (Param*)obj);
break;
case T_Rownum:
_outRownum(str, (Rownum*)obj);
break;
case T_Aggref:
_outAggref(str, (Aggref*)obj);
break;
case T_GroupingFunc:
_outGroupingFunc(str, (GroupingFunc*)obj);
break;
case T_GroupingId:
_outGroupingId(str, (GroupingId*)obj);
break;
case T_WindowFunc:
_outWindowFunc(str, (WindowFunc*)obj);
break;
case T_ArrayRef:
_outArrayRef(str, (ArrayRef*)obj);
break;
case T_FuncExpr:
_outFuncExpr(str, (FuncExpr*)obj);
break;
case T_NamedArgExpr:
_outNamedArgExpr(str, (NamedArgExpr*)obj);
break;
case T_OpExpr:
_outOpExpr(str, (OpExpr*)obj);
break;
case T_DistinctExpr:
_outDistinctExpr(str, (DistinctExpr*)obj);
break;
case T_NullIfExpr:
_outNullIfExpr(str, (NullIfExpr*)obj);
break;
case T_ScalarArrayOpExpr:
_outScalarArrayOpExpr(str, (ScalarArrayOpExpr*)obj);
break;
case T_BoolExpr:
_outBoolExpr(str, (BoolExpr*)obj);
break;
case T_SubLink:
_outSubLink(str, (SubLink*)obj);
break;
case T_SubPlan:
_outSubPlan(str, (SubPlan*)obj);
break;
case T_AlternativeSubPlan:
_outAlternativeSubPlan(str, (AlternativeSubPlan*)obj);
break;
case T_FieldSelect:
_outFieldSelect(str, (FieldSelect*)obj);
break;
case T_FieldStore:
_outFieldStore(str, (FieldStore*)obj);
break;
case T_RelabelType:
_outRelabelType(str, (RelabelType*)obj);
break;
case T_CoerceViaIO:
_outCoerceViaIO(str, (CoerceViaIO*)obj);
break;
case T_ArrayCoerceExpr:
_outArrayCoerceExpr(str, (ArrayCoerceExpr*)obj);
break;
case T_ConvertRowtypeExpr:
_outConvertRowtypeExpr(str, (ConvertRowtypeExpr*)obj);
break;
case T_CollateExpr:
_outCollateExpr(str, (CollateExpr*)obj);
break;
case T_CaseExpr:
_outCaseExpr(str, (CaseExpr*)obj);
break;
case T_CaseWhen:
_outCaseWhen(str, (CaseWhen*)obj);
break;
case T_CaseTestExpr:
_outCaseTestExpr(str, (CaseTestExpr*)obj);
break;
case T_ArrayExpr:
_outArrayExpr(str, (ArrayExpr*)obj);
break;
case T_RowExpr:
_outRowExpr(str, (RowExpr*)obj);
break;
case T_RowCompareExpr:
_outRowCompareExpr(str, (RowCompareExpr*)obj);
break;
case T_CoalesceExpr:
_outCoalesceExpr(str, (CoalesceExpr*)obj);
break;
case T_MinMaxExpr:
_outMinMaxExpr(str, (MinMaxExpr*)obj);
break;
case T_XmlExpr:
_outXmlExpr(str, (XmlExpr*)obj);
break;
case T_NullTest:
_outNullTest(str, (NullTest*)obj);
break;
case T_SetVariableExpr:
_outSetVariableExpr(str, (SetVariableExpr*)obj);
break;
case T_HashFilter:
_outHashFilter(str, (HashFilter*)obj);
break;
case T_BooleanTest:
_outBooleanTest(str, (BooleanTest*)obj);
break;
case T_CoerceToDomain:
_outCoerceToDomain(str, (CoerceToDomain*)obj);
break;
case T_CoerceToDomainValue:
_outCoerceToDomainValue(str, (CoerceToDomainValue*)obj);
break;
case T_SetToDefault:
_outSetToDefault(str, (SetToDefault*)obj);
break;
case T_CurrentOfExpr:
_outCurrentOfExpr(str, (CurrentOfExpr*)obj);
break;
case T_TargetEntry:
_outTargetEntry(str, (TargetEntry*)obj);
break;
case T_PseudoTargetEntry:
_outPseudoTargetEntry(str, (PseudoTargetEntry*)obj);
break;
case T_RangeTblRef:
_outRangeTblRef(str, (RangeTblRef*)obj);
break;
case T_JoinExpr:
_outJoinExpr(str, (JoinExpr*)obj);
break;
case T_FromExpr:
_outFromExpr(str, (FromExpr*)obj);
break;
case T_MergeAction:
_outMergeAction(str, (MergeAction*)obj);
break;
case T_UpsertExpr:
_outUpsertExpr(str, (UpsertExpr*)obj);
break;
case T_Path:
_outPath(str, (Path*)obj);
break;
case T_IndexPath:
_outIndexPath(str, (IndexPath*)obj);
break;
case T_BitmapHeapPath:
_outBitmapHeapPath(str, (BitmapHeapPath*)obj);
break;
case T_BitmapAndPath:
_outBitmapAndPath(str, (BitmapAndPath*)obj);
break;
case T_BitmapOrPath:
_outBitmapOrPath(str, (BitmapOrPath*)obj);
break;
case T_TidPath:
_outTidPath(str, (TidPath*)obj);
break;
case T_PartIteratorPath:
_outPartIteratorPath(str, (PartIteratorPath*)obj);
break;
case T_ForeignPath:
_outForeignPath(str, (ForeignPath*)obj);
break;
case T_AppendPath:
_outAppendPath(str, (AppendPath*)obj);
break;
case T_MergeAppendPath:
_outMergeAppendPath(str, (MergeAppendPath*)obj);
break;
case T_ResultPath:
_outResultPath(str, (ResultPath*)obj);
break;
case T_MaterialPath:
_outMaterialPath(str, (MaterialPath*)obj);
break;
case T_UniquePath:
_outUniquePath(str, (UniquePath*)obj);
break;
case T_NestPath:
_outNestPath(str, (NestPath*)obj);
break;
case T_MergePath:
_outMergePath(str, (MergePath*)obj);
break;
case T_HashPath:
_outHashPath(str, (HashPath*)obj);
break;
case T_PlannerGlobal:
_outPlannerGlobal(str, (PlannerGlobal*)obj);
break;
case T_PlannerInfo:
_outPlannerInfo(str, (PlannerInfo*)obj);
break;
case T_RelOptInfo:
_outRelOptInfo(str, (RelOptInfo*)obj);
break;
case T_IndexOptInfo:
_outIndexOptInfo(str, (IndexOptInfo*)obj);
break;
case T_EquivalenceClass:
_outEquivalenceClass(str, (EquivalenceClass*)obj);
break;
case T_EquivalenceMember:
_outEquivalenceMember(str, (EquivalenceMember*)obj);
break;
case T_PathKey:
_outPathKey(str, (PathKey*)obj);
break;
case T_ParamPathInfo:
_outParamPathInfo(str, (ParamPathInfo*)obj);
break;
case T_RestrictInfo:
_outRestrictInfo(str, (RestrictInfo*)obj);
break;
case T_PlaceHolderVar:
_outPlaceHolderVar(str, (PlaceHolderVar*)obj);
break;
case T_SpecialJoinInfo:
_outSpecialJoinInfo(str, (SpecialJoinInfo*)obj);
break;
case T_LateralJoinInfo:
_outLateralJoinInfo(str, (LateralJoinInfo *)obj);
break;
case T_AppendRelInfo:
_outAppendRelInfo(str, (AppendRelInfo*)obj);
break;
case T_PlaceHolderInfo:
_outPlaceHolderInfo(str, (PlaceHolderInfo*)obj);
break;
case T_MinMaxAggInfo:
_outMinMaxAggInfo(str, (MinMaxAggInfo*)obj);
break;
case T_PlannerParamItem:
_outPlannerParamItem(str, (PlannerParamItem*)obj);
break;
case T_CreateStmt:
_outCreateStmt(str, (CreateStmt*)obj);
break;
case T_PartitionState:
_outPartitionState(str, (PartitionState*)obj);
break;
case T_RangePartitionDefState:
_outRangePartitionDefState(str, (RangePartitionDefState*)obj);
break;
case T_ListPartitionDefState:
_outListPartitionDefState(str, (ListPartitionDefState*)obj);
break;
case T_HashPartitionDefState:
_outHashPartitionDefState(str, (HashPartitionDefState*)obj);
break;
case T_IntervalPartitionDefState:
_outIntervalPartitionDefState(str, (IntervalPartitionDefState*)obj);
break;
case T_RangePartitionindexDefState:
_outRangePartitionindexDefState(str, (RangePartitionindexDefState*)obj);
break;
case T_RangePartitionStartEndDefState:
_outRangePartitionStartEndDefState(str, (RangePartitionStartEndDefState*)obj);
break;
case T_AddPartitionState:
_outAddPartitionState(str, (AddPartitionState*)obj);
break;
case T_AddSubPartitionState:
_outAddSubPartitionState(str, (AddSubPartitionState*)obj);
break;
case T_CreateForeignTableStmt:
_outCreateForeignTableStmt(str, (CreateForeignTableStmt*)obj);
break;
case T_IndexStmt:
_outIndexStmt(str, (IndexStmt*)obj);
break;
case T_NotifyStmt:
_outNotifyStmt(str, (NotifyStmt*)obj);
break;
case T_DeclareCursorStmt:
_outDeclareCursorStmt(str, (DeclareCursorStmt*)obj);
break;
case T_CopyStmt:
_outCopyStmt(str, (CopyStmt*)obj);
break;
case T_AlterTableStmt:
_outAlterTableStmt(str, (AlterTableStmt*)obj);
break;
case T_SelectStmt:
_outSelectStmt(str, (SelectStmt*)obj);
break;
case T_MergeStmt:
_outMergeStmt(str, (MergeStmt*)obj);
break;
case T_InsertStmt:
_outInsertStmt(str, (InsertStmt*)obj);
break;
case T_UpdateStmt:
_outUpdateStmt(str, (UpdateStmt*)obj);
break;
case T_ColumnDef:
_outColumnDef(str, (ColumnDef*)obj);
break;
case T_TypeName:
_outTypeName(str, (TypeName*)obj);
break;
case T_TypeCast:
_outTypeCast(str, (TypeCast*)obj);
break;
case T_CollateClause:
_outCollateClause(str, (CollateClause*)obj);
break;
case T_ClientLogicColumnParam:
_outColumnParam(str, (ClientLogicColumnParam*)obj);
break;
case T_ClientLogicGlobalParam:
_outGlobalParam(str, (ClientLogicGlobalParam*)obj);
break;
case T_CreateClientLogicGlobal:
_outGlobalSetting(str, (CreateClientLogicGlobal*)obj);
break;
case T_CreateClientLogicColumn:
_outColumnSetting(str, (CreateClientLogicColumn*)obj);
break;
case T_ClientLogicColumnRef:
_outClientLogicColumnRef(str, (ClientLogicColumnRef *)obj);
break;
case T_IndexElem:
_outIndexElem(str, (IndexElem*)obj);
break;
case T_Query:
_outQuery(str, (Query*)obj);
break;
case T_SortGroupClause:
_outSortGroupClause(str, (SortGroupClause*)obj);
break;
case T_GroupingSet:
_outGroupingSet(str, (GroupingSet*)obj);
break;
case T_WindowClause:
_outWindowClause(str, (WindowClause*)obj);
break;
case T_RowMarkClause:
_outRowMarkClause(str, (RowMarkClause*)obj);
break;
case T_WithClause:
_outWithClause(str, (WithClause*)obj);
break;
case T_StartWithClause:
_outStartWithClause(str, (StartWithClause*)obj);
break;
case T_UpsertClause:
_outUpsertClause(str, (UpsertClause*)obj);
break;
case T_CommonTableExpr:
_outCommonTableExpr(str, (CommonTableExpr*)obj);
break;
case T_StartWithTargetRelInfo:
_outStartWithTargetRelInfo(str, (StartWithTargetRelInfo*) obj);
break;
case T_SetOperationStmt:
_outSetOperationStmt(str, (SetOperationStmt*)obj);
break;
case T_RangeTblEntry:
_outRangeTblEntry(str, (RangeTblEntry*)obj);
break;
case T_TableSampleClause:
_outTableSampleClause(str, (TableSampleClause*)obj);
break;
case T_TimeCapsuleClause:
OutTimeCapsuleClause(str, (TimeCapsuleClause*)obj);
break;
case T_A_Expr:
_outAExpr(str, (A_Expr*)obj);
break;
case T_ColumnRef:
_outColumnRef(str, (ColumnRef*)obj);
break;
case T_ParamRef:
_outParamRef(str, (ParamRef*)obj);
break;
case T_A_Const:
_outAConst(str, (A_Const*)obj);
break;
case T_A_Star:
_outA_Star(str, (A_Star*)obj);
break;
case T_A_Indices:
_outA_Indices(str, (A_Indices*)obj);
break;
case T_A_Indirection:
_outA_Indirection(str, (A_Indirection*)obj);
break;
case T_A_ArrayExpr:
_outA_ArrayExpr(str, (A_ArrayExpr*)obj);
break;
case T_ResTarget:
_outResTarget(str, (ResTarget*)obj);
break;
case T_SortBy:
_outSortBy(str, (SortBy*)obj);
break;
case T_WindowDef:
_outWindowDef(str, (WindowDef*)obj);
break;
case T_RangeSubselect:
_outRangeSubselect(str, (RangeSubselect*)obj);
break;
case T_RangeFunction:
_outRangeFunction(str, (RangeFunction*)obj);
break;
case T_RangeTableSample:
_outRangeTableSample(str, (RangeTableSample*)obj);
break;
case T_RangeTimeCapsule:
OutRangeTimeCapsule(str, (RangeTimeCapsule*)obj);
break;
case T_Constraint:
_outConstraint(str, (Constraint*)obj);
break;
case T_FuncCall:
_outFuncCall(str, (FuncCall*)obj);
break;
case T_DefElem:
_outDefElem(str, (DefElem*)obj);
break;
case T_TableLikeClause:
_outTableLikeClause(str, (TableLikeClause*)obj);
break;
case T_LockingClause:
_outLockingClause(str, (LockingClause*)obj);
break;
case T_XmlSerialize:
_outXmlSerialize(str, (XmlSerialize*)obj);
break;
#ifdef PGXC
case T_ExecNodes:
_outExecNodes(str, (ExecNodes*)obj);
break;
case T_SliceBoundary:
_outSliceBoundary(str, (SliceBoundary*)obj);
break;
case T_ExecBoundary:
_outExecBoundary(str, (ExecBoundary*)obj);
break;
case T_SimpleSort:
_outSimpleSort(str, (SimpleSort*)obj);
break;
#endif
case T_PruningResult:
_outPruningResult(str, (PruningResult *)obj);
break;
case T_SubPartitionPruningResult:
_outSubPartitionPruningResult(str, (SubPartitionPruningResult *)obj);
break;
case T_DistFdwDataNodeTask:
_outDistFdwDataNodeTask(str, (DistFdwDataNodeTask*)obj);
break;
case T_DistFdwFileSegment:
_outDistFdwFileSegment(str, (DistFdwFileSegment*)obj);
break;
case T_SplitInfo:
_outSplitInfo(str, (SplitInfo*)obj);
break;
case T_SplitMap:
_outSplitMap(str, (SplitMap*)obj);
break;
case T_ErrorCacheEntry:
_outErrorCacheEntry(str, (ErrorCacheEntry*)obj);
break;
case T_DfsPrivateItem:
_outDfsPrivateItem(str, (DfsPrivateItem*)obj);
break;
case T_PrefixKey:
_outPrefixKey(str, (PrefixKey*)obj);
break;
/*
* Vector Nodes
*/
case T_RowToVec:
_outRowToVec(str, (RowToVec*)obj);
break;
case T_VecToRow:
_outVecToRow(str, (VecToRow*)obj);
break;
case T_VecSort:
_outVecSort(str, (VecSort*)obj);
break;
case T_VecResult:
_outVecResult(str, (VecResult*)obj);
break;
case T_CStoreScan:
_outCStoreScan(str, (CStoreScan*)obj);
break;
#ifdef ENABLE_MULTIPLE_NODES
case T_TsStoreScan:
_outTsStoreScan(str, (TsStoreScan*)obj);
break;
#endif /* ENABLE_MULTIPLE_NODES */
case T_VecSubqueryScan:
_outVecSubqueryScan(str, (VecSubqueryScan*)obj);
break;
case T_VecPartIterator:
_outVecPartIterator(str, (VecPartIterator*)obj);
break;
case T_VecModifyTable:
_outVecModifyTable(str, (VecModifyTable*)obj);
break;
case T_VecForeignScan:
_outVecForeignScan(str, (VecForeignScan*)obj);
break;
case T_VecHashJoin:
_outVecHashJoin(str, (VecHashJoin*)obj);
break;
case T_VecAgg:
_outVecHashAgg(str, (VecAgg*)obj);
break;
case T_VecAppend:
_outVecAppend(str, (VecAppend*)obj);
break;
case T_VecLimit:
_outVecLimit(str, (VecLimit*)obj);
break;
case T_VecStream:
_outVecStream(str, (VecStream*)obj);
break;
#ifdef PGXC
case T_VecRemoteQuery:
_outVecRemoteQuery(str, (VecRemoteQuery*)obj);
break;
#endif
case T_VecGroup:
_outVecGroup(str, (VecGroup*)obj);
break;
case T_VecUnique:
_outVecUnique(str, (VecUnique*)obj);
break;
case T_VecSetOp:
_outVecSetOp(str, (VecSetOp*)obj);
break;
case T_VecNestLoop:
_outVecNestLoop(str, (VecNestLoop*)obj);
break;
case T_VecMaterial:
_outVecMaterial(str, (VecMaterial*)obj);
break;
case T_VecMergeJoin:
_outVecMergeJoin(str, (VecMergeJoin*)obj);
break;
case T_VecWindowAgg:
_outVecWindowAgg(str, (VecWindowAgg*)obj);
break;
case T_InformationalConstraint:
_outInformationalConstraint(str, (InformationalConstraint*)obj);
break;
case T_AttrMetaData:
_outAttrMetaData(str, (AttrMetaData*)obj);
break;
case T_RelationMetaData:
_outRelationMetaData(str, (RelationMetaData*)obj);
break;
case T_ForeignOptions:
_outForeignOptions(str, (ForeignOptions*)obj);
break;
case T_BloomFilterSet:
_outBloomFilterSet(str, (BloomFilterSet*)obj);
break;
case T_HintState:
_outHintState(str, (HintState*)obj);
break;
case T_JoinMethodHint:
_outJoinHint(str, (JoinMethodHint*)obj);
break;
case T_LeadingHint:
_outLeadingHint(str, (LeadingHint*)obj);
break;
case T_RowsHint:
_outRowsHint(str, (RowsHint*)obj);
break;
case T_StreamHint:
_outStreamHint(str, (StreamHint*)obj);
break;
case T_BlockNameHint:
_outBlockNameHint(str, (BlockNameHint*)obj);
break;
case T_ScanMethodHint:
_outScanMethodHint(str, (ScanMethodHint*)obj);
break;
case T_PgFdwRemoteInfo:
_outPgFdwRemoteInfo(str, (PgFdwRemoteInfo*)obj);
break;
case T_PurgeStmt:
OutPurgeStmt(str, (PurgeStmt*)obj);
break;
case T_TimeCapsuleStmt:
OutTimeCapsuleStmt(str, (TimeCapsuleStmt*)obj);
break;
case T_CommentStmt:
_outCommentStmt(str, (CommentStmt*)obj);
break;
case T_TableLikeCtx:
_outTableLikeCtx(str, (TableLikeCtx*)obj);
break;
case T_SkewHint:
_outSkewHint(str, (SkewHint*)obj);
break;
case T_SkewHintTransf:
_outSkewHintTransf(str, (SkewHintTransf*)obj);
break;
case T_SkewRelInfo:
_outSkewRelInfo(str, (SkewRelInfo*)obj);
break;
case T_SkewColumnInfo:
_outSkewColumnInfo(str, (SkewColumnInfo*)obj);
break;
case T_SkewValueInfo:
_outSkewValueInfo(str, (SkewValueInfo*)obj);
break;
case T_QualSkewInfo:
_outQualSkewInfo(str, (QualSkewInfo*)obj);
break;
case T_IndexVar:
_outIndexVar(str, (IndexVar*)obj);
break;
case T_PredpushHint:
_outPredpushHint(str, (PredpushHint *)obj);
break;
case T_PredpushSameLevelHint:
_outPredpushSameLevelHint(str, (PredpushSameLevelHint *)obj);
break;
case T_RewriteHint:
_outRewriteHint(str, (RewriteHint *)obj);
break;
case T_GatherHint:
_outGatherHint(str, (GatherHint *)obj);
break;
case T_NoExpandHint:
_outNoExpandHint(str, (NoExpandHint*) obj);
break;
case T_SetHint:
_outSetHint(str, (SetHint*) obj);
break;
case T_PlanCacheHint:
_outPlanCacheHint(str, (PlanCacheHint*) obj);
break;
case T_NoGPCHint:
_outNoGPCHint(str, (NoGPCHint*) obj);
case T_TrainModel:
_outTrainModel(str, (TrainModel*)obj);
break;
case T_UserSetElem:
_outUserSetElem(str, (UserSetElem *) obj);
break;
case T_UserVar:
_outUserVar(str, (UserVar *) obj);
break;
case T_PLDebug_variable:
_outPLDebug_variable(str, (PLDebug_variable*) obj);
break;
case T_PLDebug_breakPoint:
_outPLDebug_breakPoint(str, (PLDebug_breakPoint*) obj);
break;
case T_PLDebug_frame:
_outPLDebug_frame(str, (PLDebug_frame*) obj);
break;
case T_AutoIncrement:
_outAutoIncrement(str, (AutoIncrement*)obj);
break;
default:
/*
* This should be an ERROR, but it's too useful to be able to
* dump structures that _outNode only understands part of.
*/
elog(WARNING, "_outNode() could not dump unrecognized node type: %d", (int)nodeTag(obj));
break;
}
appendStringInfoChar(str, '}');
}
}
/*
* nodeToString -
* returns the ascii representation of the Node as a palloc'd string
*/
char* nodeToString(const void* obj)
{
StringInfoData str;
/* see stringinfo.h for an explanation of this maneuver */
initStringInfo(&str);
_outNode(&str, obj);
return str.data;
}
/*
* appendBitmapsetToString -
* append the ascii representation of bitmap set to a palloc'd string
*/
void appendBitmapsetToString(void* str, void* bms)
{
_outBitmapset((StringInfo)str, (Bitmapset*)bms);
}
/*
* out_mem_info -
* returns the ascii representation of the OpMemInfo structure
*/
static void out_mem_info(StringInfo str, OpMemInfo* node)
{
WRITE_FLOAT_FIELD(opMem, "%.2f");
WRITE_FLOAT_FIELD(minMem, "%.2f");
WRITE_FLOAT_FIELD(maxMem, "%.2f");
WRITE_FLOAT_FIELD(regressCost, "%.6f");
}
/*
* _outCursorData -
* returns the ascii representation of the Cursor_Data structure
*/
static void _outCursorData(StringInfo str, Cursor_Data* node)
{
WRITE_INT_FIELD(row_count);
WRITE_INT_FIELD(cur_dno);
WRITE_BOOL_FIELD(is_open);
WRITE_BOOL_FIELD(found);
WRITE_BOOL_FIELD(not_found);
WRITE_BOOL_FIELD(null_open);
WRITE_BOOL_FIELD(null_fetch);
}