From c517790d2ccf6668df9a737008da9e6b1c87c003 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 21 Dec 2023 17:02:03 +0200
Subject: [PATCH v1 3/5] Turn 'resjunk' into an enum

This doesn't have any user-visible effect. It's a separate commit for
easier review.
---
 src/backend/executor/functions.c          |  6 ++---
 src/backend/executor/nodeSubplan.c        |  4 ++--
 src/backend/nodes/makefuncs.c             |  2 +-
 src/backend/optimizer/plan/createplan.c   |  8 +++----
 src/backend/optimizer/plan/planagg.c      |  2 +-
 src/backend/optimizer/plan/setrefs.c      |  3 ++-
 src/backend/optimizer/plan/subselect.c    |  2 +-
 src/backend/optimizer/prep/prepjointree.c |  4 ++--
 src/backend/optimizer/prep/preptlist.c    | 14 ++++++------
 src/backend/optimizer/prep/prepunion.c    |  8 +++----
 src/backend/optimizer/util/appendinfo.c   |  4 ++--
 src/backend/optimizer/util/inherit.c      |  6 ++---
 src/backend/optimizer/util/plancat.c      |  6 ++---
 src/backend/optimizer/util/tlist.c        |  4 ++--
 src/backend/parser/analyze.c              | 15 ++++++------
 src/backend/parser/parse_agg.c            |  4 ++--
 src/backend/parser/parse_clause.c         |  4 ++--
 src/backend/parser/parse_expr.c           |  4 ++--
 src/backend/parser/parse_merge.c          |  2 +-
 src/backend/parser/parse_relation.c       |  2 +-
 src/backend/parser/parse_target.c         |  6 ++---
 src/backend/rewrite/rewriteHandler.c      |  4 ++--
 src/backend/rewrite/rewriteSearchCycle.c  | 28 +++++++++++------------
 src/include/nodes/makefuncs.h             |  2 +-
 src/include/nodes/primnodes.h             | 23 +++++++++++++++++--
 src/include/parser/parse_target.h         |  2 +-
 26 files changed, 95 insertions(+), 74 deletions(-)

diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index bace25234c3..fff41cb9dea 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -1853,7 +1853,7 @@ check_sql_fn_retval(List *queryTreeLists,
 										  makeTargetEntry(null_expr,
 														  list_length(upper_tlist) + 1,
 														  NULL,
-														  false));
+														  NOT_JUNK));
 					upper_tlist_nontrivial = true;
 				}
 			} while (attr->attisdropped);
@@ -1899,7 +1899,7 @@ check_sql_fn_retval(List *queryTreeLists,
 									  makeTargetEntry(null_expr,
 													  list_length(upper_tlist) + 1,
 													  NULL,
-													  false));
+													  NOT_JUNK));
 				upper_tlist_nontrivial = true;
 			}
 		}
@@ -2041,7 +2041,7 @@ coerce_fn_result_column(TargetEntry *src_tle,
 	}
 	new_tle = makeTargetEntry(new_tle_expr,
 							  list_length(*upper_tlist) + 1,
-							  src_tle->resname, false);
+							  src_tle->resname, NOT_JUNK);
 	*upper_tlist = lappend(*upper_tlist, new_tle);
 	return true;
 }
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index c136f75ac24..cbf6d2f8e07 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -982,7 +982,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 			tle = makeTargetEntry(expr,
 								  i,
 								  NULL,
-								  false);
+								  NOT_JUNK);
 			lefttlist = lappend(lefttlist, tle);
 
 			/* Process righthand argument */
