Skip to content

Commit a4a4160

Browse files
committed
fix merge conflicts
2 parents ace45b9 + f52d998 commit a4a4160

File tree

1 file changed

+135
-2
lines changed

1 file changed

+135
-2
lines changed

src/runtime_merge_append.c

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@
1212
#include "pathman.h"
1313

1414
#include "postgres.h"
15+
#include "catalog/pg_collation.h"
16+
#include "miscadmin.h"
17+
#include "nodes/nodeFuncs.h"
18+
#include "optimizer/clauses.h"
1519
#include "optimizer/cost.h"
1620
#include "optimizer/planmain.h"
1721
#include "optimizer/tlist.h"
1822
#include "optimizer/var.h"
19-
#include "miscadmin.h"
23+
#include "utils/builtins.h"
24+
#include "utils/guc.h"
2025
#include "utils/lsyscache.h"
26+
#include "utils/typcache.h"
2127
#include "utils/memutils.h"
22-
#include "utils/guc.h"
28+
#include "utils/ruleutils.h"
29+
2330
#include "lib/binaryheap.h"
2431

2532

@@ -51,6 +58,11 @@ static Sort * make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
5158

5259
static void copy_plan_costsize(Plan *dest, Plan *src);
5360

61+
static void show_sort_group_keys(PlanState *planstate, const char *qlabel,
62+
int nkeys, AttrNumber *keycols,
63+
Oid *sortOperators, Oid *collations, bool *nullsFirst,
64+
List *ancestors, ExplainState *es);
65+
5466
/*
5567
* We have one slot for each item in the heap array. We use SlotNumber
5668
* to store slot indexes. This doesn't actually provide any formal
@@ -472,6 +484,12 @@ runtimemergeappend_explain(CustomScanState *node, List *ancestors, ExplainState
472484
RuntimeMergeAppendState *scan_state = (RuntimeMergeAppendState *) node;
473485

474486
explain_append_common(node, scan_state->rstate.children_table, es);
487+
488+
/* We should print sort keys as well */
489+
show_sort_group_keys((PlanState *) &node->ss.ps, "Sort Key",
490+
scan_state->numCols, scan_state->sortColIdx,
491+
scan_state->sortOperators, scan_state->collations,
492+
scan_state->nullsFirst, ancestors, es);
475493
}
476494

477495

@@ -794,3 +812,118 @@ prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
794812

795813
return lefttree;
796814
}
815+
816+
/*
817+
* Append nondefault characteristics of the sort ordering of a column to buf
818+
* (collation, direction, NULLS FIRST/LAST)
819+
*/
820+
static void
821+
show_sortorder_options(StringInfo buf, Node *sortexpr,
822+
Oid sortOperator, Oid collation, bool nullsFirst)
823+
{
824+
Oid sortcoltype = exprType(sortexpr);
825+
bool reverse = false;
826+
TypeCacheEntry *typentry;
827+
828+
typentry = lookup_type_cache(sortcoltype,
829+
TYPECACHE_LT_OPR | TYPECACHE_GT_OPR);
830+
831+
/*
832+
* Print COLLATE if it's not default. There are some cases where this is
833+
* redundant, eg if expression is a column whose declared collation is
834+
* that collation, but it's hard to distinguish that here.
835+
*/
836+
if (OidIsValid(collation) && collation != DEFAULT_COLLATION_OID)
837+
{
838+
char *collname = get_collation_name(collation);
839+
840+
if (collname == NULL)
841+
elog(ERROR, "cache lookup failed for collation %u", collation);
842+
appendStringInfo(buf, " COLLATE %s", quote_identifier(collname));
843+
}
844+
845+
/* Print direction if not ASC, or USING if non-default sort operator */
846+
if (sortOperator == typentry->gt_opr)
847+
{
848+
appendStringInfoString(buf, " DESC");
849+
reverse = true;
850+
}
851+
else if (sortOperator != typentry->lt_opr)
852+
{
853+
char *opname = get_opname(sortOperator);
854+
855+
if (opname == NULL)
856+
elog(ERROR, "cache lookup failed for operator %u", sortOperator);
857+
appendStringInfo(buf, " USING %s", opname);
858+
/* Determine whether operator would be considered ASC or DESC */
859+
(void) get_equality_op_for_ordering_op(sortOperator, &reverse);
860+
}
861+
862+
/* Add NULLS FIRST/LAST only if it wouldn't be default */
863+
if (nullsFirst && !reverse)
864+
{
865+
appendStringInfoString(buf, " NULLS FIRST");
866+
}
867+
else if (!nullsFirst && reverse)
868+
{
869+
appendStringInfoString(buf, " NULLS LAST");
870+
}
871+
}
872+
873+
/*
874+
* Common code to show sort/group keys, which are represented in plan nodes
875+
* as arrays of targetlist indexes. If it's a sort key rather than a group
876+
* key, also pass sort operators/collations/nullsFirst arrays.
877+
*/
878+
static void
879+
show_sort_group_keys(PlanState *planstate, const char *qlabel,
880+
int nkeys, AttrNumber *keycols,
881+
Oid *sortOperators, Oid *collations, bool *nullsFirst,
882+
List *ancestors, ExplainState *es)
883+
{
884+
Plan *plan = planstate->plan;
885+
List *context;
886+
List *result = NIL;
887+
StringInfoData sortkeybuf;
888+
bool useprefix;
889+
int keyno;
890+
891+
if (nkeys <= 0)
892+
return;
893+
894+
initStringInfo(&sortkeybuf);
895+
896+
/* Set up deparsing context */
897+
context = set_deparse_context_planstate(es->deparse_cxt,
898+
(Node *) planstate,
899+
ancestors);
900+
useprefix = (list_length(es->rtable) > 1 || es->verbose);
901+
902+
for (keyno = 0; keyno < nkeys; keyno++)
903+
{
904+
/* find key expression in tlist */
905+
AttrNumber keyresno = keycols[keyno];
906+
TargetEntry *target = get_tle_by_resno(plan->targetlist,
907+
keyresno);
908+
char *exprstr;
909+
910+
if (!target)
911+
elog(ERROR, "no tlist entry for key %d", keyresno);
912+
/* Deparse the expression, showing any top-level cast */
913+
exprstr = deparse_expression((Node *) target->expr, context,
914+
useprefix, true);
915+
resetStringInfo(&sortkeybuf);
916+
appendStringInfoString(&sortkeybuf, exprstr);
917+
/* Append sort order information, if relevant */
918+
if (sortOperators != NULL)
919+
show_sortorder_options(&sortkeybuf,
920+
(Node *) target->expr,
921+
sortOperators[keyno],
922+
collations[keyno],
923+
nullsFirst[keyno]);
924+
/* Emit one property-list item per sort key */
925+
result = lappend(result, pstrdup(sortkeybuf.data));
926+
}
927+
928+
ExplainPropertyList(qlabel, result, es);
929+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy