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)