@@ -990,7 +990,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 			tle = makeTargetEntry(expr,
 								  i,
 								  NULL,
-								  false);
+								  NOT_JUNK);
 			righttlist = lappend(righttlist, tle);
 
 			/* Lookup the equality function (potentially cross-type) */
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 89e77adbc75..59485f00043 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -241,7 +241,7 @@ TargetEntry *
 makeTargetEntry(Expr *expr,
 				AttrNumber resno,
 				char *resname,
-				bool resjunk)
+				JunkKind resjunk)
 {
 	TargetEntry *tle = makeNode(TargetEntry);
 
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 34ca6d4ac21..5842d31bdcd 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -844,7 +844,7 @@ build_path_tlist(PlannerInfo *root, Path *path)
 		tle = makeTargetEntry((Expr *) node,
 							  resno,
 							  NULL,
-							  false);
+							  NOT_JUNK);
 		if (sortgrouprefs)
 			tle->ressortgroupref = sortgrouprefs[resno - 1];
 
@@ -1772,7 +1772,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
 			tle = makeTargetEntry((Expr *) uniqexpr,
 								  nextresno,
 								  NULL,
-								  false);
+								  NOT_JUNK);
 			newtlist = lappend(newtlist, tle);
 			nextresno++;
 			newitems = true;
@@ -3156,7 +3156,7 @@ create_indexscan_plan(PlannerInfo *root,
 		{
 			TargetEntry *indextle = (TargetEntry *) lfirst(l);
 
-			indextle->resjunk = !indexinfo->canreturn[i];
+			indextle->resjunk = indexinfo->canreturn[i] ? NOT_JUNK: JUNK_PLANNER_ONLY;
 			i++;
 		}
 	}
@@ -6270,7 +6270,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
 			tle = makeTargetEntry(copyObject(em->em_expr),
 								  list_length(tlist) + 1,
 								  NULL,
-								  true);
+								  JUNK_SORT_GROUP_COL);
 			tlist = lappend(tlist, tle);
 			lefttree->targetlist = tlist;	/* just in case NIL before */
 		}
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index a6090167f5a..624afae6bce 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -371,7 +371,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo,
 	tle = makeTargetEntry(copyObject(mminfo->target),
 						  (AttrNumber) 1,
 						  pstrdup("agg_target"),
-						  false);
+						  NOT_JUNK);
 	tlist = list_make1(tle);
 	subroot->processed_tlist = parse->targetList = tlist;
 
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 4bb68ac90e7..8018a0c536a 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -1474,6 +1474,7 @@ trivial_subqueryscan(SubqueryScan *plan)
 		TargetEntry *ptle = (TargetEntry *) lfirst(lp);
 		TargetEntry *ctle = (TargetEntry *) lfirst(lc);
 
+		/* XXX: do the kind has to match exactly? */
 		if (ptle->resjunk != ctle->resjunk)
 			return false;		/* tlist doesn't match junk status */
 
@@ -2568,7 +2569,7 @@ convert_combining_aggrefs(Node *node, void *context)
 		 * And set up parent_agg to represent the second phase.
 		 */
 		parent_agg->args = list_make1(makeTargetEntry((Expr *) child_agg,
-													  1, NULL, false));
+													  1, NULL, NOT_JUNK));
 		mark_partial_aggref(parent_agg, AGGSPLIT_FINAL_DESERIAL);
 
 		return (Node *) parent_agg;
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 7a9fe88fec3..6ec8fe8abb5 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1826,7 +1826,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
 						makeTargetEntry((Expr *) rightarg,
 										resno++,
 										NULL,
-										false));
+										NOT_JUNK));
 		testlist = lappend(testlist,
 						   make_opclause(opid, BOOLOID, false,
 										 (Expr *) leftarg, (Expr *) param,
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 73ff40721c9..8ba6b59a6e6 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -1658,7 +1658,7 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
 						makeTargetEntry((Expr *) lfirst(lc),
 										attrno,
 										NULL,
-										false));
+										NOT_JUNK));
 		attrno++;
 	}
 	rvcontext.root = root;
