Skip to content

Commit

Permalink
feat: init sql parser
Browse files Browse the repository at this point in the history
From so far, the sql parser supports:
  - CREATE TABLE `tbl` (col1 int(16), col2 char(16));
  - SELECT * FROM `tbl`;
  - SELECT `col1, col2` FROM `tbl`;
  - SELECT * FROM WHERE `cond1` AND `cond2` AND `cond3` OR `cond4`;
  - SELECT `col1, col2` FROM WHERE `c1 AND c2 OR c3`;

TODO: free the resource in `selectsql` BNF
  • Loading branch information
sinkinben committed Jan 28, 2022
1 parent 10d6e19 commit 3983d2f
Show file tree
Hide file tree
Showing 5 changed files with 415 additions and 0 deletions.
73 changes: 73 additions & 0 deletions sqlparser/condition.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "sql.h"
#ifndef __CONDITION_H__
#define __CONDITION_H__
typedef enum
{
OP_EQUAL,
OP_GREAT,
OP_GREAT_EQUAL,
OP_LESS,
OP_LESS_EQUAL,
OP_NOT_EQUAL,
OP_AND,
OP_OR
} operator_t;

/**
* A condition_t denote: `lvalue op rvalue`,
* 1) `lvalue` is always the column name.
* 2) `rvalue` could be a integer or a string.
* 3) When is_leaf = 1, then we should use lvalue/rvalue.
* 4) When is_leaf = 0, then we should use lchild/rchild.
*/
struct condition_t
{
operator_t op;
bool is_leaf;
union
{
struct condition_t *lchild;
schema_t *lvalue;
};
union
{
struct condition_t *rchild;
union
{
uint64_t intval;
char *strval;
} rvalue;
};
};
typedef struct condition_t condition_t;

static condition_t *alloc_condition(uint64_t lchild, operator_t op, uint64_t rchild, bool is_leaf)
{
condition_t *cond = (condition_t *)malloc(sizeof(condition_t));
cond->op = op;
cond->is_leaf = is_leaf;
cond->lchild = (condition_t *)(lchild);
cond->rchild = (condition_t *)(rchild);
return cond;
}

static void print_tree(condition_t *node, int depth)
{
if (node == NULL)
return;
for (int i = 0; i < depth; ++i)
printf("\t- ");
if (node->is_leaf)
{
printf("lvalue = %s, op = %d, rvalue = %p \n", node->lvalue->fieldname, node->op, node->rchild);
}
else
{
printf("op = %d\n", node->op);
print_tree(node->lchild, depth + 1);
print_tree(node->rchild, depth + 1);
}
}


#endif
9 changes: 9 additions & 0 deletions sqlparser/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CC=clang -std=gnu17 -Wall -Wno-pointer-to-int-cast
build:
flex sqlex.l
bison -d sqlparser.y
# use 'gcc -fl' if you build on Linux
$(CC) sqlparser.tab.c lex.yy.c -ll

clean:
rm a.out lex.yy.c *.tab.c *.tab.h
30 changes: 30 additions & 0 deletions sqlparser/sql.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "../list.h"
#include <stdint.h>
#include <stdlib.h>
#ifndef __SQL_H__
#define __SQL_H__

const uint32_t TBALE_COLUMN_NAME_MAX_LENGTH = 32;
typedef enum
{
COLUMN_INT, // -> uint_t in tinydb kernel
COLUMN_VARCHAR // -> varchar(n) in tinydb kernel
} column_type_t;

/* Table Schema */
typedef struct
{
column_type_t column_type;
uint32_t width;
char fieldname[TBALE_COLUMN_NAME_MAX_LENGTH];
} schema_t;

struct schema_node_t
{
struct list_head entry;
schema_t schema;
};
typedef struct schema_node_t schema_node_t;


#endif
60 changes: 60 additions & 0 deletions sqlparser/sqlex.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
%{
#include "sqlparser.tab.h"
%}

%%

"select" |
"SELECT" { return SELECT; }

"create" |
"CREATE" { return CREATE; }

"from" |
"FROM" { return FROM; }

"where" |
"WHERE" { return WHERE; }

"table" |
"TABLE" { return TABLE; }

"int" |
"INT" { return INT; }

"char" |
"CHAR" |
"varchar" |
"VARCHAR" { return CHAR; }



[;] |
[,] |
[*] |
[)] |
[(] { return *yytext; }

">=" { return GREAT_EQUAL; }
">" { return GREAT; }
"<" { return LESS; }
"<=" { return LESS_EQUAL; }
"!=" { return NOT_EQUAL; }
"=" { return EQUAL; }
"==" { return EQUAL; }

"and" |
"AND" { return AND; }

"or" |
"OR" { return OR; }

[\'][A-Za-z][A-Za-z0-9_]*[\'] { yylval.strval = strdup(yytext); return STRING; }
[A-Za-z][A-Za-z0-9_]* { yylval.strval = strdup(yytext); return IDNAME; }
[0-9]+ { yylval.intval = atoi(yytext); return NUMBER; }

\n { return *yytext; }
[ \t]+ { /* ignore and do nothing */ }


%%
Loading

0 comments on commit 3983d2f

Please sign in to comment.