|
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; |
|
176 | 177 | ** Destructor symbols |
177 | 178 | *********************************/ |
178 | 179 |
|
179 | | -%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> |
| 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> <null_ordering_t> |
180 | 181 | %destructor { |
181 | 182 | free($$.name); |
182 | 183 | free($$.schema); |
|
270 | 271 | %type <limit> opt_limit opt_top |
271 | 272 | %type <order> order_desc |
272 | 273 | %type <order_type> opt_order_type |
| 274 | +%type <null_ordering_t> opt_null_ordering |
273 | 275 | %type <datetime_field> datetime_field datetime_field_plural duration_field |
274 | 276 | %type <column_t> column_def |
275 | 277 | %type <table_element_t> table_elem |
@@ -953,12 +955,33 @@ order_list : order_desc { |
953 | 955 | $$ = $1; |
954 | 956 | }; |
955 | 957 |
|
956 | | -order_desc : expr opt_order_type { $$ = new OrderDescription($2, $1); }; |
| 958 | +order_desc : expr opt_order_type opt_null_ordering { $$ = new OrderDescription($2, $1, $3); }; |
957 | 959 |
|
958 | 960 | opt_order_type : ASC { $$ = kOrderAsc; } |
959 | 961 | | DESC { $$ = kOrderDesc; } |
960 | 962 | | /* empty */ { $$ = kOrderAsc; }; |
961 | 963 |
|
| 964 | +opt_null_ordering : /* empty */ { $$ = NullOrdering::Undefined; } |
| 965 | +| IDENTIFIER IDENTIFIER { |
| 966 | + auto null_ordering = NullOrdering::Undefined; |
| 967 | + if (strcasecmp($1, "nulls") == 0) { |
| 968 | + if (strcasecmp($2, "first") == 0) { |
| 969 | + null_ordering = NullOrdering::First; |
| 970 | + } else if (strcasecmp($2, "last") == 0) { |
| 971 | + null_ordering = NullOrdering::Last; |
| 972 | + } |
| 973 | + } |
| 974 | + free($1); |
| 975 | + free($2); |
| 976 | + |
| 977 | + if (null_ordering == NullOrdering::Undefined) { |
| 978 | + yyerror(&yyloc, result, scanner, "Expected NULLS FIRST or NULLS LAST ordering."); |
| 979 | + YYERROR; |
| 980 | + } |
| 981 | + |
| 982 | + $$ = null_ordering; |
| 983 | +}; |
| 984 | + |
962 | 985 | // TODO: TOP and LIMIT can take more than just int literals. |
963 | 986 |
|
964 | 987 | opt_top : TOP int_literal { $$ = new LimitDescription($2, nullptr); } |
|
0 commit comments