@@ -1816,7 +1816,7 @@ pull_up_constant_function(PlannerInfo *root, Node *jtnode,
 	rvcontext.targetlist = list_make1(makeTargetEntry((Expr *) rtf->funcexpr,
 													  1,	/* resno */
 													  NULL, /* resname */
-													  false));	/* resjunk */
+													  NOT_JUNK));	/* resjunk */
 	rvcontext.target_rte = rte;
 
 	/*
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 9d46488ef7c..a15b9aca0af 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -177,7 +177,7 @@ preprocess_targetlist(PlannerInfo *root)
 
 				tle = makeTargetEntry((Expr *) var,
 									  list_length(tlist) + 1,
-									  NULL, true);
+									  NULL, JUNK_OTHER);
 				tlist = lappend(tlist, tle);
 			}
 			list_free(vars);
@@ -223,7 +223,7 @@ preprocess_targetlist(PlannerInfo *root)
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			tlist = lappend(tlist, tle);
 		}
 		if (rc->allMarkTypes & (1 << ROW_MARK_COPY))
@@ -232,12 +232,12 @@ preprocess_targetlist(PlannerInfo *root)
 			var = makeWholeRowVar(rt_fetch(rc->rti, range_table),
 								  rc->rti,
 								  0,
-								  false);
+								  NOT_JUNK);
 			snprintf(resname, sizeof(resname), "wholerow%u", rc->rowmarkId);
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			tlist = lappend(tlist, tle);
 		}
 
@@ -254,7 +254,7 @@ preprocess_targetlist(PlannerInfo *root)
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			tlist = lappend(tlist, tle);
 		}
 	}
@@ -290,7 +290,7 @@ preprocess_targetlist(PlannerInfo *root)
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(tlist) + 1,
 								  NULL,
-								  true);
+								  JUNK_OTHER);
 
 			tlist = lappend(tlist, tle);
 		}
@@ -442,7 +442,7 @@ expand_insert_targetlist(List *tlist, Relation rel)
 			new_tle = makeTargetEntry((Expr *) new_expr,
 									  attrno,
 									  pstrdup(NameStr(att_tup->attname)),
-									  false);
+									  NOT_JUNK);
 		}
 
 		new_tlist = lappend(new_tlist, new_tle);
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 8eaa734916d..7567e7eb9f0 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -1227,7 +1227,7 @@ generate_setop_tlist(List *colTypes, List *colCollations,
 		tle = makeTargetEntry((Expr *) expr,
 							  (AttrNumber) resno++,
 							  pstrdup(reftle->resname),
-							  false);
+							  NOT_JUNK);
 
 		/*
 		 * By convention, all non-resjunk columns in a setop tree have
@@ -1253,7 +1253,7 @@ generate_setop_tlist(List *colTypes, List *colCollations,
 		tle = makeTargetEntry((Expr *) expr,
 							  (AttrNumber) resno++,
 							  pstrdup("flag"),
-							  true);
+							  JUNK_OTHER);
 		tlist = lappend(tlist, tle);
 		*trivial_tlist = false; /* the extra entry makes it not trivial */
 	}
