Skip to content

Commit

Permalink
fix #1. Queries support an order clause and limit clause.
Browse files Browse the repository at this point in the history
  • Loading branch information
jvshahid committed Oct 11, 2013
1 parent 647d09c commit 9416b22
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 18 deletions.
3 changes: 2 additions & 1 deletion src/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ type Query struct {
Condition *WhereCondition
groupByClause GroupByClause
Limit int
Ascending bool
}

func (self *Query) GetColumnNames() []*Value {
Expand Down Expand Up @@ -250,5 +251,5 @@ func ParseQuery(query string) (*Query, error) {
C.close_query(&q)
return nil, err
}
return &Query{q, false, nil, nil, nil, int(q.limit)}, err
return &Query{q, false, nil, nil, nil, int(q.limit), q.ascending != 0}, err
}
19 changes: 14 additions & 5 deletions src/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,16 +274,25 @@ func (self *QueryParserSuite) TestParseWhereClauseParantheses(c *C) {
c.Assert(third.Operation, Equals, "<")
}

func (self *QueryParserSuite) TestParseSelectWithLast(c *C) {
q, err := ParseQuery("select value from t last 10;")
func (self *QueryParserSuite) TestParseSelectWithOrderByAndLimit(c *C) {
q, err := ParseQuery("select value from t order asc limit 10;")
defer q.Close()
c.Assert(err, IsNil)
c.Assert(q.Limit, Equals, -10)
c.Assert(q.Limit, Equals, 10)
c.Assert(q.Ascending, Equals, true)

q, err = ParseQuery("select value from t first 10;")
q, err = ParseQuery("select value from t order desc;")
defer q.Close()
c.Assert(err, IsNil)
c.Assert(q.Limit, Equals, 10)
c.Assert(q.Limit, Equals, 0)
c.Assert(q.Ascending, Equals, false)

q, err = ParseQuery("select value from t limit 20;")
defer q.Close()
c.Assert(err, IsNil)
c.Assert(q.Limit, Equals, 20)
// ascending is the default
c.Assert(q.Ascending, Equals, true)
}

func (self *QueryParserSuite) TestParseFromWithNestedFunctions2(c *C) {
Expand Down
4 changes: 4 additions & 0 deletions src/parser/query.lex
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ last { return LAST; }
from { return FROM; }
where { return WHERE; }
select { return SELECT; }
limit { return LIMIT; }
order { return ORDER; }
asc { return ASC; }
desc { return DESC; }
group { return GROUP; }
by { return BY; }
"(" { yylval->character = *yytext; return *yytext; }
Expand Down
54 changes: 42 additions & 12 deletions src/parser/query.yacc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ expression *create_expression(expression *left, char op, expression *right) {
expression* expression;
value_array* value_array;
value* v;
struct {
int limit;
char ascending;
} limit_and_order;
}

// debugging
Expand All @@ -41,7 +45,7 @@ expression *create_expression(expression *left, char op, expression *right) {
%lex-param {void *scanner}

// define types of tokens (terminals)
%token SELECT FROM WHERE EQUAL GROUP BY FIRST LAST
%token SELECT FROM WHERE EQUAL GROUP BY FIRST LAST LIMIT ORDER ASC DESC
%token <string> STRING_VALUE INT_VALUE NAME REGEX_OP REGEX_STRING

// define the precendence of these operators
Expand All @@ -63,7 +67,9 @@ expression *create_expression(expression *left, char op, expression *right) {
%type <v> FUNCTION_CALL
%type <expression> EXPRESSION
%type <value_array> GROUP_BY_CLAUSE
%type <integer> LIMIT
%type <integer> LIMIT_CLAUSE
%type <character> ORDER_CLAUSE
%type <limit_and_order> LIMIT_AND_ORDER_CLAUSES

// the initial token
%start QUERY
Expand All @@ -78,34 +84,58 @@ expression *create_expression(expression *left, char op, expression *right) {
// grammar
%%
QUERY:
SELECT COLUMN_NAMES FROM_CLAUSE GROUP_BY_CLAUSE WHERE_CLAUSE LIMIT ';'
SELECT COLUMN_NAMES FROM_CLAUSE GROUP_BY_CLAUSE WHERE_CLAUSE LIMIT_AND_ORDER_CLAUSES ';'
{
q->c = $2;
q->f = $3;
q->group_by = $4;
q->where_condition = $5;
q->limit = $6;
q->limit = $6.limit;
q->ascending = $6.ascending;
}
|
SELECT COLUMN_NAMES FROM_CLAUSE WHERE_CLAUSE GROUP_BY_CLAUSE LIMIT ';'
SELECT COLUMN_NAMES FROM_CLAUSE WHERE_CLAUSE GROUP_BY_CLAUSE LIMIT_AND_ORDER_CLAUSES ';'
{
q->c = $2;
q->f = $3;
q->where_condition = $4;
q->group_by = $5;
q->limit = $6;
q->limit = $6.limit;
q->ascending = $6.ascending;
}

LIMIT:
FIRST INT_VALUE
LIMIT_AND_ORDER_CLAUSES:
ORDER_CLAUSE LIMIT_CLAUSE
{
$$ = atoi($2);
free($2);
$$.limit = $2;
$$.ascending = $1;
}
|
LIMIT_CLAUSE ORDER_CLAUSE
{
$$.limit = $1;
$$.ascending = $2;
}

ORDER_CLAUSE:
ORDER ASC
{
$$ = TRUE;
}
|
LAST INT_VALUE
ORDER DESC
{
$$ = -atoi($2);
$$ = FALSE;
}
|
{
$$ = TRUE;
}

LIMIT_CLAUSE:
LIMIT INT_VALUE
{
$$ = atoi($2);
free($2);
}
|
Expand Down
1 change: 1 addition & 0 deletions src/parser/query_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ typedef struct {
condition *where_condition;
error *error;
int limit;
char ascending;
} query;

// some funcs for freeing our types
Expand Down

0 comments on commit 9416b22

Please sign in to comment.