@ -134,6 +134,13 @@ typedef struct SelectLimit
LimitOption limitOption;
LimitOption limitOption;
} SelectLimit;
} SelectLimit;
/* Private struct for the result of group_clause production */
typedef struct GroupClause
{
bool distinct;
List *list;
} GroupClause;
/* ConstraintAttributeSpec yields an integer bitmask of these flags: */
/* ConstraintAttributeSpec yields an integer bitmask of these flags: */
#define CAS_NOT_DEFERRABLE 0x01
#define CAS_NOT_DEFERRABLE 0x01
#define CAS_DEFERRABLE 0x02
#define CAS_DEFERRABLE 0x02
@ -250,6 +257,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
PartitionBoundSpec *partboundspec;
PartitionBoundSpec *partboundspec;
RoleSpec *rolespec;
RoleSpec *rolespec;
struct SelectLimit *selectlimit;
struct SelectLimit *selectlimit;
SetQuantifier setquantifier;
struct GroupClause *groupclause;
}
}
%type <node> stmt schema_stmt
%type <node> stmt schema_stmt
@ -405,7 +414,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
target_list opt_target_list insert_column_list set_target_list
target_list opt_target_list insert_column_list set_target_list
set_clause_list set_clause
set_clause_list set_clause
def_list operator_def_list indirection opt_indirection
def_list operator_def_list indirection opt_indirection
reloption_list group_clause TriggerFuncArgs opclass_item_list opclass_drop_list
reloption_list TriggerFuncArgs opclass_item_list opclass_drop_list
opclass_purpose opt_opfamily transaction_mode_list_or_empty
opclass_purpose opt_opfamily transaction_mode_list_or_empty
OptTableFuncElementList TableFuncElementList opt_type_modifiers
OptTableFuncElementList TableFuncElementList opt_type_modifiers
prep_type_clause
prep_type_clause
@ -418,6 +427,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
vacuum_relation_list opt_vacuum_relation_list
vacuum_relation_list opt_vacuum_relation_list
drop_option_list
drop_option_list
%type <groupclause> group_clause
%type <list> group_by_list
%type <list> group_by_list
%type <node> group_by_item empty_grouping_set rollup_clause cube_clause
%type <node> group_by_item empty_grouping_set rollup_clause cube_clause
%type <node> grouping_sets_clause
%type <node> grouping_sets_clause
@ -443,7 +453,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <node> for_locking_item
%type <node> for_locking_item
%type <list> for_locking_clause opt_for_locking_clause for_locking_items
%type <list> for_locking_clause opt_for_locking_clause for_locking_items
%type <list> locked_rels_list
%type <list> locked_rels_list
%type <boolean> all_or_distinct
%type <setquantifier> set_quantifier
%type <node> join_qual
%type <node> join_qual
%type <jtype> join_type
%type <jtype> join_type
@ -11294,7 +11304,8 @@ simple_select:
n->intoClause = $4;
n->intoClause = $4;
n->fromClause = $5;
n->fromClause = $5;
n->whereClause = $6;
n->whereClause = $6;
n->groupClause = $7;
n->groupClause = ($7)->list;
n->groupDistinct = ($7)->distinct;
n->havingClause = $8;
n->havingClause = $8;
n->windowClause = $9;
n->windowClause = $9;
$$ = (Node *)n;
$$ = (Node *)n;
@ -11309,7 +11320,8 @@ simple_select:
n->intoClause = $4;
n->intoClause = $4;
n->fromClause = $5;
n->fromClause = $5;
n->whereClause = $6;
n->whereClause = $6;
n->groupClause = $7;
n->groupClause = ($7)->list;
n->groupDistinct = ($7)->distinct;
n->havingClause = $8;
n->havingClause = $8;
n->windowClause = $9;
n->windowClause = $9;
$$ = (Node *)n;
$$ = (Node *)n;
@ -11334,17 +11346,17 @@ simple_select:
n->fromClause = list_make1($2);
n->fromClause = list_make1($2);
$$ = (Node *)n;
$$ = (Node *)n;
}
}
| select_clause UNION all_or_distinct select_clause
| select_clause UNION set_quantifier select_clause
{
{
$$ = makeSetOp(SETOP_UNION, $3, $1, $4);
$$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL , $1, $4);
}
}
| select_clause INTERSECT all_or_distinct select_clause
| select_clause INTERSECT set_quantifier select_clause
{
{
$$ = makeSetOp(SETOP_INTERSECT, $3, $1, $4);
$$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL , $1, $4);
}
}
| select_clause EXCEPT all_or_distinct select_clause
| select_clause EXCEPT set_quantifier select_clause
{
{
$$ = makeSetOp(SETOP_EXCEPT, $3, $1, $4);
$$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL , $1, $4);
}
}
;
;
@ -11542,10 +11554,10 @@ opt_table: TABLE
| /*EMPTY*/
| /*EMPTY*/
;
;
all_or_distinct :
set_quantifier :
ALL { $$ = true ; }
ALL { $$ = SET_QUANTIFIER_ALL ; }
| DISTINCT { $$ = false ; }
| DISTINCT { $$ = SET_QUANTIFIER_DISTINCT ; }
| /*EMPTY*/ { $$ = false ; }
| /*EMPTY*/ { $$ = SET_QUANTIFIER_DEFAULT ; }
;
;
/* We use (NIL) as a placeholder to indicate that all target expressions
/* We use (NIL) as a placeholder to indicate that all target expressions
@ -11771,8 +11783,20 @@ first_or_next: FIRST_P { $$ = 0; }
* GroupingSet node of some type.
* GroupingSet node of some type.
*/
*/
group_clause:
group_clause:
GROUP_P BY group_by_list { $$ = $3; }
GROUP_P BY set_quantifier group_by_list
| /*EMPTY*/ { $$ = NIL; }
{
GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause));
n->distinct = $3 == SET_QUANTIFIER_DISTINCT;
n->list = $4;
$$ = n;
}
| /*EMPTY*/
{
GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause));
n->distinct = false;
n->list = NIL;
$$ = n;
}
;
;
group_by_list:
group_by_list:
@ -15145,7 +15169,8 @@ PLpgSQL_Expr: opt_distinct_clause opt_target_list
n->targetList = $2;
n->targetList = $2;
n->fromClause = $3;
n->fromClause = $3;
n->whereClause = $4;
n->whereClause = $4;
n->groupClause = $5;
n->groupClause = ($5)->list;
n->groupDistinct = ($5)->distinct;
n->havingClause = $6;
n->havingClause = $6;
n->windowClause = $7;
n->windowClause = $7;
n->sortClause = $8;
n->sortClause = $8;