@@ -1361,7 +1361,7 @@ generate_append_tlist(List *colTypes, List *colCollations,
 		tle = makeTargetEntry((Expr *) expr,
 							  (AttrNumber) resno++,
 							  pstrdup(reftle->resname),
-							  false);
+							  NOT_JUNK);
 
 		/*
 		 * By convention, all non-resjunk columns in a setop tree have
@@ -1386,7 +1386,7 @@ generate_append_tlist(List *colTypes, List *colCollations,
 		tle = makeTargetEntry((Expr *) expr,
 							  (AttrNumber) resno++,
 							  pstrdup("flag"),
-							  true);
+							  JUNK_OTHER);
 		tlist = lappend(tlist, tle);
 	}
 
diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c
index f456b3b0a44..4c33ebc7f51 100644
--- a/src/backend/optimizer/util/appendinfo.c
+++ b/src/backend/optimizer/util/appendinfo.c
@@ -810,7 +810,7 @@ add_row_identity_var(PlannerInfo *root, Var *orig_var,
 		tle = makeTargetEntry((Expr *) orig_var,
 							  list_length(root->processed_tlist) + 1,
 							  pstrdup(rowid_name),
-							  true);
+							  JUNK_OTHER);
 		root->processed_tlist = lappend(root->processed_tlist, tle);
 		return;
 	}
@@ -869,7 +869,7 @@ add_row_identity_var(PlannerInfo *root, Var *orig_var,
 	tle = makeTargetEntry((Expr *) rowid_var,
 						  list_length(root->processed_tlist) + 1,
 						  pstrdup(rowid_name),
-						  true);
+						  JUNK_OTHER);
 	root->processed_tlist = lappend(root->processed_tlist, tle);
 }
 
diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c
index f9d3ff1e7ac..8b8d7470711 100644
--- a/src/backend/optimizer/util/inherit.c
+++ b/src/backend/optimizer/util/inherit.c
@@ -260,7 +260,7 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel,
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(root->processed_tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			root->processed_tlist = lappend(root->processed_tlist, tle);
 			newvars = lappend(newvars, var);
 		}
@@ -277,7 +277,7 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel,
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(root->processed_tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			root->processed_tlist = lappend(root->processed_tlist, tle);
 			newvars = lappend(newvars, var);
 		}
@@ -295,7 +295,7 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel,
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(root->processed_tlist) + 1,
 								  pstrdup(resname),
-								  true);
+								  JUNK_OTHER);
 			root->processed_tlist = lappend(root->processed_tlist, tle);
 			newvars = lappend(newvars, var);
 		}
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 0e35b9d0ab9..219040b52f0 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1759,7 +1759,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
 								makeTargetEntry((Expr *) var,
 												attrno,
 												NULL,
-												false));
+												NOT_JUNK));
 			}
 
 			table_close(relation, NoLock);
@@ -1812,7 +1812,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
 								makeTargetEntry((Expr *) var,
 												var->varattno,
 												NULL,
-												false));
+												NOT_JUNK));
 			}
 			break;
 
@@ -1881,7 +1881,7 @@ build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
 						makeTargetEntry(indexvar,
 										i + 1,
 										NULL,
-										false));
+										NOT_JUNK));
 	}
 	if (indexpr_item != NULL)
 		elog(ERROR, "wrong number of index expressions");
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index c672b338c0d..a2a343e960e 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -145,7 +145,7 @@ add_to_flat_tlist(List *tlist, List *exprs)
 			tle = makeTargetEntry(copyObject(expr), /* copy needed?? */
 								  next_resno++,
 								  NULL,
-								  false);
+								  NOT_JUNK);
 			tlist = lappend(tlist, tle);
 		}
 	}
@@ -636,7 +636,7 @@ make_tlist_from_pathtarget(PathTarget *target)
 		tle = makeTargetEntry(expr,
 							  i + 1,
 							  NULL,
-							  false);
+							  NOT_JUNK);
 		if (target->sortgrouprefs)
 			tle->ressortgroupref = target->sortgrouprefs[i];
 		tlist = lappend(tlist, tle);
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 7a1dfb63645..9e032d917f7 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -953,7 +953,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
 		tle = makeTargetEntry(expr,
 							  attr_num,
 							  col->name,
-							  false);
+							  NOT_JUNK);
 		qry->targetList = lappend(qry->targetList, tle);
 
 		perminfo->insertedCols = bms_add_member(perminfo->insertedCols,
@@ -1250,7 +1250,7 @@ BuildOnConflictExcludedTargetlist(Relation targetrel,
 		te = makeTargetEntry((Expr *) var,
 							 attno + 1,
 							 name,
-							 false);
+							 NOT_JUNK);
 
 		result = lappend(result, te);
 	}
