|
142 | 142 | hsql::LockingClause* locking_t; |
143 | 143 | hsql::OrderDescription* order; |
144 | 144 | hsql::OrderType order_type; |
| 145 | + hsql::NullOrdering null_ordering_t; |
145 | 146 | hsql::ReferencesSpecification* references_spec_t; |
146 | 147 | hsql::SetOperation* set_operator_t; |
147 | 148 | hsql::TableConstraint* table_constraint_t; |
|
177 | 178 | ** Destructor symbols |
178 | 179 | *********************************/ |
179 | 180 |
|
180 | | -%destructor { } <fval> <ival> <bval> <join_type> <order_type> <datetime_field> <column_type_t> <column_constraint_t> <import_type_t> <lock_mode_t> <lock_wait_policy_t> <frame_type> |
| 181 | +%destructor { } <fval> <ival> <bval> <join_type> <order_type> <datetime_field> <column_type_t> <column_constraint_t> <import_type_t> <lock_mode_t> <lock_wait_policy_t> <frame_type> <null_ordering_t> |
181 | 182 | %destructor { |
182 | 183 | free($$.name); |
183 | 184 | free($$.schema); |
|
272 | 273 | %type <limit> opt_limit opt_top |
273 | 274 | %type <order> order_desc |
274 | 275 | %type <order_type> opt_order_type |
| 276 | +%type <null_ordering_t> opt_null_ordering |
275 | 277 | %type <datetime_field> datetime_field datetime_field_plural duration_field |
276 | 278 | %type <column_t> column_def |
277 | 279 | %type <table_element_t> table_elem |
@@ -1019,12 +1021,33 @@ order_list : order_desc { |
1019 | 1021 | $$ = $1; |
1020 | 1022 | }; |
1021 | 1023 |
|
1022 | | -order_desc : expr opt_order_type { $$ = new OrderDescription($2, $1); }; |
| 1024 | +order_desc : expr opt_order_type opt_null_ordering { $$ = new OrderDescription($2, $1, $3); }; |
1023 | 1025 |
|
1024 | 1026 | opt_order_type : ASC { $$ = kOrderAsc; } |
1025 | 1027 | | DESC { $$ = kOrderDesc; } |
1026 | 1028 | | /* empty */ { $$ = kOrderAsc; }; |
1027 | 1029 |
|
| 1030 | +opt_null_ordering : /* empty */ { $$ = NullOrdering::Undefined; } |
| 1031 | +| IDENTIFIER IDENTIFIER { |
| 1032 | + auto null_ordering = NullOrdering::Undefined; |
| 1033 | + if (strcasecmp($1, "nulls") == 0) { |
| 1034 | + if (strcasecmp($2, "first") == 0) { |
| 1035 | + null_ordering = NullOrdering::First; |
| 1036 | + } else if (strcasecmp($2, "last") == 0) { |
| 1037 | + null_ordering = NullOrdering::Last; |
| 1038 | + } |
| 1039 | + } |
| 1040 | + free($1); |
| 1041 | + free($2); |
| 1042 | + |
| 1043 | + if (null_ordering == NullOrdering::Undefined) { |
| 1044 | + yyerror(&yyloc, result, scanner, "Expected NULLS FIRST or NULLS LAST ordering."); |
| 1045 | + YYERROR; |
| 1046 | + } |
| 1047 | + |
| 1048 | + $$ = null_ordering; |
| 1049 | +}; |
| 1050 | + |
1028 | 1051 | // TODO: TOP and LIMIT can take more than just int literals. |
1029 | 1052 |
|
1030 | 1053 | opt_top : TOP int_literal { $$ = new LimitDescription($2, nullptr); } |
|
0 commit comments