52
52
#define parser_yyerror (msg ) scanner_yyerror(msg, yyscanner)
53
53
#define parser_errposition (pos ) scanner_errposition(pos, yyscanner)
54
54
55
+ /* Private struct for the result of privilege_target production */
56
+ typedef struct PrivTarget
57
+ {
58
+ GrantTargetType targtype;
59
+ ObjectType objtype;
60
+ List *objs;
61
+ } PrivTarget;
62
+
63
+ /* Private struct for the result of import_qualification production */
64
+ typedef struct ImportQual
65
+ {
66
+ ImportForeignSchemaType type;
67
+ List *table_names;
68
+ } ImportQual;
69
+
70
+ /* Private struct for the result of opt_select_limit production */
71
+ typedef struct SelectLimit
72
+ {
73
+ Node *limitOffset;
74
+ Node *limitCount;
75
+ LimitOption limitOption;
76
+ } SelectLimit;
77
+
55
78
/* Private struct for the result of group_clause production */
56
79
typedef struct GroupClause
57
80
{
58
81
bool distinct;
59
82
List *list;
60
83
} GroupClause;
61
84
85
+ static void insertSelectOptions (SelectStmt *stmt,
86
+ List *sortClause, List *lockingClause,
87
+ SelectLimit *limitClause,
88
+ WithClause *withClause,
89
+ ag_scanner_t yyscanner);
62
90
%}
63
91
64
92
%locations
@@ -91,6 +119,7 @@ typedef struct GroupClause
91
119
struct ResTarget *target;
92
120
struct Alias *alias;
93
121
struct GroupClause *groupclause;
122
+ struct SortBy *sortby;
94
123
}
95
124
96
125
%token <integer> INTEGER
@@ -100,7 +129,6 @@ typedef struct GroupClause
100
129
%token <string> INET
101
130
%token <string> PARAMETER
102
131
%token <string> OPERATOR
103
-
104
132
/* operators that have more than 1 character */
105
133
%token NOT_EQ LT_EQ GT_EQ DOT_DOT TYPECAST PLUS_EQ
106
134
@@ -227,6 +255,7 @@ typedef struct GroupClause
227
255
OptWith
228
256
qualified_name_list
229
257
reloption_list
258
+ sort_clause opt_sort_clause sortby_list
230
259
from_clause from_list
231
260
target_list opt_target_list
232
261
opt_collate
@@ -238,8 +267,8 @@ typedef struct GroupClause
238
267
%type <string> NonReservedWord_or_Sconst name
239
268
%type <list> create_extension_opt_list
240
269
%type <defelt> create_extension_opt_item
241
-
242
- %type <integer> OptTemp
270
+ %type <sortby> sortby
271
+ %type <integer> OptTemp opt_asc_desc
243
272
244
273
%type <typnam> Typename SimpleTypename GenericType func_type
245
274
@@ -436,59 +465,59 @@ select_with_parens:
436
465
*/
437
466
select_no_parens :
438
467
simple_select { $$ = $1 ; }
439
- /* | select_clause sort_clause
468
+ | select_clause sort_clause
440
469
{
441
470
insertSelectOptions ((SelectStmt *) $1, $2, NIL,
442
471
NULL, NULL,
443
- yyscanner );
472
+ scanner );
444
473
$$ = $1 ;
445
474
}
446
- | select_clause opt_sort_clause for_locking_clause opt_select_limit
475
+ /* | select_clause opt_sort_clause for_locking_clause opt_select_limit
447
476
{
448
477
insertSelectOptions((SelectStmt *) $1, $2, $3,
449
478
$4,
450
479
NULL,
451
- yyscanner );
480
+ scanner );
452
481
$$ = $1;
453
482
}
454
483
| select_clause opt_sort_clause select_limit opt_for_locking_clause
455
484
{
456
485
insertSelectOptions((SelectStmt *) $1, $2, $4,
457
486
$3,
458
487
NULL,
459
- yyscanner );
488
+ scanner );
460
489
$$ = $1;
461
490
}
462
491
| with_clause select_clause
463
492
{
464
493
insertSelectOptions((SelectStmt *) $2, NULL, NIL,
465
494
NULL,
466
495
$1,
467
- yyscanner );
496
+ scanner );
468
497
$$ = $2;
469
498
}
470
499
| with_clause select_clause sort_clause
471
500
{
472
501
insertSelectOptions((SelectStmt *) $2, $3, NIL,
473
502
NULL,
474
503
$1,
475
- yyscanner );
504
+ scanner );
476
505
$$ = $2;
477
506
}
478
507
| with_clause select_clause opt_sort_clause for_locking_clause opt_select_limit
479
508
{
480
509
insertSelectOptions((SelectStmt *) $2, $3, $4,
481
510
$5,
482
511
$1,
483
- yyscanner );
512
+ scanner );
484
513
$$ = $2;
485
514
}
486
515
| with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause
487
516
{
488
517
insertSelectOptions((SelectStmt *) $2, $3, $5,
489
518
$4,
490
519
$1,
491
- yyscanner );
520
+ scanner );
492
521
$$ = $2;
493
522
}*/
494
523
;
@@ -875,6 +904,40 @@ where_clause:
875
904
| /* EMPTY*/ { $$ = NULL ; }
876
905
;
877
906
907
+ opt_sort_clause :
908
+ sort_clause { $$ = $1 ; }
909
+ | /* EMPTY*/ { $$ = NIL; }
910
+ ;
911
+
912
+ sort_clause :
913
+ ORDER BY sortby_list { $$ = $3 ; }
914
+ ;
915
+
916
+ sortby_list :
917
+ sortby { $$ = list_make1($1 ); }
918
+ | sortby_list ' ,' sortby { $$ = lappend($1 , $3 ); }
919
+ ;
920
+
921
+ sortby : a_expr USING all_op opt_nulls_order
922
+ {
923
+ $$ = makeNode(SortBy);
924
+ $$ ->node = $1 ;
925
+ $$ ->sortby_dir = SORTBY_USING;
926
+ $$ ->sortby_nulls = $4 ;
927
+ $$ ->useOp = $3 ;
928
+ $$ ->location = @3 ;
929
+ }
930
+ | a_expr opt_asc_desc opt_nulls_order
931
+ {
932
+ $$ = makeNode(SortBy);
933
+ $$ ->node = $1 ;
934
+ $$ ->sortby_dir = $2 ;
935
+ $$ ->sortby_nulls = $3 ;
936
+ $$ ->useOp = NIL;
937
+ $$ ->location = -1 ; /* no operator */
938
+ }
939
+ ;
940
+
878
941
CreateGraphStmt :
879
942
CREATE GRAPH IDENTIFIER
880
943
{
@@ -1394,6 +1457,12 @@ return_item:
1394
1457
}
1395
1458
;
1396
1459
1460
+ opt_asc_desc : ASC { $$ = SORTBY_ASC; }
1461
+ | DESC { $$ = SORTBY_DESC; }
1462
+ | /* EMPTY*/ { $$ = SORTBY_DEFAULT; }
1463
+ ;
1464
+
1465
+
1397
1466
opt_nulls_order : NULLS_LA FIRST_P { $$ = SORTBY_NULLS_FIRST; }
1398
1467
| NULLS_LA LAST_P { $$ = SORTBY_NULLS_LAST; }
1399
1468
| /* EMPTY*/ { $$ = SORTBY_NULLS_DEFAULT; }
@@ -1686,7 +1755,7 @@ Iconst: INTEGER { $$ = $1; };
1686
1755
/* Note: any simple identifier will be returned as a type name! */
1687
1756
def_arg : func_type { $$ = (Node *)$1 ; }
1688
1757
//| reserved_keyword { $$ = (Node *)makeString(pstrdup($1 )); }
1689
- // | qual_all_Op { $$ = (Node *)$1 ; }
1758
+ | all_op { $$ = (Node *)$1 ; }
1690
1759
| NumericOnly { $$ = (Node *)$1 ; }
1691
1760
| Sconst { $$ = (Node *)makeString($1 ); }
1692
1761
//| NONE { $$ = (Node *)makeString(pstrdup($1 )); }
@@ -4543,3 +4612,87 @@ doNegate(Node *n, int location)
4543
4612
return (Node *) makeSimpleA_Expr(AEXPR_OP, "-", NULL, n, location);
4544
4613
}
4545
4614
4615
+ /* insertSelectOptions()
4616
+ * Insert ORDER BY, etc into an already-constructed SelectStmt.
4617
+ *
4618
+ * This routine is just to avoid duplicating code in SelectStmt productions.
4619
+ */
4620
+ static void
4621
+ insertSelectOptions(SelectStmt *stmt,
4622
+ List *sortClause, List *lockingClause,
4623
+ SelectLimit *limitClause,
4624
+ WithClause *withClause,
4625
+ ag_scanner_t yyscanner)
4626
+ {
4627
+ Assert(IsA(stmt, SelectStmt));
4628
+
4629
+ /*
4630
+ * Tests here are to reject constructs like
4631
+ * (SELECT foo ORDER BY bar) ORDER BY baz
4632
+ */
4633
+ if (sortClause)
4634
+ {
4635
+ if (stmt->sortClause)
4636
+ ereport(ERROR,
4637
+ (errcode(ERRCODE_SYNTAX_ERROR),
4638
+ errmsg("multiple ORDER BY clauses not allowed"),
4639
+ parser_errposition(exprLocation((Node *) sortClause))));
4640
+ stmt->sortClause = sortClause;
4641
+ }
4642
+ /* We can handle multiple locking clauses, though */
4643
+ stmt->lockingClause = list_concat(stmt->lockingClause, lockingClause);
4644
+ if (limitClause && limitClause->limitOffset)
4645
+ {
4646
+ if (stmt->limitOffset)
4647
+ ereport(ERROR,
4648
+ (errcode(ERRCODE_SYNTAX_ERROR),
4649
+ errmsg("multiple OFFSET clauses not allowed"),
4650
+ parser_errposition(exprLocation(limitClause->limitOffset))));
4651
+ stmt->limitOffset = limitClause->limitOffset;
4652
+ }
4653
+ if (limitClause && limitClause->limitCount)
4654
+ {
4655
+ if (stmt->limitCount)
4656
+ ereport(ERROR,
4657
+ (errcode(ERRCODE_SYNTAX_ERROR),
4658
+ errmsg("multiple LIMIT clauses not allowed"),
4659
+ parser_errposition(exprLocation(limitClause->limitCount))));
4660
+ stmt->limitCount = limitClause->limitCount;
4661
+ }
4662
+ if (limitClause && limitClause->limitOption != LIMIT_OPTION_DEFAULT)
4663
+ {
4664
+ if (stmt->limitOption)
4665
+ ereport(ERROR,
4666
+ (errcode(ERRCODE_SYNTAX_ERROR),
4667
+ errmsg("multiple limit options not allowed")));
4668
+ if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES)
4669
+ ereport(ERROR,
4670
+ (errcode(ERRCODE_SYNTAX_ERROR),
4671
+ errmsg("WITH TIES cannot be specified without ORDER BY clause")));
4672
+ if (limitClause->limitOption == LIMIT_OPTION_WITH_TIES && stmt->lockingClause)
4673
+ {
4674
+ ListCell *lc;
4675
+
4676
+ foreach(lc, stmt->lockingClause)
4677
+ {
4678
+ LockingClause *lock = lfirst_node(LockingClause, lc);
4679
+
4680
+ if (lock->waitPolicy == LockWaitSkip)
4681
+ ereport(ERROR,
4682
+ (errcode(ERRCODE_SYNTAX_ERROR),
4683
+ errmsg("%s and %s options cannot be used together",
4684
+ "SKIP LOCKED", "WITH TIES")));
4685
+ }
4686
+ }
4687
+ stmt->limitOption = limitClause->limitOption;
4688
+ }
4689
+ if (withClause)
4690
+ {
4691
+ if (stmt->withClause)
4692
+ ereport(ERROR,
4693
+ (errcode(ERRCODE_SYNTAX_ERROR),
4694
+ errmsg("multiple WITH clauses not allowed"),
4695
+ parser_errposition(exprLocation((Node *) withClause))));
4696
+ stmt->withClause = withClause;
4697
+ }
4698
+ }
0 commit comments