in ext/pg_query/pg_query_deparse.c [2967:3037]
static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
{
ListCell *lc;
bool need_alias_parens = join_expr->alias != NULL;
bool need_rarg_parens = IsA(join_expr->rarg, JoinExpr) && castNode(JoinExpr, join_expr->rarg)->alias == NULL;
if (need_alias_parens)
appendStringInfoChar(str, '(');
deparseTableRef(str, join_expr->larg);
appendStringInfoChar(str, ' ');
if (join_expr->isNatural)
appendStringInfoString(str, "NATURAL ");
switch (join_expr->jointype)
{
case JOIN_INNER: /* matching tuple pairs only */
if (!join_expr->isNatural && join_expr->quals == NULL && list_length(join_expr->usingClause) == 0)
appendStringInfoString(str, "CROSS ");
break;
case JOIN_LEFT: /* pairs + unmatched LHS tuples */
appendStringInfoString(str, "LEFT ");
break;
case JOIN_FULL: /* pairs + unmatched LHS + unmatched RHS */
appendStringInfoString(str, "FULL ");
break;
case JOIN_RIGHT: /* pairs + unmatched RHS tuples */
appendStringInfoString(str, "RIGHT ");
break;
case JOIN_SEMI:
case JOIN_ANTI:
case JOIN_UNIQUE_OUTER:
case JOIN_UNIQUE_INNER:
// Only used by the planner/executor, not seen in parser output
Assert(false);
break;
}
appendStringInfoString(str, "JOIN ");
if (need_rarg_parens)
appendStringInfoChar(str, '(');
deparseTableRef(str, join_expr->rarg);
if (need_rarg_parens)
appendStringInfoChar(str, ')');
appendStringInfoChar(str, ' ');
if (join_expr->quals != NULL)
{
appendStringInfoString(str, "ON ");
deparseExpr(str, join_expr->quals);
appendStringInfoChar(str, ' ');
}
if (list_length(join_expr->usingClause) > 0)
{
appendStringInfoString(str, "USING (");
deparseNameList(str, join_expr->usingClause);
appendStringInfoString(str, ") ");
}
if (need_alias_parens)
appendStringInfoString(str, ") ");
if (join_expr->alias != NULL)
deparseAlias(str, join_expr->alias);
removeTrailingSpace(str);
}