@@ -1265,7 +1265,8 @@ BuildOnConflictExcludedTargetlist(Relation targetrel,
 	var = makeVar(exclRelIndex, InvalidAttrNumber,
 				  targetrel->rd_rel->reltype,
 				  -1, InvalidOid, 0);
-	te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true);
+	// XXX: right junk kind?
+	te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, JUNK_OTHER);
 	result = lappend(result, te);
 
 	return result;
@@ -1832,7 +1833,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 		tle = makeTargetEntry((Expr *) var,
 							  (AttrNumber) pstate->p_next_resno++,
 							  colName,
-							  false);
+							  NOT_JUNK);
 		qry->targetList = lappend(qry->targetList, tle);
 		targetvars = lappend(targetvars, var);
 		targetnames = lappend(targetnames, makeString(colName));
@@ -2306,7 +2307,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt,
 				restle = makeTargetEntry((Expr *) rescolnode,
 										 0, /* no need to set resno */
 										 NULL,
-										 false);
+										 NOT_JUNK);
 				*targetlist = lappend(*targetlist, restle);
 			}
 		}
@@ -2360,7 +2361,7 @@ determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist)
 		tle = makeTargetEntry(nrtle->expr,
 							  next_resno++,
 							  colName,
-							  false);
+							  NOT_JUNK);
 		targetList = lappend(targetList, tle);
 	}
 
@@ -2382,7 +2383,7 @@ transformReturnStmt(ParseState *pstate, ReturnStmt *stmt)
 	qry->isReturn = true;
 
 	qry->targetList = list_make1(makeTargetEntry((Expr *) transformExpr(pstate, stmt->returnval, EXPR_KIND_SELECT_TARGET),
-												 1, NULL, false));
+												 1, NULL, NOT_JUNK));
 
 	if (pstate->p_resolve_unknowns)
 		resolveTargetListUnknowns(pstate, qry->targetList);
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 9bbad33fbdb..92559a5cd72 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -139,7 +139,7 @@ transformAggregateCall(ParseState *pstate, Aggref *agg,
 			TargetEntry *tle;
 
 			/* We don't bother to assign column names to the entries */
-			tle = makeTargetEntry(arg, attno++, NULL, false);
+			tle = makeTargetEntry(arg, attno++, NULL, NOT_JUNK);
 			tlist = lappend(tlist, tle);
 
 			torder = addTargetToSortList(pstate, tle,
@@ -163,7 +163,7 @@ transformAggregateCall(ParseState *pstate, Aggref *agg,
 			TargetEntry *tle;
 
 			/* We don't bother to assign column names to the entries */
-			tle = makeTargetEntry(arg, attno++, NULL, false);
+			tle = makeTargetEntry(arg, attno++, NULL, NOT_JUNK);
 			tlist = lappend(tlist, tle);
 		}
 
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 334b9b42bd5..9f33ce97cd0 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -2201,11 +2201,11 @@ findTargetlistEntrySQL99(ParseState *pstate, Node *node, List **tlist,
 
 	/*
 	 * If no matches, construct a new target entry which is appended to the
-	 * end of the target list.  This target is given resjunk = true so that it
+	 * end of the target list.  This target is given resjunk = true XXX so that it
 	 * will not be projected into the final tuple.
 	 */
 	target_result = transformTargetEntry(pstate, node, expr, exprKind,
-										 NULL, true);
+										 NULL, JUNK_SORT_GROUP_COL);
 
 	*tlist = lappend(*tlist, target_result);
 
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 64c582c344c..b04586345f7 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -1480,7 +1480,7 @@ transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
 			 * about selecting a resno for it; transformUpdateStmt will do
 			 * that.
 			 */
-			tle = makeTargetEntry((Expr *) sublink, 0, NULL, true);
+			tle = makeTargetEntry((Expr *) sublink, 0, NULL, JUNK_OTHER);
 			pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
 												  tle);
 
@@ -1509,7 +1509,7 @@ transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref)
 			 * Temporarily append it to p_multiassign_exprs, so we can get it
 			 * back when we come back here for additional columns.
 			 */
