Patch applied, modified by Tom and myself.

---------------------------------------------------------------------------

Andreas Pflug wrote:
> Bruce Momjian wrote:
> 
> >Andreas, looks good, but I need a diff -c, context diff.
> >
> >  
> >
> Hi Bruce,
> I intentionally only attached only non-context diffs because the patch 
> is about 50 % size of the original file. Now, here's the same as context 
> diff.
> 
> Regards,
> Andreas

> Index: pg_proc.h
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v
> retrieving revision 1.309
> diff -c -r1.309 pg_proc.h
> *** pg_proc.h 1 Jul 2003 00:04:38 -0000       1.309
> --- pg_proc.h 22 Jul 2003 12:52:07 -0000
> ***************
> *** 3405,3410 ****
> --- 3405,3424 ----
>   DATA(insert OID = 2503 (  anyarray_send                PGNSP PGUID 12 f f t f s 1 
> 17 "2277"  anyarray_send - _null_ ));
>   DESCR("I/O");
>   
> + /* System-view support functions with pretty-print option */
> + DATA(insert OID = 2504 (  pg_get_ruledef       PGNSP PGUID 12 f f t f s 2 25 "26 
> 16"  pg_get_ruledef - _null_ ));
> + DESCR("source text of a rule with pretty-print option");
> + DATA(insert OID = 2505 (  pg_get_viewdef       PGNSP PGUID 12 f f t f s 2 25 "25 
> 16"  pg_get_viewdef_name - _null_ ));
> + DESCR("select statement of a view with pretty-print option");
> + DATA(insert OID = 2506 (  pg_get_viewdef       PGNSP PGUID 12 f f t f s 2 25 "26 
> 16"  pg_get_viewdef - _null_ ));
> + DESCR("select statement of a view with pretty-print option");
> + DATA(insert OID = 2507 (  pg_get_indexdef      PGNSP PGUID 12 f f t f s 3 25 "26 
> 23 16"  pg_get_indexdef - _null_ ));
> + DESCR("index description (full create statement or single expression) with 
> pretty-print option");
> + DATA(insert OID = 2508 (  pg_get_constraintdef PGNSP PGUID 12 f f t f s 2 25 "26 
> 16"  pg_get_constraintdef - _null_ ));
> + DESCR("constraint description with pretty-print option");
> + DATA(insert OID = 2509 (  pg_get_expr                  PGNSP PGUID 12 f f t f s 3 
> 25 "25 26 16"     pg_get_expr - _null_ ));
> + DESCR("deparse an encoded expression with pretty-print option");
> + 
>   
>   /*
>    * Symbolic values for provolatile column: these indicate whether the result

> Index: ruleutils.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/ruleutils.c,v
> retrieving revision 1.145
> diff -c -r1.145 ruleutils.c
> *** ruleutils.c       4 Jul 2003 02:51:34 -0000       1.145
> --- ruleutils.c       22 Jul 2003 12:54:10 -0000
> ***************
> *** 71,76 ****
> --- 71,95 ----
>   #include "utils/lsyscache.h"
>   
>   
> + /******************************
> +  * Pretty formatting constants
> +  ******************************/
> + 
> + /* Indent counts */
> + #define PRETTYINDENT_STD        8
> + #define PRETTYINDENT_JOIN      13
> + #define PRETTYINDENT_JOIN_ON    (PRETTYINDENT_JOIN-PRETTYINDENT_STD)
> + #define PRETTYINDENT_VAR        4
> + 
> + /* Pretty flags */
> + #define PRETTYFLAG_PAREN        1
> + #define PRETTYFLAG_INDENT       2
> + 
> + /* macro to test if pretty action needed */
> + #define PRETTY_PAREN(context)   (context->prettyFlags & PRETTYFLAG_PAREN)
> + #define PRETTY_INDENT(context)  (context->prettyFlags & PRETTYFLAG_INDENT)
> + 
> + 
>   /* ----------
>    * Local data types
>    * ----------
> ***************
> *** 81,86 ****
> --- 100,107 ----
>   {
>       StringInfo      buf;                    /* output buffer to append to */
>       List       *namespaces;         /* List of deparse_namespace nodes */
> +         int             prettyFlags;            /* enabling/disabling of 
> pretty-print functions */
> +         int             indentLevel;            /* for prettyPrint, current space 
> indents are counted */
>       bool            varprefix;              /* TRUE to print prefixes on Vars */
>   } deparse_context;
>   
> ***************
> *** 123,135 ****
>    * as a parameter, and append their text output to its contents.
>    * ----------
>    */
> ! static text *pg_do_getviewdef(Oid viewoid);
>   static void decompile_column_index_array(Datum column_index_array, Oid relId,
>                                                        StringInfo buf);
> ! static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc);
> ! static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc);
>   static void get_query_def(Query *query, StringInfo buf, List *parentnamespace,
> !                       TupleDesc resultDesc);
>   static void get_select_query_def(Query *query, deparse_context *context,
>                                        TupleDesc resultDesc);
>   static void get_insert_query_def(Query *query, deparse_context *context);
> --- 144,162 ----
>    * as a parameter, and append their text output to its contents.
>    * ----------
>    */
> ! static char *get_simple_binary_op_name(OpExpr *expr);
> ! static void appendStringInfoSpace(StringInfo buf, int count);
> ! static void appendContextKeyword(deparse_context *context, char *str, int 
> indentBefore, int indentAfter, int indentPlus);
> ! static char *deparse_expression_pretty(Node *expr, List *dpcontext,
> !                       bool forceprefix, bool showimplicit, int prettyFlags, int 
> startIndent);
> ! static bool isSimpleNode(Node *node, Node *parentNode, int prettyFlags);
> ! static text *pg_do_getviewdef(Oid viewoid, int prettyFlags);
>   static void decompile_column_index_array(Datum column_index_array, Oid relId,
>                                                        StringInfo buf);
> ! static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int 
> prettyFlags);
> ! static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int 
> prettyFlags);
>   static void get_query_def(Query *query, StringInfo buf, List *parentnamespace,
> !                       TupleDesc resultDesc, int prettyFlags, int startIndent);
>   static void get_select_query_def(Query *query, deparse_context *context,
>                                        TupleDesc resultDesc);
>   static void get_insert_query_def(Query *query, deparse_context *context);
> ***************
> *** 192,197 ****
> --- 219,225 ----
>       TupleDesc       rulettc;
>       StringInfoData buf;
>       int                     len;
> +     int             prettyFlags = !PG_ARGISNULL(1) && PG_GETARG_BOOL(1) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
>       /*
>        * Connect to SPI manager
> ***************
> *** 241,247 ****
>        * Get the rules definition and put it into executors memory
>        */
>       initStringInfo(&buf);
> !     make_ruledef(&buf, ruletup, rulettc);
>       len = buf.len + VARHDRSZ;
>       ruledef = SPI_palloc(len);
>       VARATT_SIZEP(ruledef) = len;
> --- 269,275 ----
>        * Get the rules definition and put it into executors memory
>        */
>       initStringInfo(&buf);
> !     make_ruledef(&buf, ruletup, rulettc, prettyFlags);
>       len = buf.len + VARHDRSZ;
>       ruledef = SPI_palloc(len);
>       VARATT_SIZEP(ruledef) = len;
> ***************
> *** 272,279 ****
>       /* By OID */
>       Oid                     viewoid = PG_GETARG_OID(0);
>       text       *ruledef;
>   
> !     ruledef = pg_do_getviewdef(viewoid);
>       PG_RETURN_TEXT_P(ruledef);
>   }
>   
> --- 300,308 ----
>       /* By OID */
>       Oid                     viewoid = PG_GETARG_OID(0);
>       text       *ruledef;
> +     int             prettyFlags = !PG_ARGISNULL(1) && PG_GETARG_BOOL(1) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
> !     ruledef = pg_do_getviewdef(viewoid, prettyFlags);
>       PG_RETURN_TEXT_P(ruledef);
>   }
>   
> ***************
> *** 285,296 ****
>       RangeVar   *viewrel;
>       Oid                     viewoid;
>       text       *ruledef;
>   
>       viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname,
>                                                                                      
>                           "get_viewdef"));
>       viewoid = RangeVarGetRelid(viewrel, false);
>   
> !     ruledef = pg_do_getviewdef(viewoid);
>       PG_RETURN_TEXT_P(ruledef);
>   }
>   
> --- 314,326 ----
>       RangeVar   *viewrel;
>       Oid                     viewoid;
>       text       *ruledef;
> +     int             prettyFlags = !PG_ARGISNULL(1) && PG_GETARG_BOOL(1) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
>       viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname,
>                                                                                      
>                           "get_viewdef"));
>       viewoid = RangeVarGetRelid(viewrel, false);
>   
> !     ruledef = pg_do_getviewdef(viewoid, prettyFlags);
>       PG_RETURN_TEXT_P(ruledef);
>   }
>   
> ***************
> *** 298,304 ****
>    * Common code for by-OID and by-name variants of pg_get_viewdef
>    */
>   static text *
> ! pg_do_getviewdef(Oid viewoid)
>   {
>       text       *ruledef;
>       Datum           args[2];
> --- 328,334 ----
>    * Common code for by-OID and by-name variants of pg_get_viewdef
>    */
>   static text *
> ! pg_do_getviewdef(Oid viewoid, int prettyFlags)
>   {
>       text       *ruledef;
>       Datum           args[2];
> ***************
> *** 353,359 ****
>                */
>               ruletup = SPI_tuptable->vals[0];
>               rulettc = SPI_tuptable->tupdesc;
> !             make_viewdef(&buf, ruletup, rulettc);
>       }
>       len = buf.len + VARHDRSZ;
>       ruledef = SPI_palloc(len);
> --- 383,389 ----
>                */
>               ruletup = SPI_tuptable->vals[0];
>               rulettc = SPI_tuptable->tupdesc;
> !             make_viewdef(&buf, ruletup, rulettc, prettyFlags);
>       }
>       len = buf.len + VARHDRSZ;
>       ruledef = SPI_palloc(len);
> ***************
> *** 544,549 ****
> --- 574,581 ----
>       StringInfoData buf;
>       char       *str;
>       char       *sep;
> +     int        colno = PG_ARGISNULL(1) ? 0 : PG_GETARG_INT32(1);
> +     int        prettyFlags = !PG_ARGISNULL(2) && PG_GETARG_BOOL(2) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
>       /*
>        * Fetch the pg_index tuple by the Oid of the index
> ***************
> *** 582,587 ****
> --- 614,621 ----
>        * Get the index expressions, if any.  (NOTE: we do not use the relcache
>        * versions of the expressions and predicate, because we want to display
>        * non-const-folded expressions.)
> +          * if colno == 0, we want a complete index definition.
> +          * if colno > 0, we only want the nth expression.
>        */
>       if (!heap_attisnull(ht_idx, Anum_pg_index_indexprs))
>       {
> ***************
> *** 607,613 ****
>        * never be schema-qualified, but the indexed rel's name may be.
>        */
>       initStringInfo(&buf);
> !     appendStringInfo(&buf, "CREATE %sINDEX %s ON %s USING %s (",
>                                        idxrec->indisunique ? "UNIQUE " : "",
>                                        quote_identifier(NameStr(idxrelrec->relname)),
>                                        generate_relation_name(indrelid),
> --- 641,649 ----
>        * never be schema-qualified, but the indexed rel's name may be.
>        */
>       initStringInfo(&buf);
> ! 
> !     if (!colno)
> !         appendStringInfo(&buf, "CREATE %sINDEX %s ON %s USING %s (",
>                                        idxrec->indisunique ? "UNIQUE " : "",
>                                        quote_identifier(NameStr(idxrelrec->relname)),
>                                        generate_relation_name(indrelid),
> ***************
> *** 621,627 ****
>       {
>               AttrNumber      attnum = idxrec->indkey[keyno];
>   
> !             appendStringInfo(&buf, sep);
>               sep = ", ";
>   
>               if (attnum != 0)
> --- 657,664 ----
>       {
>               AttrNumber      attnum = idxrec->indkey[keyno];
>   
> !             if (!colno)
> !                 appendStringInfo(&buf, sep);
>               sep = ", ";
>   
>               if (attnum != 0)
> ***************
> *** 630,636 ****
>                       char       *attname;
>   
>                       attname = get_relid_attribute_name(indrelid, attnum);
> !                     appendStringInfo(&buf, "%s", quote_identifier(attname));
>                       keycoltype = get_atttype(indrelid, attnum);
>               }
>               else
> --- 667,674 ----
>                       char       *attname;
>   
>                       attname = get_relid_attribute_name(indrelid, attnum);
> !                     if (!colno || colno == keyno+1)
> !                         appendStringInfo(&buf, "%s", quote_identifier(attname));
>                       keycoltype = get_atttype(indrelid, attnum);
>               }
>               else
> ***************
> *** 643,672 ****
>                       indexkey = (Node *) lfirst(indexprs);
>                       indexprs = lnext(indexprs);
>                       /* Deparse */
> !                     str = deparse_expression(indexkey, context, false, false);
> !                     /* Need parens if it's not a bare function call */
> !                     if (indexkey && IsA(indexkey, FuncExpr) &&
>                               ((FuncExpr *) indexkey)->funcformat == 
> COERCE_EXPLICIT_CALL)
>                               appendStringInfo(&buf, "%s", str);
> !                     else
>                               appendStringInfo(&buf, "(%s)", str);
>                       keycoltype = exprType(indexkey);
>               }
>   
>               /*
>                * Add the operator class name
>                */
> !             get_opclass_name(idxrec->indclass[keyno], keycoltype,
>                                                &buf);
>       }
>   
> !     appendStringInfoChar(&buf, ')');
> ! 
> !     /*
> !      * If it's a partial index, decompile and append the predicate
> !      */
> !     if (!heap_attisnull(ht_idx, Anum_pg_index_indpred))
>       {
>               Node       *node;
>               Datum           predDatum;
>               bool            isnull;
> --- 681,716 ----
>                       indexkey = (Node *) lfirst(indexprs);
>                       indexprs = lnext(indexprs);
>                       /* Deparse */
> !                     str = deparse_expression_pretty(indexkey, context, false, 
> false, prettyFlags, 0);
> !                     if (!colno || colno == keyno+1)
> !                     {
> !                         /* Need parens if it's not a bare function call */
> !                         if (indexkey && IsA(indexkey, FuncExpr) &&
>                               ((FuncExpr *) indexkey)->funcformat == 
> COERCE_EXPLICIT_CALL)
>                               appendStringInfo(&buf, "%s", str);
> !                         else
>                               appendStringInfo(&buf, "(%s)", str);
> +                     }
>                       keycoltype = exprType(indexkey);
>               }
>   
>               /*
>                * Add the operator class name
>                */
> !             if (!colno)
> !                 get_opclass_name(idxrec->indclass[keyno], keycoltype,
>                                                &buf);
>       }
>   
> !     if (!colno)
>       {
> +         appendStringInfoChar(&buf, ')');
> + 
> +         /*
> +          * If it's a partial index, decompile and append the predicate
> +          */
> +         if (!heap_attisnull(ht_idx, Anum_pg_index_indpred))
> +         {
>               Node       *node;
>               Datum           predDatum;
>               bool            isnull;
> ***************
> *** 689,698 ****
>               if (node && IsA(node, List))
>                       node = (Node *) make_ands_explicit((List *) node);
>               /* Deparse */
> !             str = deparse_expression(node, context, false, false);
>               appendStringInfo(&buf, " WHERE %s", str);
>       }
> - 
>       /*
>        * Create the result as a TEXT datum, and free working data
>        */
> --- 733,742 ----
>               if (node && IsA(node, List))
>                       node = (Node *) make_ands_explicit((List *) node);
>               /* Deparse */
> !             str = deparse_expression_pretty(node, context, false, false, 
> prettyFlags, 0);
>               appendStringInfo(&buf, " WHERE %s", str);
> +         }
>       }
>       /*
>        * Create the result as a TEXT datum, and free working data
>        */
> ***************
> *** 729,734 ****
> --- 773,779 ----
>       ScanKeyData skey[1];
>       HeapTuple       tup;
>       Form_pg_constraint conForm;
> +     int      prettyFlags = !PG_ARGISNULL(1) && PG_GETARG_BOOL(1) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
>       /*
>        * Fetch the pg_constraint row.  There's no syscache for pg_constraint
> ***************
> *** 934,940 ****
>                                       context = 
> deparse_context_for(get_typname(conForm->contypid),
>                                                                                      
>            InvalidOid);
>   
> !                             consrc = deparse_expression(expr, context, false, 
> false);
>   
>                               /* Append the constraint source */
>                               appendStringInfoString(&buf, consrc); 
> --- 979,985 ----
>                                       context = 
> deparse_context_for(get_typname(conForm->contypid),
>                                                                                      
>            InvalidOid);
>   
> !                             consrc = deparse_expression_pretty(expr, context, 
> false, false, prettyFlags, 0);
>   
>                               /* Append the constraint source */
>                               appendStringInfoString(&buf, consrc); 
> ***************
> *** 1018,1023 ****
> --- 1063,1069 ----
>       char       *exprstr;
>       char       *relname;
>       char       *str;
> +     int      prettyFlags = !PG_ARGISNULL(2) && PG_GETARG_BOOL(2) ? 
> PRETTYFLAG_PAREN|PRETTYFLAG_INDENT : 0;
>   
>       /* Get the name for the relation */
>       relname = get_rel_name(relid);
> ***************
> *** 1041,1047 ****
>   
>       /* Deparse */
>       context = deparse_context_for(relname, relid);
> !     str = deparse_expression(node, context, false, false);
>   
>       /* Pass the result back as TEXT */
>       result = DatumGetTextP(DirectFunctionCall1(textin,
> --- 1087,1093 ----
>   
>       /* Deparse */
>       context = deparse_context_for(relname, relid);
> !     str = deparse_expression_pretty(node, context, false, false, prettyFlags, 0);
>   
>       /* Pass the result back as TEXT */
>       result = DatumGetTextP(DirectFunctionCall1(textin,
> ***************
> *** 1090,1095 ****
> --- 1136,1152 ----
>   
>   /* ----------
>    * deparse_expression                       - General utility for deparsing 
> expressions
> +  * calls deparse_expression_pretty with all prettyPrinting disabled
> +  */
> + char *
> + deparse_expression(Node *expr, List *dpcontext,
> +                bool forceprefix, bool showimplicit)
> + {
> +     return deparse_expression_pretty(expr, dpcontext, forceprefix, showimplicit, 
> 0, 0);
> + }
> + 
> + /* ----------
> +  * deparse_expression_pretty                        - General utility for 
> deparsing expressions
>    *
>    * expr is the node tree to be deparsed.  It must be a transformed expression
>    * tree (ie, not the raw output of gram.y).
> ***************
> *** 1100,1112 ****
>    * forceprefix is TRUE to force all Vars to be prefixed with their table names.
>    *
>    * showimplicit is TRUE to force all implicit casts to be shown explicitly.
>    *
>    * The result is a palloc'd string.
>    * ----------
>    */
>   char *
> ! deparse_expression(Node *expr, List *dpcontext,
> !                                bool forceprefix, bool showimplicit)
>   {
>       StringInfoData buf;
>       deparse_context context;
> --- 1157,1171 ----
>    * forceprefix is TRUE to force all Vars to be prefixed with their table names.
>    *
>    * showimplicit is TRUE to force all implicit casts to be shown explicitly.
> +  * 
> +  * tries to pretty up the output according to prettyFlags
>    *
>    * The result is a palloc'd string.
>    * ----------
>    */
>   char *
> ! deparse_expression_pretty(Node *expr, List *dpcontext,
> !                                bool forceprefix, bool showimplicit, int 
> prettyFlags, int startIndent)
>   {
>       StringInfoData buf;
>       deparse_context context;
> ***************
> *** 1115,1120 ****
> --- 1174,1181 ----
>       context.buf = &buf;
>       context.namespaces = dpcontext;
>       context.varprefix = forceprefix;
> +     context.prettyFlags = prettyFlags;
> +     context.indentLevel = startIndent;
>   
>       get_rule_expr(expr, &context, showimplicit);
>   
> ***************
> *** 1267,1273 ****
>    * ----------
>    */
>   static void
> ! make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
>   {
>       char       *rulename;
>       char            ev_type;
> --- 1328,1334 ----
>    * ----------
>    */
>   static void
> ! make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags)
>   {
>       char       *rulename;
>       char            ev_type;
> ***************
> *** 1321,1329 ****
>       /*
>        * Build the rules definition text
>        */
> !     appendStringInfo(buf, "CREATE RULE %s AS ON ",
>                                        quote_identifier(rulename));
>   
>       /* The event the rule is fired for */
>       switch (ev_type)
>       {
> --- 1382,1395 ----
>       /*
>        * Build the rules definition text
>        */
> !     appendStringInfo(buf, "CREATE RULE %s AS",
>                                        quote_identifier(rulename));
>   
> +     if (prettyFlags & PRETTYFLAG_INDENT)
> +         appendStringInfoString(buf, "\n    ON ");
> +     else
> +         appendStringInfoString(buf, "ON ");
> + 
>       /* The event the rule is fired for */
>       switch (ev_type)
>       {
> ***************
> *** 1366,1371 ****
> --- 1432,1439 ----
>               deparse_context context;
>               deparse_namespace dpns;
>   
> +             if (prettyFlags & PRETTYFLAG_INDENT)
> +                 appendStringInfoString(buf, "\n  ");
>               appendStringInfo(buf, " WHERE ");
>   
>               qual = stringToNode(ev_qual);
> ***************
> *** 1387,1392 ****
> --- 1455,1462 ----
>               context.buf = buf;
>               context.namespaces = makeList1(&dpns);
>               context.varprefix = (length(query->rtable) != 1);
> +             context.prettyFlags = prettyFlags;
> +             context.indentLevel = PRETTYINDENT_STD;
>               dpns.rtable = query->rtable;
>               dpns.outer_varno = dpns.inner_varno = 0;
>               dpns.outer_rte = dpns.inner_rte = NULL;
> ***************
> *** 1410,1417 ****
>               foreach(action, actions)
>               {
>                       query = (Query *) lfirst(action);
> !                     get_query_def(query, buf, NIL, NULL);
> !                     appendStringInfo(buf, "; ");
>               }
>               appendStringInfo(buf, ");");
>       }
> --- 1480,1490 ----
>               foreach(action, actions)
>               {
>                       query = (Query *) lfirst(action);
> !                     get_query_def(query, buf, NIL, NULL, prettyFlags, 0);
> !                     if (prettyFlags)
> !                         appendStringInfo(buf, ";\n");
> !                     else
> !                         appendStringInfo(buf, "; ");
>               }
>               appendStringInfo(buf, ");");
>       }
> ***************
> *** 1424,1430 ****
>               Query      *query;
>   
>               query = (Query *) lfirst(actions);
> !             get_query_def(query, buf, NIL, NULL);
>               appendStringInfo(buf, ";");
>       }
>   }
> --- 1497,1503 ----
>               Query      *query;
>   
>               query = (Query *) lfirst(actions);
> !             get_query_def(query, buf, NIL, NULL, prettyFlags, 0);
>               appendStringInfo(buf, ";");
>       }
>   }
> ***************
> *** 1436,1442 ****
>    * ----------
>    */
>   static void
> ! make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
>   {
>       Query      *query;
>       char            ev_type;
> --- 1509,1515 ----
>    * ----------
>    */
>   static void
> ! make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, int prettyFlags)
>   {
>       Query      *query;
>       char            ev_type;
> ***************
> *** 1490,1496 ****
>   
>       ev_relation = heap_open(ev_class, AccessShareLock);
>   
> !     get_query_def(query, buf, NIL, RelationGetDescr(ev_relation));
>       appendStringInfo(buf, ";");
>   
>       heap_close(ev_relation, AccessShareLock);
> --- 1563,1569 ----
>   
>       ev_relation = heap_open(ev_class, AccessShareLock);
>   
> !     get_query_def(query, buf, NIL, RelationGetDescr(ev_relation), prettyFlags, 0);
>       appendStringInfo(buf, ";");
>   
>       heap_close(ev_relation, AccessShareLock);
> ***************
> *** 1506,1512 ****
>    */
>   static void
>   get_query_def(Query *query, StringInfo buf, List *parentnamespace,
> !                       TupleDesc resultDesc)
>   {
>       deparse_context context;
>       deparse_namespace dpns;
> --- 1579,1585 ----
>    */
>   static void
>   get_query_def(Query *query, StringInfo buf, List *parentnamespace,
> !                       TupleDesc resultDesc, int prettyFlags, int startIndent)
>   {
>       deparse_context context;
>       deparse_namespace dpns;
> ***************
> *** 1515,1520 ****
> --- 1588,1596 ----
>       context.namespaces = lcons(&dpns, parentnamespace);
>       context.varprefix = (parentnamespace != NIL ||
>                                                length(query->rtable) != 1);
> +     context.prettyFlags = prettyFlags;
> +     context.indentLevel = startIndent;
> + 
>       dpns.rtable = query->rtable;
>       dpns.outer_varno = dpns.inner_varno = 0;
>       dpns.outer_rte = dpns.inner_rte = NULL;
> ***************
> *** 1586,1592 ****
>       /* Add the ORDER BY clause if given */
>       if (query->sortClause != NIL)
>       {
> !             appendStringInfo(buf, " ORDER BY ");
>               sep = "";
>               foreach(l, query->sortClause)
>               {
> --- 1662,1668 ----
>       /* Add the ORDER BY clause if given */
>       if (query->sortClause != NIL)
>       {
> !             appendContextKeyword(context, " ORDER BY ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 1);
>               sep = "";
>               foreach(l, query->sortClause)
>               {
> ***************
> *** 1615,1626 ****
>       /* Add the LIMIT clause if given */
>       if (query->limitOffset != NULL)
>       {
> !             appendStringInfo(buf, " OFFSET ");
>               get_rule_expr(query->limitOffset, context, false);
>       }
>       if (query->limitCount != NULL)
>       {
> !             appendStringInfo(buf, " LIMIT ");
>               if (IsA(query->limitCount, Const) &&
>                       ((Const *) query->limitCount)->constisnull)
>                       appendStringInfo(buf, "ALL");
> --- 1691,1702 ----
>       /* Add the LIMIT clause if given */
>       if (query->limitOffset != NULL)
>       {
> !             appendContextKeyword(context, " OFFSET ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 0);
>               get_rule_expr(query->limitOffset, context, false);
>       }
>       if (query->limitCount != NULL)
>       {
> !             appendContextKeyword(context, " LIMIT ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 0);
>               if (IsA(query->limitCount, Const) &&
>                       ((Const *) query->limitCount)->constisnull)
>                       appendStringInfo(buf, "ALL");
> ***************
> *** 1641,1646 ****
> --- 1717,1727 ----
>       /*
>        * Build up the query string - first we say SELECT
>        */
> +     if (PRETTY_INDENT(context))
> +     {
> +         context->indentLevel += PRETTYINDENT_STD;
> +         appendStringInfoChar(buf, ' ');
> +     }
>       appendStringInfo(buf, "SELECT");
>   
>       /* Add the DISTINCT clause if given */
> ***************
> *** 1720,1733 ****
>       /* Add the WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendStringInfo(buf, " WHERE ");
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   
>       /* Add the GROUP BY clause if given */
>       if (query->groupClause != NULL)
>       {
> !             appendStringInfo(buf, " GROUP BY ");
>               sep = "";
>               foreach(l, query->groupClause)
>               {
> --- 1801,1814 ----
>       /* Add the WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendContextKeyword(context, " WHERE ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 1);
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   
>       /* Add the GROUP BY clause if given */
>       if (query->groupClause != NULL)
>       {
> !             appendContextKeyword(context, " GROUP BY ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 1);
>               sep = "";
>               foreach(l, query->groupClause)
>               {
> ***************
> *** 1743,1749 ****
>       /* Add the HAVING clause if given */
>       if (query->havingQual != NULL)
>       {
> !             appendStringInfo(buf, " HAVING ");
>               get_rule_expr(query->havingQual, context, false);
>       }
>   }
> --- 1824,1830 ----
>       /* Add the HAVING clause if given */
>       if (query->havingQual != NULL)
>       {
> !             appendContextKeyword(context, " HAVING ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 0);
>               get_rule_expr(query->havingQual, context, false);
>       }
>   }
> ***************
> *** 1761,1795 ****
>               Query      *subquery = rte->subquery;
>   
>               Assert(subquery != NULL);
> !             get_query_def(subquery, buf, context->namespaces, resultDesc);
>       }
>       else if (IsA(setOp, SetOperationStmt))
>       {
>               SetOperationStmt *op = (SetOperationStmt *) setOp;
>   
> -             appendStringInfo(buf, "((");
>               get_setop_query(op->larg, query, context, resultDesc);
>               switch (op->op)
>               {
>                       case SETOP_UNION:
> !                             appendStringInfo(buf, ") UNION ");
>                               break;
>                       case SETOP_INTERSECT:
> !                             appendStringInfo(buf, ") INTERSECT ");
>                               break;
>                       case SETOP_EXCEPT:
> !                             appendStringInfo(buf, ") EXCEPT ");
>                               break;
>                       default:
>                               elog(ERROR, "get_setop_query: unexpected set op %d",
>                                        (int) op->op);
>               }
>               if (op->all)
> !                     appendStringInfo(buf, "ALL (");
>               else
> !                     appendStringInfo(buf, "(");
>               get_setop_query(op->rarg, query, context, resultDesc);
> !             appendStringInfo(buf, "))");
>       }
>       else
>       {
> --- 1842,1905 ----
>               Query      *subquery = rte->subquery;
>   
>               Assert(subquery != NULL);
> !             get_query_def(subquery, buf, context->namespaces, resultDesc, 
> context->prettyFlags, context->indentLevel);
>       }
>       else if (IsA(setOp, SetOperationStmt))
>       {
>               SetOperationStmt *op = (SetOperationStmt *) setOp;
> +             bool need_paren=(PRETTY_PAREN(context) ? !IsA(op->rarg, RangeTblRef) : 
> true);
> + 
> +             if (!PRETTY_PAREN(context))
> +                 appendStringInfoString(buf, "((");
>   
>               get_setop_query(op->larg, query, context, resultDesc);
> + 
> +             if (!PRETTY_PAREN(context))
> +                 appendStringInfoChar(buf, ')');
> +             if (!PRETTY_INDENT(context))
> +                 appendStringInfoChar(buf, ' ');
>               switch (op->op)
>               {
>                       case SETOP_UNION:
> !                             appendContextKeyword(context, "UNION ", 
> -PRETTYINDENT_STD, 0, 0);
>                               break;
>                       case SETOP_INTERSECT:
> !                             appendContextKeyword(context, "INTERSECT ", 
> -PRETTYINDENT_STD, 0, 0);
>                               break;
>                       case SETOP_EXCEPT:
> !                             appendContextKeyword(context, "EXCEPT ", 
> -PRETTYINDENT_STD, 0, 0);
>                               break;
>                       default:
>                               elog(ERROR, "get_setop_query: unexpected set op %d",
>                                        (int) op->op);
>               }
>               if (op->all)
> !                     appendStringInfo(buf, "ALL ");
> ! 
> !             if (PRETTY_INDENT(context))
> !                 appendStringInfoChar(buf, '\n');
> ! 
> !             if (PRETTY_PAREN(context))
> !             {
> !                 if (need_paren)
> !                 {
> !                     appendStringInfoChar(buf, '(');
> !                     if (PRETTY_INDENT(context))
> !                         appendStringInfoChar(buf, '\n');
> !                 }
> !             }
>               else
> !                 appendStringInfoChar(buf, '(');
> ! 
>               get_setop_query(op->rarg, query, context, resultDesc);
> ! 
> !             if (PRETTY_PAREN(context))
> !             {
> !                 if (need_paren)
> !                     appendStringInfoChar(buf, ')');
> !             }
> !             else
> !                 appendStringInfoString(buf, "))");
>       }
>       else
>       {
> ***************
> *** 1862,1867 ****
> --- 1972,1983 ----
>        */
>       rte = rt_fetch(query->resultRelation, query->rtable);
>       Assert(rte->rtekind == RTE_RELATION);
> + 
> +     if (PRETTY_INDENT(context))
> +     {
> +         context->indentLevel += PRETTYINDENT_STD;
> +         appendStringInfoChar(buf, ' ');
> +     }
>       appendStringInfo(buf, "INSERT INTO %s",
>                                        generate_relation_name(rte->relid));
>   
> ***************
> *** 1883,1889 ****
>       /* Add the VALUES or the SELECT */
>       if (select_rte == NULL)
>       {
> !             appendStringInfo(buf, "VALUES (");
>               sep = "";
>               foreach(l, query->targetList)
>               {
> --- 1999,2005 ----
>       /* Add the VALUES or the SELECT */
>       if (select_rte == NULL)
>       {
> !             appendContextKeyword(context, "VALUES (", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 2);
>               sep = "";
>               foreach(l, query->targetList)
>               {
> ***************
> *** 1899,1905 ****
>               appendStringInfoChar(buf, ')');
>       }
>       else
> !             get_query_def(select_rte->subquery, buf, NIL, NULL);
>   }
>   
>   
> --- 2015,2021 ----
>               appendStringInfoChar(buf, ')');
>       }
>       else
> !             get_query_def(select_rte->subquery, buf, NIL, NULL, 
> context->prettyFlags, context->indentLevel);
>   }
>   
>   
> ***************
> *** 1920,1925 ****
> --- 2036,2046 ----
>        */
>       rte = rt_fetch(query->resultRelation, query->rtable);
>       Assert(rte->rtekind == RTE_RELATION);
> +     if (PRETTY_INDENT(context))
> +     {
> +         appendStringInfoChar(buf, ' ');
> +         context->indentLevel += PRETTYINDENT_STD;
> +     }
>       appendStringInfo(buf, "UPDATE %s%s SET ",
>                                        only_marker(rte),
>                                        generate_relation_name(rte->relid));
> ***************
> *** 1953,1959 ****
>       /* Finally add a WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendStringInfo(buf, " WHERE ");
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   }
> --- 2074,2080 ----
>       /* Finally add a WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendContextKeyword(context, " WHERE ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 1);
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   }
> ***************
> *** 1974,1979 ****
> --- 2095,2105 ----
>        */
>       rte = rt_fetch(query->resultRelation, query->rtable);
>       Assert(rte->rtekind == RTE_RELATION);
> +     if (PRETTY_INDENT(context))
> +     {
> +         context->indentLevel += PRETTYINDENT_STD;
> +         appendStringInfoChar(buf, ' ');
> +     }
>       appendStringInfo(buf, "DELETE FROM %s%s",
>                                        only_marker(rte),
>                                        generate_relation_name(rte->relid));
> ***************
> *** 1981,1987 ****
>       /* Add a WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendStringInfo(buf, " WHERE ");
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   }
> --- 2107,2113 ----
>       /* Add a WHERE clause if given */
>       if (query->jointree->quals != NULL)
>       {
> !             appendContextKeyword(context, " WHERE ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 1);
>               get_rule_expr(query->jointree->quals, context, false);
>       }
>   }
> ***************
> *** 2000,2005 ****
> --- 2126,2132 ----
>       {
>               NotifyStmt *stmt = (NotifyStmt *) query->utilityStmt;
>   
> +             appendContextKeyword(context, "", 0, PRETTYINDENT_STD, 1);
>               appendStringInfo(buf, "NOTIFY %s",
>                                  
> quote_qualified_identifier(stmt->relation->schemaname,
>                                                                                      
>    stmt->relation->relname));
> ***************
> *** 2140,2145 ****
> --- 2267,2508 ----
>   }
>   
>   
> + /********************************************
> +  * get_simple_binary_op_name
> +  * helper function for isSimpleNode
> +  * will return single char binary operator
> +  *******************************************/
> + 
> + static char *get_simple_binary_op_name(OpExpr *expr)
> + {
> +     List       *args = expr->args;
> + 
> +     if (length(args) == 2)
> +     {
> +             /* binary operator */
> +             Node       *arg1 = (Node *) lfirst(args);
> +             Node       *arg2 = (Node *) lsecond(args);
> +             char *op = generate_operator_name(expr->opno, exprType(arg1), 
> exprType(arg2));
> + 
> +             if (strlen(op) == 1)
> +                 return op;
> +     }
> +     return 0;
> + }
> + 
> + 
> + /***************************************
> +  * check if given node is simple.
> +  *  false  : not simple
> +  *  true   : simple in the context of parent node's type
> +  ***************************************/
> + 
> + static bool isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
> + {
> +     if (!node)
> +     return true;
> + 
> +     switch (nodeTag(node))
> +     {
> +     // single words: always simple
> +     case T_Var:
> +     case T_Const:
> +     case T_Param:
> + 
> +     // function-like: name(..) or name[..]
> +     case T_ArrayRef:
> +     case T_ArrayExpr:
> +     case T_CoalesceExpr:
> +     case T_NullIfExpr:
> +     case T_Aggref:
> +     case T_FuncExpr:
> + 
> +         // CASE keywords act as parentheses
> +     case T_CaseExpr:
> +         return true;
> + 
> +         // appears simple since . has top precedence, unless parent is 
> T_FieldSelect itself!
> +     case T_FieldSelect:
> +         return (nodeTag(parentNode) == T_FieldSelect ? false : true);
> + 
> + 
> +         // maybe simple, check args
> +     case T_CoerceToDomain:
> +         return isSimpleNode((Node*) ((CoerceToDomain*)node)->arg, node, 
> prettyFlags);
> +     case T_RelabelType:
> +         return isSimpleNode((Node*) ((RelabelType*)node)->arg, node, prettyFlags);
> + 
> + 
> +     // depends on parent node type; needs further checking
> +     case T_OpExpr:
> +     {
> +         if (prettyFlags & PRETTYFLAG_PAREN && nodeTag(parentNode) == T_OpExpr)
> +         {
> +             char *op=get_simple_binary_op_name((OpExpr*)node);
> +             char *parentOp=get_simple_binary_op_name((OpExpr*)parentNode);
> +             if (!op || !parentOp)
> +                 return false;
> + 
> +                 // we know only these basic operators
> +             if (!strchr("+-*/%", *op) || !strchr("+-*/%", *parentOp))
> +                 return false;
> + 
> +             // natural operator precedence, so we don't need parentheses
> +             if (strchr("*/%", *op) || strchr("+-", *parentOp))
> +                 return true;
> + 
> +             return false;
> +         }
> +             // else do the same stuff as for T_SubLink et al.
> +     }
> +     case T_SubLink:
> +     case T_NullTest:
> +     case T_BooleanTest:
> +     case T_DistinctExpr:
> +     {
> +         switch (nodeTag(parentNode))
> +         {
> +             case T_FuncExpr:
> +             {
> +                 // special handling for casts
> +                 CoercionForm type=((FuncExpr*)parentNode)->funcformat;
> +                 if (type == COERCE_EXPLICIT_CAST || type == COERCE_IMPLICIT_CAST)
> +                     return false;
> +                     return true;      // own parentheses
> +             }
> +             case T_BoolExpr:      // lower precedence
> +             case T_ArrayRef:      // other separators
> +             case T_ArrayExpr:     // other separators
> +             case T_CoalesceExpr:  // own parentheses
> +             case T_NullIfExpr:    // other separators
> +             case T_Aggref:        // own parentheses
> +             case T_CaseExpr:      // other separators
> +                 return true;
> +             default:
> +                 return false;
> +         }
> +     }
> +     case T_BoolExpr:
> +         switch (nodeTag(parentNode))
> +         {
> +             case T_BoolExpr:
> +                 if (prettyFlags & PRETTYFLAG_PAREN)
> +                 {
> +                     BoolExprType type=((BoolExpr*)node)->boolop;
> +                     BoolExprType parentType=((BoolExpr*)parentNode)->boolop;
> +                     switch (type)
> +                     {
> +                         case NOT_EXPR:
> +                         case AND_EXPR:
> +                             if (parentType == AND_EXPR || parentType == OR_EXPR)
> +                                 return true;
> +                             break;
> +                         case OR_EXPR:
> +                             if (parentType == OR_EXPR)
> +                                 return true;
> +                             break;
> +                     }
> +                 }
> +                 return false;
> +             case T_FuncExpr:
> +             {
> +                 // special handling for casts
> +                 CoercionForm type=((FuncExpr*)parentNode)->funcformat;
> +                 if (type == COERCE_EXPLICIT_CAST || type == COERCE_IMPLICIT_CAST)
> +                     return false;
> +                     return true;      // own parentheses
> +             }
> +             case T_ArrayRef:      // other separators
> +             case T_ArrayExpr:     // other separators
> +             case T_CoalesceExpr:  // own parentheses
> +             case T_NullIfExpr:    // other separators
> +             case T_Aggref:        // own parentheses
> +             case T_CaseExpr:      // other separators
> +                 return true;
> +             default:
> +                 return false;
> +         }
> +         // these are not completely implemented; so far, they're simple
> +     case T_SubPlan:
> +     case T_CoerceToDomainValue:
> +         return true;
> + 
> +     case T_ScalarArrayOpExpr:
> +         // need to check
> +     default:
> +         break;
> +     }
> +     // those we don't know: in dubio complexo
> +     return false;
> + }
> + 
> + 
> + /******************************************
> +  * appendContextKeyword
> +  * append spaces to buffer
> +  ******************************************/
> + static void appendStringInfoSpace(StringInfo buf, int count)
> + {
> +     while (count-- > 0)
> +     appendStringInfoChar(buf, ' ');
> + }
> + 
> + /******************************************
> +  * appendContextKeyword
> +  * performing a line break, and indentation
> +  * if prettyPrint is enabled.
> +  * Otherwise, only the keyword is appended
> +  *****************************************/
> + 
> + static void appendContextKeyword(deparse_context *context, char *str, int 
> indentBefore, int indentAfter, int indentPlus)
> + {
> +     if (PRETTY_INDENT(context))
> +     {
> +     context->indentLevel += indentBefore;
> +     if (context->indentLevel < 0)
> +         context->indentLevel=0;
> + 
> +     appendStringInfoChar(context->buf, '\n');
> +     appendStringInfoSpace(context->buf, context->indentLevel + indentPlus);
> +     }
> + 
> +     appendStringInfoString(context->buf, str);
> + 
> +     if (PRETTY_INDENT(context))
> +     {
> +     context->indentLevel += indentAfter;
> +     if (context->indentLevel < 0)
> +         context->indentLevel=0;
> +     }
> + }
> + 
> + 
> + /*
> +  * get_rule_expr_paren  - parsing expr using get_rule_expr, 
> +  * embracing the string with parentheses if necessary for prettyPrint.
> +  * never embracing if prettyFlags=0, because it's done in the calling node.
> +  *
> +  * Any node that does *not* embrace its argument node by sql syntax (with 
> parentheses, non-operator keywords 
> +  * like CASE/WHEN/ON, or comma etc) should use get_rule_expr_paren instead of 
> get_rule_expr 
> +  * so parentheses can be added.
> +  */
> + 
> + static void
> + get_rule_expr_paren(Node *node, deparse_context *context, 
> +                 bool showimplicit, Node *parentNode)
> + {
> +     bool need_paren = PRETTY_PAREN(context) && !isSimpleNode(node, parentNode, 
> context->prettyFlags);
> + 
> +     if (need_paren)
> +         appendStringInfoChar(context->buf, '(');
> + 
> +     get_rule_expr(node, context, showimplicit);
> + 
> +     if (need_paren)
> +         appendStringInfoChar(context->buf, ')');
> + }
> + 
> + 
>   /* ----------
>    * get_rule_expr                    - Parse back an expression
>    *
> ***************
> *** 2294,2305 ****
>                               List       *args = expr->args;
>                               Node       *arg1 = (Node *) lfirst(args);
>                               Node       *arg2 = (Node *) lsecond(args);
> ! 
> !                             appendStringInfoChar(buf, '(');
> !                             get_rule_expr(arg1, context, true);
>                               appendStringInfo(buf, " IS DISTINCT FROM ");
> !                             get_rule_expr(arg2, context, true);
> !                             appendStringInfoChar(buf, ')');
>                       }
>                       break;
>   
> --- 2657,2669 ----
>                               List       *args = expr->args;
>                               Node       *arg1 = (Node *) lfirst(args);
>                               Node       *arg2 = (Node *) lsecond(args);
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
> !                             get_rule_expr_paren(arg1, context, true, node);
>                               appendStringInfo(buf, " IS DISTINCT FROM ");
> !                             get_rule_expr_paren(arg2, context, true, node);
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, ')');
>                       }
>                       break;
>   
> ***************
> *** 2310,2324 ****
>                               Node       *arg1 = (Node *) lfirst(args);
>                               Node       *arg2 = (Node *) lsecond(args);
>   
> !                             appendStringInfoChar(buf, '(');
> !                             get_rule_expr(arg1, context, true);
>                               appendStringInfo(buf, " %s %s (",
>                                                                
> generate_operator_name(expr->opno,
>                                                                                      
>                          exprType(arg1),
>                                                                               
> get_element_type(exprType(arg2))),
>                                                                expr->useOr ? "ANY" : 
> "ALL");
> !                             get_rule_expr(arg2, context, true);
> !                             appendStringInfo(buf, "))");
>                       }
>                       break;
>   
> --- 2674,2692 ----
>                               Node       *arg1 = (Node *) lfirst(args);
>                               Node       *arg2 = (Node *) lsecond(args);
>   
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
> !                             get_rule_expr_paren(arg1, context, true, node);
>                               appendStringInfo(buf, " %s %s (",
>                                                                
> generate_operator_name(expr->opno,
>                                                                                      
>                          exprType(arg1),
>                                                                               
> get_element_type(exprType(arg2))),
>                                                                expr->useOr ? "ANY" : 
> "ALL");
> !                             get_rule_expr_paren(arg2, context, true, node);
> !                             appendStringInfoString(buf, ")");
> ! 
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, ')');
>                       }
>                       break;
>   
> ***************
> *** 2330,2362 ****
>                               switch (expr->boolop)
>                               {
>                                       case AND_EXPR:
> !                                             appendStringInfoChar(buf, '(');
> !                                             get_rule_expr((Node *) lfirst(args), 
> context, false);
>                                               while ((args = lnext(args)) != NIL)
>                                               {
>                                                       appendStringInfo(buf, " AND ");
> !                                                     get_rule_expr((Node *) 
> lfirst(args), context,
> !                                                                               
> false);
>                                               }
> !                                             appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       case OR_EXPR:
> !                                             appendStringInfoChar(buf, '(');
> !                                             get_rule_expr((Node *) lfirst(args), 
> context, false);
>                                               while ((args = lnext(args)) != NIL)
>                                               {
>                                                       appendStringInfo(buf, " OR ");
> !                                                     get_rule_expr((Node *) 
> lfirst(args), context,
> !                                                                               
> false);
>                                               }
> !                                             appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       case NOT_EXPR:
> !                                             appendStringInfo(buf, "(NOT ");
> !                                             get_rule_expr((Node *) lfirst(args), 
> context, false);
> !                                             appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       default:
> --- 2698,2737 ----
>                               switch (expr->boolop)
>                               {
>                                       case AND_EXPR:
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, '(');
> !                                             get_rule_expr_paren((Node *) 
> lfirst(args), context, false, node);
>                                               while ((args = lnext(args)) != NIL)
>                                               {
>                                                       appendStringInfo(buf, " AND ");
> !                                                     get_rule_expr_paren((Node *) 
> lfirst(args), context,
> !                                                                               
> false, node);
>                                               }
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       case OR_EXPR:
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, '(');
> !                                             get_rule_expr_paren((Node *) 
> lfirst(args), context, false, node);
>                                               while ((args = lnext(args)) != NIL)
>                                               {
>                                                       appendStringInfo(buf, " OR ");
> !                                                     get_rule_expr_paren((Node *) 
> lfirst(args), context,
> !                                                                               
> false, node);
>                                               }
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       case NOT_EXPR:
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, '(');
> !                                             appendStringInfo(buf, "NOT ");
> !                                             get_rule_expr_paren((Node *) 
> lfirst(args), context, false, node);
> !                                             if (!PRETTY_PAREN(context))
> !                                                 appendStringInfoChar(buf, ')');
>                                               break;
>   
>                                       default:
> ***************
> *** 2404,2412 ****
>                                * arg.fieldname, but most cases where FieldSelect is 
> used
>                                * are *not* simple.  So, always use parenthesized 
> syntax.
>                                */
> !                             appendStringInfoChar(buf, '(');
> !                             get_rule_expr((Node *) fselect->arg, context, true);
> !                             appendStringInfo(buf, ").%s", 
> quote_identifier(fieldname));
>                       }
>                       break;
>   
> --- 2779,2790 ----
>                                * arg.fieldname, but most cases where FieldSelect is 
> used
>                                * are *not* simple.  So, always use parenthesized 
> syntax.
>                                */
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
> !                             get_rule_expr_paren((Node *) fselect->arg, context, 
> true, node);
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, ')');
> !                             appendStringInfo(buf, ".%s", 
> quote_identifier(fieldname));
>                       }
>                       break;
>   
> ***************
> *** 2419,2425 ****
>                                       !showimplicit)
>                               {
>                                       /* don't show the implicit cast */
> !                                     get_rule_expr(arg, context, showimplicit);
>                               }
>                               else
>                               {
> --- 2797,2803 ----
>                                       !showimplicit)
>                               {
>                                       /* don't show the implicit cast */
> !                                     get_rule_expr_paren(arg, context, 
> showimplicit, node);
>                               }
>                               else
>                               {
> ***************
> *** 2431,2439 ****
>                                        */
>                                       arg = strip_type_coercion(arg, 
> relabel->resulttype);
>   
> !                                     appendStringInfoChar(buf, '(');
> !                                     get_rule_expr(arg, context, showimplicit);
> !                                     appendStringInfo(buf, ")::%s",
>                                                       
> format_type_with_typemod(relabel->resulttype,
>                                                                                      
>                   relabel->resulttypmod));
>                               }
> --- 2809,2821 ----
>                                        */
>                                       arg = strip_type_coercion(arg, 
> relabel->resulttype);
>   
> !                                     if (!PRETTY_PAREN(context))
> !                                         appendStringInfoChar(buf, '(');
> ! 
> !                                     get_rule_expr_paren(arg, context, 
> showimplicit, node);
> !                                     if (!PRETTY_PAREN(context))
> !                                         appendStringInfoChar(buf, ')');
> !                                     appendStringInfo(buf, "::%s",
>                                                       
> format_type_with_typemod(relabel->resulttype,
>                                                                                      
>                   relabel->resulttypmod));
>                               }
> ***************
> *** 2445,2463 ****
>                               CaseExpr   *caseexpr = (CaseExpr *) node;
>                               List       *temp;
>   
> !                             appendStringInfo(buf, "CASE");
>                               foreach(temp, caseexpr->args)
>                               {
>                                       CaseWhen   *when = (CaseWhen *) lfirst(temp);
>   
> !                                     appendStringInfo(buf, " WHEN ");
>                                       get_rule_expr((Node *) when->expr, context, 
> false);
>                                       appendStringInfo(buf, " THEN ");
>                                       get_rule_expr((Node *) when->result, context, 
> true);
>                               }
> !                             appendStringInfo(buf, " ELSE ");
>                               get_rule_expr((Node *) caseexpr->defresult, context, 
> true);
> !                             appendStringInfo(buf, " END");
>                       }
>                       break;
>   
> --- 2827,2853 ----
>                               CaseExpr   *caseexpr = (CaseExpr *) node;
>                               List       *temp;
>   
> !                             appendContextKeyword(context, "CASE", 0, 
> PRETTYINDENT_VAR, 0);
>                               foreach(temp, caseexpr->args)
>                               {
>                                       CaseWhen   *when = (CaseWhen *) lfirst(temp);
>   
> !                                     if (!PRETTY_INDENT(context))
> !                                         appendStringInfoChar(buf, ' ');
> ! 
> !                                     appendContextKeyword(context, "WHEN ", 0, 0, 
> 0);
>                                       get_rule_expr((Node *) when->expr, context, 
> false);
> + 
>                                       appendStringInfo(buf, " THEN ");
>                                       get_rule_expr((Node *) when->result, context, 
> true);
>                               }
> !                             if (!PRETTY_INDENT(context))
> !                                 appendStringInfoChar(buf, ' ');
> !                             appendContextKeyword(context, "ELSE ", 0, 0, 0);
>                               get_rule_expr((Node *) caseexpr->defresult, context, 
> true);
> !                             if (!PRETTY_INDENT(context))
> !                                 appendStringInfoChar(buf, ' ');
> !                             appendContextKeyword(context, "END", 
> -PRETTYINDENT_VAR, 0, 0);
>                       }
>                       break;
>   
> ***************
> *** 2525,2544 ****
>                       {
>                               NullTest   *ntest = (NullTest *) node;
>   
> !                             appendStringInfo(buf, "(");
> !                             get_rule_expr((Node *) ntest->arg, context, true);
>                               switch (ntest->nulltesttype)
>                               {
>                                       case IS_NULL:
> !                                             appendStringInfo(buf, " IS NULL)");
>                                               break;
>                                       case IS_NOT_NULL:
> !                                             appendStringInfo(buf, " IS NOT NULL)");
>                                               break;
>                                       default:
>                                               elog(ERROR, "get_rule_expr: unexpected 
> nulltesttype %d",
>                                                        (int) ntest->nulltesttype);
>                               }
>                       }
>                       break;
>   
> --- 2915,2937 ----
>                       {
>                               NullTest   *ntest = (NullTest *) node;
>   
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
> !                             get_rule_expr_paren((Node *) ntest->arg, context, 
> true, node);
>                               switch (ntest->nulltesttype)
>                               {
>                                       case IS_NULL:
> !                                             appendStringInfo(buf, " IS NULL");
>                                               break;
>                                       case IS_NOT_NULL:
> !                                             appendStringInfo(buf, " IS NOT NULL");
>                                               break;
>                                       default:
>                                               elog(ERROR, "get_rule_expr: unexpected 
> nulltesttype %d",
>                                                        (int) ntest->nulltesttype);
>                               }
> +                             if (!PRETTY_PAREN(context))
> +                                 appendStringInfoChar(buf, ')');
>                       }
>                       break;
>   
> ***************
> *** 2546,2577 ****
>                       {
>                               BooleanTest *btest = (BooleanTest *) node;
>   
> !                             appendStringInfo(buf, "(");
> !                             get_rule_expr((Node *) btest->arg, context, false);
>                               switch (btest->booltesttype)
>                               {
>                                       case IS_TRUE:
> !                                             appendStringInfo(buf, " IS TRUE)");
>                                               break;
>                                       case IS_NOT_TRUE:
> !                                             appendStringInfo(buf, " IS NOT TRUE)");
>                                               break;
>                                       case IS_FALSE:
> !                                             appendStringInfo(buf, " IS FALSE)");
>                                               break;
>                                       case IS_NOT_FALSE:
> !                                             appendStringInfo(buf, " IS NOT 
> FALSE)");
>                                               break;
>                                       case IS_UNKNOWN:
> !                                             appendStringInfo(buf, " IS UNKNOWN)");
>                                               break;
>                                       case IS_NOT_UNKNOWN:
> !                                             appendStringInfo(buf, " IS NOT 
> UNKNOWN)");
>                                               break;
>                                       default:
>                                               elog(ERROR, "get_rule_expr: unexpected 
> booltesttype %d",
>                                                        (int) btest->booltesttype);
>                               }
>                       }
>                       break;
>   
> --- 2939,2973 ----
>                       {
>                               BooleanTest *btest = (BooleanTest *) node;
>   
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
> !                             get_rule_expr_paren((Node *) btest->arg, context, 
> false, node);
>                               switch (btest->booltesttype)
>                               {
>                                       case IS_TRUE:
> !                                             appendStringInfo(buf, " IS TRUE");
>                                               break;
>                                       case IS_NOT_TRUE:
> !                                             appendStringInfo(buf, " IS NOT TRUE");
>                                               break;
>                                       case IS_FALSE:
> !                                             appendStringInfo(buf, " IS FALSE");
>                                               break;
>                                       case IS_NOT_FALSE:
> !                                             appendStringInfo(buf, " IS NOT FALSE");
>                                               break;
>                                       case IS_UNKNOWN:
> !                                             appendStringInfo(buf, " IS UNKNOWN");
>                                               break;
>                                       case IS_NOT_UNKNOWN:
> !                                             appendStringInfo(buf, " IS NOT 
> UNKNOWN");
>                                               break;
>                                       default:
>                                               elog(ERROR, "get_rule_expr: unexpected 
> booltesttype %d",
>                                                        (int) btest->booltesttype);
>                               }
> +                             if (!PRETTY_PAREN(context))
> +                                 appendStringInfoChar(buf, ')');
>                       }
>                       break;
>   
> ***************
> *** 2593,2601 ****
>                               }
>                               else
>                               {
> !                                     appendStringInfoChar(buf, '(');
> !                                     get_rule_expr(arg, context, false);
> !                                     appendStringInfo(buf, ")::%s",
>                                                       
> format_type_with_typemod(ctest->resulttype,
>                                                                                      
>                   ctest->resulttypmod));
>                               }
> --- 2989,3002 ----
>                               }
>                               else
>                               {
> !                                     if (!PRETTY_PAREN(context))
> !                                         appendStringInfoChar(buf, '(');
> ! 
> !                                     get_rule_expr_paren(arg, context, false, node);
> ! 
> !                                     if (!PRETTY_PAREN(context))
> !                                         appendStringInfoChar(buf, ')');
> !                                     appendStringInfo(buf, "::%s",
>                                                       
> format_type_with_typemod(ctest->resulttype,
>                                                                                      
>                   ctest->resulttypmod));
>                               }
> ***************
> *** 2627,2645 ****
>       Oid                     opno = expr->opno;
>       List       *args = expr->args;
>   
> !     appendStringInfoChar(buf, '(');
>       if (length(args) == 2)
>       {
>               /* binary operator */
>               Node       *arg1 = (Node *) lfirst(args);
>               Node       *arg2 = (Node *) lsecond(args);
> ! 
> !             get_rule_expr(arg1, context, true);
>               appendStringInfo(buf, " %s ",
>                                                generate_operator_name(opno,
>                                                                                      
>          exprType(arg1),
>                                                                                      
>          exprType(arg2)));
> !             get_rule_expr(arg2, context, true);
>       }
>       else
>       {
> --- 3028,3046 ----
>       Oid                     opno = expr->opno;
>       List       *args = expr->args;
>   
> !     if (!PRETTY_PAREN(context))
> !         appendStringInfoChar(buf, '(');
>       if (length(args) == 2)
>       {
>               /* binary operator */
>               Node       *arg1 = (Node *) lfirst(args);
>               Node       *arg2 = (Node *) lsecond(args);
> !             get_rule_expr_paren(arg1, context, true, (Node*)expr);
>               appendStringInfo(buf, " %s ",
>                                                generate_operator_name(opno,
>                                                                                      
>          exprType(arg1),
>                                                                                      
>          exprType(arg2)));
> !             get_rule_expr_paren(arg2, context, true, (Node*)expr);
>       }
>       else
>       {
> ***************
> *** 2661,2670 ****
>                                                                
> generate_operator_name(opno,
>                                                                                      
>                          InvalidOid,
>                                                                                      
>                          exprType(arg)));
> !                             get_rule_expr(arg, context, true);
>                               break;
>                       case 'r':
> !                             get_rule_expr(arg, context, true);
>                               appendStringInfo(buf, " %s",
>                                                                
> generate_operator_name(opno,
>                                                                                      
>                          exprType(arg),
> --- 3062,3071 ----
>                                                                
> generate_operator_name(opno,
>                                                                                      
>                          InvalidOid,
>                                                                                      
>                          exprType(arg)));
> !                             get_rule_expr_paren(arg, context, true, (Node*)expr);
>                               break;
>                       case 'r':
> !                             get_rule_expr_paren(arg, context, true, (Node*)expr);
>                               appendStringInfo(buf, " %s",
>                                                                
> generate_operator_name(opno,
>                                                                                      
>                          exprType(arg),
> ***************
> *** 2675,2681 ****
>               }
>               ReleaseSysCache(tp);
>       }
> !     appendStringInfoChar(buf, ')');
>   }
>   
>   /*
> --- 3076,3083 ----
>               }
>               ReleaseSysCache(tp);
>       }
> !     if (!PRETTY_PAREN(context))
> !         appendStringInfoChar(buf, ')');
>   }
>   
>   /*
> ***************
> *** 2698,2704 ****
>        */
>       if (expr->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
>       {
> !             get_rule_expr((Node *) lfirst(expr->args), context, showimplicit);
>               return;
>       }
>   
> --- 3100,3106 ----
>        */
>       if (expr->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
>       {
> !             get_rule_expr_paren((Node *) lfirst(expr->args), context, 
> showimplicit, (Node*)expr);
>               return;
>       }
>   
> ***************
> *** 2724,2732 ****
>                */
>               arg = strip_type_coercion(arg, rettype);
>   
> !             appendStringInfoChar(buf, '(');
> !             get_rule_expr(arg, context, showimplicit);
> !             appendStringInfo(buf, ")::%s",
>                                                format_type_with_typemod(rettype, 
> coercedTypmod));
>   
>               return;
> --- 3126,3139 ----
>                */
>               arg = strip_type_coercion(arg, rettype);
>   
> !             if (!PRETTY_PAREN(context))
> !                 appendStringInfoChar(buf, '(');
> !             
> !             get_rule_expr_paren(arg, context, showimplicit, (Node*)expr);
> ! 
> !             if (!PRETTY_PAREN(context))
> !                 appendStringInfoChar(buf, ')');
> !             appendStringInfo(buf, "::%s",
>                                                format_type_with_typemod(rettype, 
> coercedTypmod));
>   
>               return;
> ***************
> *** 3047,3053 ****
>       if (need_paren)
>               appendStringInfoChar(buf, '(');
>   
> !     get_query_def(query, buf, context->namespaces, NULL);
>   
>       if (need_paren)
>               appendStringInfo(buf, "))");
> --- 3454,3460 ----
>       if (need_paren)
>               appendStringInfoChar(buf, '(');
>   
> !     get_query_def(query, buf, context->namespaces, NULL, context->prettyFlags, 
> context->indentLevel);
>   
>       if (need_paren)
>               appendStringInfo(buf, "))");
> ***************
> *** 3064,3070 ****
>   get_from_clause(Query *query, deparse_context *context)
>   {
>       StringInfo      buf = context->buf;
> !     char       *sep;
>       List       *l;
>   
>       /*
> --- 3471,3477 ----
>   get_from_clause(Query *query, deparse_context *context)
>   {
>       StringInfo      buf = context->buf;
> !     char       *sep=0;
>       List       *l;
>   
>       /*
> ***************
> *** 3074,3080 ****
>        * sufficient to check here.) Also ignore the rule pseudo-RTEs for NEW
>        * and OLD.
>        */
> -     sep = " FROM ";
>   
>       foreach(l, query->jointree->fromlist)
>       {
> --- 3481,3486 ----
> ***************
> *** 3093,3099 ****
>                               continue;
>               }
>   
> !             appendStringInfo(buf, sep);
>               get_from_clause_item(jtnode, query, context);
>               sep = ", ";
>       }
> --- 3499,3509 ----
>                               continue;
>               }
>   
> !             if (!sep)
> !                 appendContextKeyword(context, " FROM ", -PRETTYINDENT_STD, 
> PRETTYINDENT_STD, 2);
> !             else
> !                 appendStringInfo(buf, sep);
> ! 
>               get_from_clause_item(jtnode, query, context);
>               sep = ", ";
>       }
> ***************
> *** 3122,3128 ****
>                       case RTE_SUBQUERY:
>                               /* Subquery RTE */
>                               appendStringInfoChar(buf, '(');
> !                             get_query_def(rte->subquery, buf, context->namespaces, 
> NULL);
>                               appendStringInfoChar(buf, ')');
>                               break;
>                       case RTE_FUNCTION:
> --- 3532,3539 ----
>                       case RTE_SUBQUERY:
>                               /* Subquery RTE */
>                               appendStringInfoChar(buf, '(');
> !                             get_query_def(rte->subquery, buf, context->namespaces, 
> NULL, 
> !                                           context->prettyFlags, 
> context->indentLevel);
>                               appendStringInfoChar(buf, ')');
>                               break;
>                       case RTE_FUNCTION:
> ***************
> *** 3144,3150 ****
>                       {
>                               List       *col;
>   
> !                             appendStringInfo(buf, "(");
>                               foreach(col, rte->alias->colnames)
>                               {
>                                       if (col != rte->alias->colnames)
> --- 3555,3561 ----
>                       {
>                               List       *col;
>   
> !                             appendStringInfoChar(buf, '(');
>                               foreach(col, rte->alias->colnames)
>                               {
>                                       if (col != rte->alias->colnames)
> ***************
> *** 3178,3213 ****
>       else if (IsA(jtnode, JoinExpr))
>       {
>               JoinExpr   *j = (JoinExpr *) jtnode;
>   
> -             appendStringInfoChar(buf, '(');
>               get_from_clause_item(j->larg, query, context);
>               if (j->isNatural)
> -                     appendStringInfo(buf, " NATURAL");
> -             switch (j->jointype)
>               {
>                       case JOIN_INNER:
>                               if (j->quals)
> !                                     appendStringInfo(buf, " JOIN ");
>                               else
> !                                     appendStringInfo(buf, " CROSS JOIN ");
>                               break;
>                       case JOIN_LEFT:
> !                             appendStringInfo(buf, " LEFT JOIN ");
>                               break;
>                       case JOIN_FULL:
> !                             appendStringInfo(buf, " FULL JOIN ");
>                               break;
>                       case JOIN_RIGHT:
> !                             appendStringInfo(buf, " RIGHT JOIN ");
>                               break;
>                       case JOIN_UNION:
> !                             appendStringInfo(buf, " UNION JOIN ");
>                               break;
>                       default:
>                               elog(ERROR, "get_from_clause_item: unknown join type 
> %d",
>                                        (int) j->jointype);
>               }
>               get_from_clause_item(j->rarg, query, context);
>               if (!j->isNatural)
>               {
>                       if (j->using)
> --- 3589,3666 ----
>       else if (IsA(jtnode, JoinExpr))
>       {
>               JoinExpr   *j = (JoinExpr *) jtnode;
> +             bool need_paren_on_right = PRETTY_PAREN(context) && !IsA(j->rarg, 
> RangeTblRef);
> + 
> +             if (!PRETTY_PAREN(context) || j->alias != NULL)
> +                 appendStringInfoChar(buf, '(');
>   
>               get_from_clause_item(j->larg, query, context);
> + 
>               if (j->isNatural)
>               {
> +                 if (!PRETTY_INDENT(context))
> +                     appendStringInfoChar(buf, ' ');
> +                 switch (j->jointype)
> +                 {
> +                     case JOIN_INNER:
> +                             if (j->quals)
> +                                     appendContextKeyword(context, "NATURAL JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             else
> +                                     appendContextKeyword(context, "NATURAL CROSS 
> JOIN ", -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             break;
> +                     case JOIN_LEFT:
> +                             appendContextKeyword(context, "NATURAL LEFT JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             break;
> +                     case JOIN_FULL:
> +                             appendContextKeyword(context, "NATURAL FULL JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             break;
> +                     case JOIN_RIGHT:
> +                             appendContextKeyword(context, "NATURAL RIGHT JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             break;
> +                     case JOIN_UNION:
> +                             appendContextKeyword(context, "NATURAL UNION JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 0);
> +                             break;
> +                     default:
> +                             elog(ERROR, "get_from_clause_item: unknown join type 
> %d",
> +                                      (int) j->jointype);
> +                 }
> +             }
> +             else
> +             {
> +                 switch (j->jointype)
> +                 {
>                       case JOIN_INNER:
>                               if (j->quals)
> !                                     appendContextKeyword(context, " JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 2);
>                               else
> !                                     appendContextKeyword(context, " CROSS JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 1);
>                               break;
>                       case JOIN_LEFT:
> !                             appendContextKeyword(context, " LEFT JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 2);
>                               break;
>                       case JOIN_FULL:
> !                             appendContextKeyword(context, " FULL JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 2);
>                               break;
>                       case JOIN_RIGHT:
> !                             appendContextKeyword(context, " RIGHT JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 2);
>                               break;
>                       case JOIN_UNION:
> !                             appendContextKeyword(context, " UNION JOIN ", 
> -PRETTYINDENT_JOIN, PRETTYINDENT_JOIN, 2);
>                               break;
>                       default:
>                               elog(ERROR, "get_from_clause_item: unknown join type 
> %d",
>                                        (int) j->jointype);
> +                 }
>               }
> + 
> +             if (need_paren_on_right)
> +                 appendStringInfoChar(buf, '(');
>               get_from_clause_item(j->rarg, query, context);
> +             if (need_paren_on_right)
> +                 appendStringInfoChar(buf, ')');
> + 
> +             context->indentLevel -= PRETTYINDENT_JOIN_ON;
> + 
>               if (!j->isNatural)
>               {
>                       if (j->using)
> ***************
> *** 3226,3237 ****
>                       }
>                       else if (j->quals)
>                       {
> !                             appendStringInfo(buf, " ON (");
>                               get_rule_expr(j->quals, context, false);
> !                             appendStringInfoChar(buf, ')');
>                       }
>               }
> !             appendStringInfoChar(buf, ')');
>               /* Yes, it's correct to put alias after the right paren ... */
>               if (j->alias != NULL)
>               {
> --- 3679,3695 ----
>                       }
>                       else if (j->quals)
>                       {
> !                             appendStringInfo(buf, " ON ");
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, '(');
>                               get_rule_expr(j->quals, context, false);
> !                             if (!PRETTY_PAREN(context))
> !                                 appendStringInfoChar(buf, ')');
>                       }
>               }
> !             if (!PRETTY_PAREN(context) || j->alias != NULL)
> !                 appendStringInfoChar(buf, ')');
> ! 
>               /* Yes, it's correct to put alias after the right paren ... */
>               if (j->alias != NULL)
>               {
> ***************
> *** 3241,3247 ****
>                       {
>                               List       *col;
>   
> !                             appendStringInfo(buf, "(");
>                               foreach(col, j->alias->colnames)
>                               {
>                                       if (col != j->alias->colnames)
> --- 3699,3705 ----
>                       {
>                               List       *col;
>   
> !                             appendStringInfoChar(buf, '(');
>                               foreach(col, j->alias->colnames)
>                               {
>                                       if (col != j->alias->colnames)

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to