implemented insert statement

This commit is contained in:
Pedro 2014-11-26 00:26:20 +01:00
parent 7ab73f7b2b
commit b86bf6e7f9
14 changed files with 252 additions and 49 deletions

View File

@ -11,7 +11,5 @@ SELECT name, city, grade FROM (SELECT * FROM students WHERE city = 'Potsdam') t1
SELECT city, AVG(grade) AS average|, MIN(grade) AS best, MAX(grade) AS worst FROM students GROUP BY city;
# UNION
SELECT * FROM students WHERE grade = 1.3 UNION SELECT * FROM students WHERE grade = 3.7;
# SIMPLE JOIN
# JOIN
SELECT * FROM companies JOIN employees ON company_id = employee_company_id;
# HASH JOIN
SELECT * FROM companies HASH JOIN employees ON company_id = employee_company_id;

View File

@ -12,7 +12,9 @@ echo "\n\n"
# ./bin/analysis "SELECT t1.a AS id, t1.b, t2.c FROM \"tbl\" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5"
# ./bin/analysis "CREATE TABLE \"table\" FROM TBL FILE 'students.tbl'"
./bin/analysis "SELECT * FROM t1 UNION (SELECT abc AS t FROM t2 ORDER BY col3 LIMIT 10) ORDER BY col1;"
./bin/analysis "SELECT * FROM t1 UNION SELECT abc AS t FROM t2 ORDER BY col3 LIMIT 10;"
./bin/analysis "INSERT INTO students (name, city, age) VALUES ('Max', 'Musterhausen', 5);"
./bin/analysis "INSERT INTO students (name, city) SELECT * FROM employees;"
echo "\n\n"

36
src/lib/InsertStatement.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef __INSERT_STATEMENT_H__
#define __INSERT_STATEMENT_H__
#include "Statement.h"
#include "SelectStatement.h"
namespace hsql {
struct InsertStatement : Statement {
typedef enum {
kInsertValues,
kInsertSelect
} Type;
InsertStatement() :
Statement(kStmtInsert),
table_name(NULL),
columns(NULL),
values(NULL),
select(NULL) {}
virtual ~InsertStatement(); // defined in destructors.cpp
Type insert_type;
const char* table_name;
List<char*>* columns;
List<Expr*>* values;
SelectStatement* select;
};
} // namsepace hsql
#endif

View File

@ -14,9 +14,9 @@ typedef enum {
kStmtError, // Unused
kStmtSelect,
kStmtImport,
kStmtInsert,
// Following types are planned but not supported yet
kStmtDelete,
kStmtInsert,
kStmtCreate,
kStmtDrop,
kStmtExport,

View File

@ -31,6 +31,13 @@ CreateStatement::~CreateStatement() {
delete table_name;
}
InsertStatement::~InsertStatement() {
delete table_name;
delete select;
}
OrderDescription::~OrderDescription() {
delete expr;
}

View File

@ -120,5 +120,28 @@ void printCreateStatementInfo(CreateStatement* stmt, uint num_indent) {
inprint(stmt->file_path, num_indent+1);
}
void printInsertStatementInfo(InsertStatement* stmt, uint num_indent) {
inprint("InsertStatment", num_indent);
inprint(stmt->table_name, num_indent+1);
if (stmt->columns != NULL) {
inprint("Columns", num_indent+1);
for (char* col_name : stmt->columns->vector()) {
inprint(col_name, num_indent+2);
}
}
switch (stmt->insert_type) {
case InsertStatement::kInsertValues:
inprint("Values", num_indent+1);
for (Expr* expr : stmt->values->vector()) {
printExpression(expr, num_indent+2);
}
break;
case InsertStatement::kInsertSelect:
printSelectStatementInfo(stmt->select, num_indent+1);
break;
}
}
} // namespace hsql

View File

@ -9,6 +9,7 @@ namespace hsql {
void printSelectStatementInfo(SelectStatement* stmt, uint num_indent);
void printImportStatementInfo(ImportStatement* stmt, uint num_indent);
void printInsertStatementInfo(InsertStatement* stmt, uint num_indent);
void printCreateStatementInfo(CreateStatement* stmt, uint num_indent);
} // namespace hsql

View File

@ -5,5 +5,6 @@
#include "SelectStatement.h"
#include "ImportStatement.h"
#include "CreateStatement.h"
#include "InsertStatement.h"
#endif

View File