-			tle = makeTargetEntry((Expr *) rexpr, 0, NULL, true);
+			tle = makeTargetEntry((Expr *) rexpr, 0, NULL, JUNK_OTHER);
 			pstate->p_multiassign_exprs = lappend(pstate->p_multiassign_exprs,
 												  tle);
 		}
diff --git a/src/backend/parser/parse_merge.c b/src/backend/parser/parse_merge.c
index 91b1156d991..1c7456c6f7f 100644
--- a/src/backend/parser/parse_merge.c
+++ b/src/backend/parser/parse_merge.c
@@ -358,7 +358,7 @@ transformMergeStmt(ParseState *pstate, MergeStmt *stmt)
 						tle = makeTargetEntry(expr,
 											  attr_num,
 											  col->name,
-											  false);
+											  NOT_JUNK);
 						action->targetList = lappend(action->targetList, tle);
 
 						perminfo->insertedCols =
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 864ea9b0d5d..77885e2b4e5 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -3221,7 +3221,7 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem,
 		te = makeTargetEntry((Expr *) varnode,
 							 (AttrNumber) pstate->p_next_resno++,
 							 label,
-							 false);
+							 NOT_JUNK);
 		te_list = lappend(te_list, te);
 
 		if (require_col_privs)
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 3bc62ac3ba5..3d684506049 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -78,7 +78,7 @@ transformTargetEntry(ParseState *pstate,
 					 Node *expr,
 					 ParseExprKind exprKind,
 					 char *colname,
-					 bool resjunk)
+					 JunkKind resjunk)
 {
 	/* Transform the node if caller didn't do it already */
 	if (expr == NULL)
@@ -184,7 +184,7 @@ transformTargetList(ParseState *pstate, List *targetlist,
 												NULL,
 												exprKind,
 												res->name,
-												false));
+												NOT_JUNK));
 	}
 
 	/*
@@ -1480,7 +1480,7 @@ ExpandRowReference(ParseState *pstate, Node *expr,
 			te = makeTargetEntry((Expr *) fselect,
 								 (AttrNumber) pstate->p_next_resno++,
 								 pstrdup(NameStr(att->attname)),
-								 false);
+								 NOT_JUNK);
 			result = lappend(result, te);
 		}
 		else
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 41a362310a8..ee6cd97f6a3 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -1020,7 +1020,7 @@ rewriteTargetListIU(List *targetList,
 				new_tle = makeTargetEntry((Expr *) new_expr,
 										  attrno,
 										  pstrdup(NameStr(att_tup->attname)),
-										  false);
+										  NOT_JUNK);
 		}
 
 		if (new_tle)
@@ -1782,7 +1782,7 @@ ApplyRetrieveRule(Query *parsetree,
 			tle = makeTargetEntry((Expr *) var,
 								  list_length(parsetree->targetList) + 1,
 								  pstrdup("wholerow"),
-								  true);
+								  JUNK_OTHER);
 
 			parsetree->targetList = lappend(parsetree->targetList, tle);
 
diff --git a/src/backend/rewrite/rewriteSearchCycle.c b/src/backend/rewrite/rewriteSearchCycle.c
index 428a98ef2bb..767c7fe5b38 100644
--- a/src/backend/rewrite/rewriteSearchCycle.c
+++ b/src/backend/rewrite/rewriteSearchCycle.c
@@ -306,7 +306,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 					  list_nth_int(cte->ctecoltypmods, i),
 					  list_nth_oid(cte->ctecolcollations, i),
 					  0);
-		tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), false);
+		tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), NOT_JUNK);
 		tle->resorigtbl = list_nth_node(TargetEntry, rte1->subquery->targetList, i)->resorigtbl;
 		tle->resorigcol = list_nth_node(TargetEntry, rte1->subquery->targetList, i)->resorigcol;
 		newq1->targetList = lappend(newq1->targetList, tle);
@@ -330,7 +330,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry(texpr,
 							  list_length(newq1->targetList) + 1,
 							  cte->search_clause->search_seq_column,
-							  false);
+							  NOT_JUNK);
 		newq1->targetList = lappend(newq1->targetList, tle);
 	}
 	if (cte->cycle_clause)
@@ -338,13 +338,13 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry((Expr *) cte->cycle_clause->cycle_mark_default,
 							  list_length(newq1->targetList) + 1,
 							  cte->cycle_clause->cycle_mark_column,
-							  false);
+							  NOT_JUNK);
 		newq1->targetList = lappend(newq1->targetList, tle);
 		cycle_col_rowexpr = make_path_rowexpr(cte, cte->cycle_clause->cycle_col_list);
 		tle = makeTargetEntry(make_path_initial_array(cycle_col_rowexpr),
 							  list_length(newq1->targetList) + 1,
 							  cte->cycle_clause->cycle_path_column,
-							  false);
+							  NOT_JUNK);
 		newq1->targetList = lappend(newq1->targetList, tle);
 	}
 
@@ -426,7 +426,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry((Expr *) var,
 							  list_length(newsubquery->targetList) + 1,
 							  cte->search_clause->search_seq_column,
-							  false);
+							  NOT_JUNK);
 		newsubquery->targetList = lappend(newsubquery->targetList, tle);
 	}
 	if (cte->cycle_clause)
@@ -441,7 +441,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry((Expr *) var,
 							  list_length(newsubquery->targetList) + 1,
 							  cte->cycle_clause->cycle_mark_column,
-							  false);
+							  NOT_JUNK);
 		newsubquery->targetList = lappend(newsubquery->targetList, tle);
 
 		/* ctename.cpa */
