Skip to content

Commit 7d8171f

Browse files
committed
Merge branch 'main' of https://github.com/hyrise/sql-parser into lukas/better-csv-import
2 parents 9c638a7 + 0663319 commit 7d8171f

File tree

7 files changed

+1684
-1589
lines changed

7 files changed

+1684
-1589
lines changed

src/parser/bison_parser.cpp

Lines changed: 1634 additions & 1581 deletions
Large diffs are not rendered by default.

src/parser/bison_parser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ union HSQL_STYPE
318318
hsql::LockingClause* locking_t;
319319
hsql::OrderDescription* order;
320320
hsql::OrderType order_type;
321+
hsql::NullOrdering null_ordering_t;
321322
hsql::ReferencesSpecification* references_spec_t;
322323
hsql::SetOperation* set_operator_t;
323324
hsql::TableConstraint* table_constraint_t;
@@ -348,7 +349,7 @@ union HSQL_STYPE
348349

349350
// clang-format off
350351

351-
#line 352 "bison_parser.h"
352+
#line 353 "bison_parser.h"
352353

353354
};
354355
typedef union HSQL_STYPE HSQL_STYPE;

src/parser/bison_parser.y

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
hsql::LockingClause* locking_t;
143143
hsql::OrderDescription* order;
144144
hsql::OrderType order_type;
145+
hsql::NullOrdering null_ordering_t;
145146
hsql::ReferencesSpecification* references_spec_t;
146147
hsql::SetOperation* set_operator_t;
147148
hsql::TableConstraint* table_constraint_t;
@@ -177,7 +178,7 @@
177178
** Destructor symbols
178179
*********************************/
179180

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>
181182
%destructor {
182183
free($$.name);
183184
free($$.schema);
@@ -272,6 +273,7 @@
272273
%type <limit> opt_limit opt_top
273274
%type <order> order_desc
274275
%type <order_type> opt_order_type
276+
%type <null_ordering_t> opt_null_ordering
275277
%type <datetime_field> datetime_field datetime_field_plural duration_field
276278
%type <column_t> column_def
277279
%type <table_element_t> table_elem
@@ -1019,12 +1021,33 @@ order_list : order_desc {
10191021
$$ = $1;
10201022
};
10211023

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); };
10231025

10241026
opt_order_type : ASC { $$ = kOrderAsc; }
10251027
| DESC { $$ = kOrderDesc; }
10261028
| /* empty */ { $$ = kOrderAsc; };
10271029

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+
10281051
// TODO: TOP and LIMIT can take more than just int literals.
10291052

10301053
opt_top : TOP int_literal { $$ = new LimitDescription($2, nullptr); }

src/sql/SelectStatement.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace hsql {
99
enum OrderType { kOrderAsc, kOrderDesc };
10+
enum NullOrdering { Undefined, First, Last };
1011

1112
enum SetType { kSetUnion, kSetIntersect, kSetExcept };
1213

@@ -15,11 +16,12 @@ enum RowLockWaitPolicy { NoWait, SkipLocked, None };
1516

1617
// Description of the order by clause within a select statement.
1718
struct OrderDescription {
18-
OrderDescription(OrderType type, Expr* expr);
19+
OrderDescription(OrderType type, Expr* expr, NullOrdering null_ordering);
1920
virtual ~OrderDescription();
2021

2122
OrderType type;
2223
Expr* expr;
24+
NullOrdering null_ordering;
2325
};
2426

2527
// Description of the limit clause within a select statement.

src/sql/statements.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ ShowStatement::~ShowStatement() {
246246
// SelectStatement.h
247247

248248
// OrderDescription
249-
OrderDescription::OrderDescription(OrderType type, Expr* expr) : type(type), expr(expr) {}
249+
OrderDescription::OrderDescription(OrderType type, Expr* expr, NullOrdering null_ordering)
250+
: type(type), expr(expr), null_ordering(null_ordering) {}
250251

251252
OrderDescription::~OrderDescription() { delete expr; }
252253

test/queries/queries-bad.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@
9393
!SELECT * FROM foo WITH HINT (?);
9494
!SELECT * FROM foo WITH HINT (CAST(column_a AS INT));
9595
!SELECT * FROM foo WITH HINT (AVG(another_column));
96+
# ORDER BY with NULL ordering.
97+
!SELECT * FROM students ORDER BY name ASC NULL FIRST;
98+
!SELECT * FROM students ORDER BY name ASC gibberish LAST;
99+
!SELECT * FROM students ORDER BY name NULLS FIRS;
100+
!SELECT * FROM students ORDER BY name NULLS;
101+
!SELECT * FROM students ORDER BY name ASC NULLS;
102+
!SELECT * FROM students ORDER BY name FIRST;
103+
!SELECT * FROM students ORDER BY name ASC LAST;
104+
!SELECT * FROM students ORDER BY name DESC NULLS gibberish;
96105
# CSV options
97106
!COPY students FROM 'file_path' WITH (FORMAT TBL, DELIMITER '|', NULL '', QUOTE '"');
98107
!COPY students FROM 'file_path' WITH (DELIMITER '|', NULL '', QUOTE '"', FORMAT TBL);

test/select_tests.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,24 @@ TEST(SelectGroupDistinctTest) {
172172
}
173173

174174
TEST(OrderByTest) {
175-
TEST_PARSE_SINGLE_SQL("SELECT grade, city FROM students ORDER BY grade, city DESC;", kStmtSelect, SelectStatement,
176-
result, stmt);
175+
TEST_PARSE_SINGLE_SQL("SELECT grade, city FROM students ORDER BY grade, city DESC NULLS FIRST, name NULLS LAST;",
176+
kStmtSelect, SelectStatement, result, stmt);
177177

178178
ASSERT_NULL(stmt->whereClause);
179179
ASSERT_NOTNULL(stmt->order);
180180

181-
ASSERT_EQ(stmt->order->size(), 2);
181+
ASSERT_EQ(stmt->order->size(), 3);
182182
ASSERT_EQ(stmt->order->at(0)->type, kOrderAsc);
183183
ASSERT_STREQ(stmt->order->at(0)->expr->name, "grade");
184+
ASSERT_EQ(stmt->order->at(0)->null_ordering, NullOrdering::Undefined);
184185

185186
ASSERT_EQ(stmt->order->at(1)->type, kOrderDesc);
186187
ASSERT_STREQ(stmt->order->at(1)->expr->name, "city");
188+
ASSERT_EQ(stmt->order->at(1)->null_ordering, NullOrdering::First);
189+
190+
ASSERT_EQ(stmt->order->at(2)->type, kOrderAsc);
191+
ASSERT_STREQ(stmt->order->at(2)->expr->name, "name");
192+
ASSERT_EQ(stmt->order->at(2)->null_ordering, NullOrdering::Last);
187193
}
188194

189195
TEST(SelectBetweenTest) {

0 commit comments

Comments
 (0)