@ -82,6 +82,7 @@ typedef void* yyscan_t;
hsql::SelectStatement* select_stmt;
hsql::ImportStatement* import_stmt;
hsql::CreateStatement* create_stmt;
hsql::InsertStatement* insert_stmt;
hsql::TableRef* table;
hsql::Expr* expr;
@ -106,13 +107,17 @@ typedef void* yyscan_t;
%token <uval> NOTEQUALS LESSEQ GREATEREQ
/* SQL Keywords */
%token DATABASE DISTINCT BETWEEN CONTROL NATURAL COLUMN
%token CREATE DELETE EXISTS HAVING IMPORT INSERT ISNULL
%token OFFSET RENAME SELECT UNLOAD UPDATE ALTER CROSS GROUP
%token INDEX INNER LIMIT ORDER OUTER RADIX RIGHT TABLE UNION
%token USING WHERE DESC DROP FILE FROM HASH INTO JOIN LEFT
%token LIKE LOAD NULL SCAN ALL AND ASC CSV NOT TBL TOP AS BY
%token IF IN IS ON OR
%token INTERSECT TEMPORARY DISTINCT RESTRICT TRUNCATE
%token ANALYZE BETWEEN CASCADE COLUMNS CONTROL DEFAULT
%token EXPLAIN HISTORY NATURAL PRIMARY SCHEMAS SPATIAL
%token BEFORE COLUMN CREATE DELETE DIRECT ESCAPE EXCEPT
%token EXISTS GLOBAL HAVING IMPORT INSERT ISNULL OFFSET
%token RENAME SCHEMA SELECT SORTED TABLES UNIQUE UNLOAD
%token UPDATE VALUES AFTER ALTER CROSS GROUP INDEX INNER
%token LIMIT LOCAL MINUS ORDER OUTER RIGHT TABLE UNION USING
%token WHERE CALL DESC DROP FILE FROM FULL HASH INTO JOIN
%token LEFT LIKE LOAD NULL PLAN SHOW WITH ADD ALL AND ASC
%token CSV FOR KEY NOT SET TBL TOP AS BY IF IN IS ON OR TO
/*********************************
@ -120,9 +125,10 @@ typedef void* yyscan_t;
*********************************/
%type <stmt_list> statement_list
%type <statement> statement
%type <select_stmt> select_statement select_ref select_with_paren select_no_paren select_clause
%type <select_stmt> select_statement select_with_paren select_no_paren select_clause
%type <import_stmt> import_statement
%type <create_stmt> create_statement
%type <insert_stmt> insert_statement
%type <sval> table_name opt_alias alias file_path
%type <bval> opt_not_exists
%type <table> from_clause table_ref table_ref_atomic table_ref_name
@ -130,12 +136,13 @@ typedef void* yyscan_t;
%type <expr> expr scalar_expr unary_expr binary_expr function_expr star_expr expr_alias
%type <expr> column_name literal int_literal num_literal string_literal
%type <expr> comp_expr opt_where join_condition
%type <expr_list> expr_list opt_group select_list
%type <expr_list> expr_list opt_group select_list literal_list
%type <table_list> table_ref_commalist
%type <order> opt_order
%type <limit> opt_limit
%type <order_type> opt_order_type
%type <uval> import_file_type opt_join_type
%type <slist> ident_commalist opt_column_list
/******************************
** Token Precedence and Associativity
@ -165,9 +172,7 @@ typedef void* yyscan_t;
** Section 3: Grammar Definition
*********************************/
// Defines our general input.
// TODO: Support list of statements
input:
statement_list opt_semicolon { *result = $1; }
;
@ -178,13 +183,11 @@ statement_list:
| statement_list ';' statement { $1->push_back($3); $$ = $1; }
;
// All types of statements
// TODO: insert, delete, etc...
statement:
select_statement { $$ = $1; }
| import_statement { $$ = $1; }
| create_statement { $$ = $1; }
| insert_statement { $$ = $1; }
;
@ -228,6 +231,33 @@ opt_not_exists:
| /* empty */ { $$ = false; }
;
/******************************
** Insert Statement
******************************/
insert_statement:
INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' {
$$ = new InsertStatement();
$$->insert_type = InsertStatement::kInsertValues;
$$->table_name = $3;
$$->columns = $4;
$$->values = $7;
}
| INSERT INTO table_name opt_column_list select_no_paren {
$$ = new InsertStatement();
$$->insert_type = InsertStatement::kInsertSelect;
$$->table_name = $3;
$$->columns = $4;
$$->select = $5;
}
;
opt_column_list:
'(' ident_commalist ')' { $$ = $2; }
| /* empty */ { $$ = NULL; }
;
/******************************
** Select Statement
******************************/
@ -248,18 +278,21 @@ select_no_paren:
$$->order = $2;
$$->limit = $3;
}
| select_ref UNION select_ref opt_order opt_limit {
| select_clause set_operator select_clause opt_order opt_limit {
// TODO: allow multiple unions (through linked list)
// TODO: capture type of set_operator
// TODO: might overwrite order and limit of first select here
$$ = $1;
$$->union_select = $3;
// TODO: might overwrite order and limit of first select here
$$->order = $4;
$$->limit = $5;
}
;
select_ref:
select_clause
| select_with_paren
set_operator:
UNION
| INTERSECT
| EXCEPT
;
select_clause:
@ -321,6 +354,11 @@ expr_list:
| expr_list ',' expr_alias { $1->push_back($3); $$ = $1; }
;
literal_list:
literal { $$ = new List<Expr*>($1); }
| literal_list ',' literal { $1->push_back($3); $$ = $1; }
;
expr_alias:
expr opt_alias {
$$ = $1;
@ -512,6 +550,11 @@ opt_semicolon:
;
ident_commalist:
IDENTIFIER { $$ = new List<char*>($1); }
| ident_commalist ',' IDENTIFIER { $1->push_back($3); $$ = $1; }
;
%%
/*********************************
** Section 4: Additional C code

View File

@ -57,42 +57,68 @@
[ \t\n]+ /* skip whitespace */;
DATABASE TOKEN(DATABASE)
INTERSECT TOKEN(INTERSECT)
TEMPORARY TOKEN(TEMPORARY)
DISTINCT TOKEN(DISTINCT)
RESTRICT TOKEN(RESTRICT)
TRUNCATE TOKEN(TRUNCATE)
ANALYZE TOKEN(ANALYZE)
BETWEEN TOKEN(BETWEEN)
CASCADE TOKEN(CASCADE)
COLUMNS TOKEN(COLUMNS)
CONTROL TOKEN(CONTROL)
DEFAULT TOKEN(DEFAULT)
EXPLAIN TOKEN(EXPLAIN)
HISTORY TOKEN(HISTORY)
NATURAL TOKEN(NATURAL)
PRIMARY TOKEN(PRIMARY)
SCHEMAS TOKEN(SCHEMAS)
SPATIAL TOKEN(SPATIAL)
BEFORE TOKEN(BEFORE)
COLUMN TOKEN(COLUMN)
CREATE TOKEN(CREATE)
DELETE TOKEN(DELETE)
DIRECT TOKEN(DIRECT)
ESCAPE TOKEN(ESCAPE)
EXCEPT TOKEN(EXCEPT)
EXISTS TOKEN(EXISTS)
GLOBAL TOKEN(GLOBAL)
HAVING TOKEN(HAVING)
IMPORT TOKEN(IMPORT)
INSERT TOKEN(INSERT)
ISNULL TOKEN(ISNULL)
OFFSET TOKEN(OFFSET)
RENAME TOKEN(RENAME)
SCHEMA TOKEN(SCHEMA)
SELECT TOKEN(SELECT)
SORTED TOKEN(SORTED)
TABLES TOKEN(TABLES)
UNIQUE TOKEN(UNIQUE)
UNLOAD TOKEN(UNLOAD)
UPDATE TOKEN(UPDATE)
VALUES TOKEN(VALUES)
AFTER TOKEN(AFTER)
ALTER TOKEN(ALTER)
CROSS TOKEN(CROSS)
GROUP TOKEN(GROUP)
INDEX TOKEN(INDEX)
INNER TOKEN(INNER)
LIMIT TOKEN(LIMIT)
LOCAL TOKEN(LOCAL)
MINUS TOKEN(MINUS)
ORDER TOKEN(ORDER)
OUTER TOKEN(OUTER)
RADIX TOKEN(RADIX)
RIGHT TOKEN(RIGHT)
TABLE TOKEN(TABLE)
UNION TOKEN(UNION)
USING TOKEN(USING)
WHERE TOKEN(WHERE)
CALL TOKEN(CALL)
DESC TOKEN(DESC)
DROP TOKEN(DROP)
FILE TOKEN(FILE)
FROM TOKEN(FROM)
FULL TOKEN(FULL)
HASH TOKEN(HASH)
INTO TOKEN(INTO)
JOIN TOKEN(JOIN)
@ -100,12 +126,18 @@ LEFT TOKEN(LEFT)
LIKE TOKEN(LIKE)
LOAD TOKEN(LOAD)
NULL TOKEN(NULL)
SCAN TOKEN(SCAN)
PLAN TOKEN(PLAN)
SHOW TOKEN(SHOW)
WITH TOKEN(WITH)
ADD TOKEN(ADD)
ALL TOKEN(ALL)
AND TOKEN(AND)
ASC TOKEN(ASC)
CSV TOKEN(CSV)
FOR TOKEN(FOR)
KEY TOKEN(KEY)
NOT TOKEN(NOT)
SET TOKEN(SET)
TBL TOKEN(TBL)
TOP TOKEN(TOP)
AS TOKEN(AS)
@ -115,6 +147,7 @@ IN TOKEN(IN)
IS TOKEN(IS)
ON TOKEN(ON)
OR TOKEN(OR)
TO TOKEN(TO)
"<>" TOKEN(NOTEQUALS)

View File

@ -5,7 +5,7 @@ import math
with open("sql_keywords.txt", 'r') as fh:
keywords = [line.strip() for line in fh.readlines() if not line.strip().startswith("//") and len(line.strip()) > 0]
keywords = sorted(keywords) # Sort by name
keywords = sorted(set(keywords)) # Sort by name
keywords = sorted(keywords, key=lambda x: len(x), reverse=True) # Sort by length
#################

View File

@ -1,6 +1,7 @@
// Possible source for more tokens https://www.sqlite.org/lang_keywords.html
// Select statement
//////////////////////////
// Select Statement
SELECT
TOP
FROM
@ -16,6 +17,9 @@ DISTINCT
OFFSET
UNION
ALL
EXCEPT
MINUS
INTERSECT
// Join clause
JOIN
@ -24,42 +28,92 @@ INNER
OUTER
LEFT
RIGHT
FULL
CROSS
USING
NATURAL
HASH
RADIX
SCAN
// Create statement
// Select Statement
//////////////////////
// Data Definition
CREATE
TABLE
DATABASE
SCHEMA
INDEX
IF
NOT
EXISTS
GLOBAL
LOCAL
TEMPORARY
WITH
UNIQUE
INDEX
UNIQUE
HASH
SPATIAL
PRIMARY
KEY
ON
DROP
TABLE
SCHEMA
RESTRICT
CASCADE
ALTER
ADD
COLUMN
BEFORE
AFTER
// Data Definition
////////////////////////
// Data Manipulation
INSERT
VALUES
SET
DIRECT
SORTED
// Import statement
IMPORT
CSV
FILE
TBL
CONTROL
// other statements
ALTER
RENAME
DROP
DELETE
INSERT
LOAD
UPDATE
DELETE
HISTORY
TRUNCATE
// other statements
RENAME
TO
DELETE
EXPLAIN
PLAN
ANALYZE
LOAD
UNLOAD
SHOW
SCHEMAS
TABLES
COLUMNS
// misc.
COLUMN
INTO
AS
SET
DEFAULT
CALL
FOR
// Expressions
NOT
@ -71,3 +125,4 @@ IN
IS
ISNULL
BETWEEN
ESCAPE

View File

@ -30,6 +30,7 @@ int main(int argc, char *argv[]) {
case kStmtSelect: printSelectStatementInfo((SelectStatement*) stmt, 1); break;
case kStmtImport: printImportStatementInfo((ImportStatement*) stmt, 1); break;
case kStmtCreate: printCreateStatementInfo((CreateStatement*) stmt, 1); break;
case kStmtInsert: printInsertStatementInfo((InsertStatement*) stmt, 1); break;
default:
fprintf(stderr, "\tStatement Type %u. No detailed print method available.\n", stmt->type);
break;

View File

@ -6,8 +6,7 @@ SELECT * from "table" JOIN table2 ON a = b WHERE (b OR NOT a) AND a = 12.5
(SELECT a FROM foo WHERE a > 12 OR b > 3 AND c NOT LIKE 's%' LIMIT 10);
SELECT * FROM "table" LIMIT 10 OFFSET 10;
SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY col1;
SELECT * FROM t1 UNION (SELECT * FROM t2) ORDER BY col1;
SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
# SELECT * FROM t1 UNION (SELECT * FROM t2 UNION SELECT * FROM t3) ORDER BY col1;
# JOIN
SELECT t1.a, t1.b, t2.c FROM "table" AS t1 JOIN (SELECT * FROM foo JOIN bar ON foo.id = bar.id) t2 ON t1.a = t2.b WHERE (t1.b OR NOT t1.a) AND t2.c = 12.5
SELECT * FROM t1 JOIN t2 ON c1 = c2;
@ -16,3 +15,7 @@ CREATE TABLE "table" FROM TBL FILE 'students.tbl'
CREATE TABLE IF NOT EXISTS "table" FROM TBL FILE 'students.tbl'
# Multiple statements
CREATE TABLE "table" FROM TBL FILE 'students.tbl'; SELECT * FROM "table";
# INSERT
INSERT INTO test_table VALUES (1, 2, 'test');
INSERT INTO test_table (id, value, name) VALUES (1, 2, 'test');
INSERT INTO test_table SELECT * FROM students;