@@ -450,7 +450,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry((Expr *) var,
 							  list_length(newsubquery->targetList) + 1,
 							  cte->cycle_clause->cycle_path_column,
-							  false);
+							  NOT_JUNK);
 		newsubquery->targetList = lappend(newsubquery->targetList, tle);
 	}
 
@@ -494,7 +494,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 					  list_nth_int(cte->ctecoltypmods, i),
 					  list_nth_oid(cte->ctecolcollations, i),
 					  0);
-		tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), false);
+		tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), NOT_JUNK);
 		tle->resorigtbl = list_nth_node(TargetEntry, rte2->subquery->targetList, i)->resorigtbl;
 		tle->resorigcol = list_nth_node(TargetEntry, rte2->subquery->targetList, i)->resorigcol;
 		newq2->targetList = lappend(newq2->targetList, tle);
@@ -537,7 +537,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry(texpr,
 							  list_length(newq2->targetList) + 1,
 							  cte->search_clause->search_seq_column,
-							  false);
+							  NOT_JUNK);
 		newq2->targetList = lappend(newq2->targetList, tle);
 	}
 
@@ -572,7 +572,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry((Expr *) caseexpr,
 							  list_length(newq2->targetList) + 1,
 							  cte->cycle_clause->cycle_mark_column,
-							  false);
+							  NOT_JUNK);
 		newq2->targetList = lappend(newq2->targetList, tle);
 
 		/*
@@ -581,7 +581,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 		tle = makeTargetEntry(make_path_cat_expr(cycle_col_rowexpr, cpa_attno),
 							  list_length(newq2->targetList) + 1,
 							  cte->cycle_clause->cycle_path_column,
-							  false);
+							  NOT_JUNK);
 		newq2->targetList = lappend(newq2->targetList, tle);
 	}
 
@@ -636,7 +636,7 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 																		search_seq_type, -1, InvalidOid, 0),
 													   list_length(ctequery->targetList) + 1,
 													   cte->search_clause->search_seq_column,
-													   false));
+													   NOT_JUNK));
 	}
 	if (cte->cycle_clause)
 	{
@@ -647,13 +647,13 @@ rewriteSearchAndCycle(CommonTableExpr *cte)
 																		cte->cycle_clause->cycle_mark_collation, 0),
 													   list_length(ctequery->targetList) + 1,
 													   cte->cycle_clause->cycle_mark_column,
-													   false));
+													   NOT_JUNK));
 		ctequery->targetList = lappend(ctequery->targetList,
 									   makeTargetEntry((Expr *) makeVar(1, cpa_attno,
 																		RECORDARRAYOID, -1, InvalidOid, 0),
 													   list_length(ctequery->targetList) + 1,
 													   cte->cycle_clause->cycle_path_column,
-													   false));
+													   NOT_JUNK));
 	}
 
 	/*
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index aca0ee54dfa..56115960279 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -42,7 +42,7 @@ extern Var *makeWholeRowVar(RangeTblEntry *rte,
 extern TargetEntry *makeTargetEntry(Expr *expr,
 									AttrNumber resno,
 									char *resname,
-									bool resjunk);
+									JunkKind junk_kind);
 
 extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle);
 
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index bb930afb521..ba7c0e1642d 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -21,6 +21,24 @@
 #include "nodes/bitmapset.h"
 #include "nodes/pg_list.h"
 
+/*
+ * These are numbered so that to check if a column is junk or not, you can
+ * use "if (resjunk)" or "if (!resjunk)".
+ */
+typedef enum JunkKind
+{
+	/* Regular column, not junk */
+	NOT_JUNK = 0,
+
+	/* An ORDER or GROUP BY column. These are left out from the final plan. */	
+	JUNK_SORT_GROUP_COL = 1,
+
+	/* Other junk column used only in planner. Also left out from final plan. */	
+	JUNK_PLANNER_ONLY,
+	
+	/* Other junk column, needs to be preserved in the final plan. */
+	JUNK_OTHER,
+} JunkKind;
 
 typedef enum OverridingKind
 {
@@ -1908,13 +1926,14 @@ typedef struct InferenceElem
  * simple reference to a column of a base table (or view).  If it is not
  * a simple reference, these fields are zeroes.
  *
- * If resjunk is true then the column is a working column (such as a sort key)
+ * If XXX resjunk is true then the column is a working column (such as a sort key)
  * that should be removed from the final output of the query.  Resjunk columns
  * must have resnos that cannot duplicate any regular column's resno.  Also
  * note that there are places that assume resjunk columns come after non-junk
  * columns.
  *--------------------
  */
+
 typedef struct TargetEntry
 {
 	Expr		xpr;
@@ -1931,7 +1950,7 @@ typedef struct TargetEntry
 	/* column's number in source table */
 	AttrNumber	resorigcol pg_node_attr(query_jumble_ignore);
 	/* set to true to eliminate the attribute from final target list */
-	bool		resjunk pg_node_attr(query_jumble_ignore);
+	JunkKind	resjunk pg_node_attr(query_jumble_ignore);
 } TargetEntry;
 
 
diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h
index d84c311bbca..92a78808a77 100644
--- a/src/include/parser/parse_target.h
+++ b/src/include/parser/parse_target.h
@@ -25,7 +25,7 @@ extern void resolveTargetListUnknowns(ParseState *pstate, List *targetlist);
 extern void markTargetListOrigins(ParseState *pstate, List *targetlist);
 extern TargetEntry *transformTargetEntry(ParseState *pstate,
 										 Node *node, Node *expr, ParseExprKind exprKind,
-										 char *colname, bool resjunk);
+										 char *colname, JunkKind resjunk);
 extern Expr *transformAssignedExpr(ParseState *pstate, Expr *expr,
 								   ParseExprKind exprKind,
 								   const char *colname,
-- 
2.39.2

