@ -181,7 +181,7 @@ static void get_rule_windowclause(Query *query, deparse_context *context);
static void get_rule_windowspec ( WindowClause * wc , List * targetList ,
static void get_rule_windowspec ( WindowClause * wc , List * targetList ,
deparse_context * context ) ;
deparse_context * context ) ;
static void push_plan ( deparse_namespace * dpns , Plan * subplan ) ;
static void push_plan ( deparse_namespace * dpns , Plan * subplan ) ;
static char * get_variable ( Var * var , int levelsup , bool showstar ,
static char * get_variable ( Var * var , int levelsup , bool istoplevel ,
deparse_context * context ) ;
deparse_context * context ) ;
static RangeTblEntry * find_rte_by_refname ( const char * refname ,
static RangeTblEntry * find_rte_by_refname ( const char * refname ,
deparse_context * context ) ;
deparse_context * context ) ;
@ -2664,11 +2664,12 @@ get_target_list(List *targetList, deparse_context *context,
* " foo.* " , which is the preferred notation in most contexts , but at
* " foo.* " , which is the preferred notation in most contexts , but at
* the top level of a SELECT list it ' s not right ( the parser will
* the top level of a SELECT list it ' s not right ( the parser will
* expand that notation into multiple columns , yielding behavior
* expand that notation into multiple columns , yielding behavior
* different from a whole - row Var ) . We want just " foo " , instead .
* different from a whole - row Var ) . We need to call get_variable
* directly so that we can tell it to do the right thing .
*/
*/
if ( tle - > expr & & IsA ( tle - > expr , Var ) )
if ( tle - > expr & & IsA ( tle - > expr , Var ) )
{
{
attname = get_variable ( ( Var * ) tle - > expr , 0 , fals e, context ) ;
attname = get_variable ( ( Var * ) tle - > expr , 0 , tru e, context ) ;
}
}
else
else
{
{
@ -3350,13 +3351,20 @@ push_plan(deparse_namespace *dpns, Plan *subplan)
* the Var ' s varlevelsup has to be interpreted with respect to a context
* the Var ' s varlevelsup has to be interpreted with respect to a context
* above the current one ; levelsup indicates the offset .
* above the current one ; levelsup indicates the offset .
*
*
* If showstar is TRUE , whole - row Vars are displayed as " foo.* " ;
* If istoplevel is TRUE , the Var is at the top level of a SELECT ' s
* if FALSE , merely as " foo " .
* targetlist , which means we need special treatment of whole - row Vars .
* Instead of the normal " tab.* " , we ' ll print " tab.*::typename " , which is a
* dirty hack to prevent " tab.* " from being expanded into multiple columns .
* ( The parser will strip the useless coercion , so no inefficiency is added in
* dump and reload . ) We used to print just " tab " in such cases , but that is
* ambiguous and will yield the wrong result if " tab " is also a plain column
* name in the query .
*
*
* Returns the attname of the Var , or NULL if not determinable .
* Returns the attname of the Var , or NULL if the Var has no attname ( because
* it is a whole - row Var ) .
*/
*/
static char *
static char *
get_variable ( Var * var , int levelsup , bool showstar , deparse_context * context )
get_variable ( Var * var , int levelsup , bool istoplevel , deparse_context * context )
{
{
StringInfo buf = context - > buf ;
StringInfo buf = context - > buf ;
RangeTblEntry * rte ;
RangeTblEntry * rte ;
@ -3492,10 +3500,16 @@ get_variable(Var *var, int levelsup, bool showstar, deparse_context *context)
if ( IsA ( aliasvar , Var ) )
if ( IsA ( aliasvar , Var ) )
{
{
return get_variable ( aliasvar , var - > varlevelsup + levelsup ,
return get_variable ( aliasvar , var - > varlevelsup + levelsup ,
showstar , context ) ;
istoplevel , context ) ;
}
}
}
}
/* Unnamed join has neither schemaname nor refname */
/*
* Unnamed join has neither schemaname nor refname . ( Note : since
* it ' s unnamed , there is no way the user could have referenced it
* to create a whole - row Var for it . So we don ' t have to cover
* that case below . )
*/
refname = NULL ;
refname = NULL ;
}
}
}
}
@ -3518,13 +3532,18 @@ get_variable(Var *var, int levelsup, bool showstar, deparse_context *context)
else
else
appendStringInfoString ( buf , quote_identifier ( refname ) ) ;
appendStringInfoString ( buf , quote_identifier ( refname ) ) ;
if ( attname | | showstar )
appendStringInfoChar ( buf , ' . ' ) ;
appendStringInfoChar ( buf , ' . ' ) ;
}
}
if ( attname )
if ( attname )
appendStringInfoString ( buf , quote_identifier ( attname ) ) ;
appendStringInfoString ( buf , quote_identifier ( attname ) ) ;
else if ( showstar )
else
{
appendStringInfoChar ( buf , ' * ' ) ;
appendStringInfoChar ( buf , ' * ' ) ;
if ( istoplevel )
appendStringInfo ( buf , " ::%s " ,
format_type_with_typemod ( var - > vartype ,
var - > vartypmod ) ) ;
}
return attname ;
return attname ;
}
}
@ -4274,7 +4293,7 @@ get_rule_expr(Node *node, deparse_context *context,
switch ( nodeTag ( node ) )
switch ( nodeTag ( node ) )
{
{
case T_Var :
case T_Var :
( void ) get_variable ( ( Var * ) node , 0 , tru e, context ) ;
( void ) get_variable ( ( Var * ) node , 0 , fals e, context ) ;
break ;
break ;
case T_Const :
case T_Const :