Support more of the CREATE TABLE command (#101)

* Support more of the CREATE TABLE command

* bison version

* build on nemea

* bla

* Check for flex version
This commit is contained in:
mrks 2018-10-19 14:18:03 +02:00 committed by GitHub
parent 79bdad949f
commit f7bd4ee592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 2887 additions and 2706 deletions

View File

@ -1,15 +1,26 @@
# bison's version is too old on OSX, allow user to pass in custom path # bison's version is too old on OSX, allow user to pass in custom path
BISON?=bison BISON?=bison
FLEX?=flex
BISON_VERSION=$(shell $(BISON) --version | head -n 1 | grep -o '[0-9]\.[0-9]\+')
BISON_VERSION_SUPPORTED=$(shell echo $(BISON_VERSION) \>= 3.0 | bc)
ifneq ($(BISON_VERSION_SUPPORTED), 1)
$(error Bison version $(BISON_VERSION) not supported. If you are using OS X, `bison` uses the system default instead of the brew version. Run BISON=/usr/local/opt/bison/bin/bison make)
endif
FLEX_VERSION=$(shell $(FLEX) --version | head -n 1 | grep -o '[0-9]\.[0-9]\+')
FLEX_VERSION_SUPPORTED=$(shell echo $(FLEX_VERSION) \>= 2.6 | bc)
ifneq ($(FLEX_VERSION_SUPPORTED), 1)
$(error Flex version $(FLEX_VERSION) not supported. If you are using OS X, `flex` uses the system default instead of the brew version. Run FLEX=/usr/local/opt/flex/bin/flex make)
endif
all: bison_parser.cpp flex_lexer.cpp all: bison_parser.cpp flex_lexer.cpp
bison_parser.cpp: bison_parser.y bison_parser.cpp: bison_parser.y
@$(BISON) --version | head -n 1
$(BISON) bison_parser.y --output=bison_parser.cpp --defines=bison_parser.h --verbose $(BISON) bison_parser.y --output=bison_parser.cpp --defines=bison_parser.h --verbose
flex_lexer.cpp: flex_lexer.l flex_lexer.cpp: flex_lexer.l
@flex --version $(FLEX) flex_lexer.l
flex flex_lexer.l
clean: clean:
rm -f bison_parser.cpp flex_lexer.cpp bison_parser.h flex_lexer.h *.output rm -f bison_parser.cpp flex_lexer.cpp bison_parser.h flex_lexer.h *.output

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.0.4. */ /* A Bison parser, made by GNU Bison 3.1. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -48,7 +48,7 @@
extern int hsql_debug; extern int hsql_debug;
#endif #endif
/* "%code requires" blocks. */ /* "%code requires" blocks. */
#line 35 "bison_parser.y" /* yacc.c:1909 */ #line 35 "bison_parser.y" /* yacc.c:1919 */
// %code requires block // %code requires block
@ -72,7 +72,7 @@ extern int hsql_debug;
} \ } \
} }
#line 76 "bison_parser.h" /* yacc.c:1909 */ #line 76 "bison_parser.h" /* yacc.c:1919 */
/* Token type. */ /* Token type. */
#ifndef HSQL_TOKENTYPE #ifndef HSQL_TOKENTYPE
@ -107,115 +107,119 @@ extern int hsql_debug;
SQL_PRIMARY = 283, SQL_PRIMARY = 283,
SQL_SCHEMAS = 284, SQL_SCHEMAS = 284,
SQL_SPATIAL = 285, SQL_SPATIAL = 285,
SQL_VIRTUAL = 286, SQL_VARCHAR = 286,
SQL_BEFORE = 287, SQL_VIRTUAL = 287,
SQL_COLUMN = 288, SQL_BEFORE = 288,
SQL_CREATE = 289, SQL_COLUMN = 289,
SQL_DELETE = 290, SQL_CREATE = 290,
SQL_DIRECT = 291, SQL_DELETE = 291,
SQL_DOUBLE = 292, SQL_DIRECT = 292,
SQL_ESCAPE = 293, SQL_DOUBLE = 293,
SQL_EXCEPT = 294, SQL_ESCAPE = 294,
SQL_EXISTS = 295, SQL_EXCEPT = 295,
SQL_EXTRACT = 296, SQL_EXISTS = 296,
SQL_GLOBAL = 297, SQL_EXTRACT = 297,
SQL_HAVING = 298, SQL_GLOBAL = 298,
SQL_IMPORT = 299, SQL_HAVING = 299,
SQL_INSERT = 300, SQL_IMPORT = 300,
SQL_ISNULL = 301, SQL_INSERT = 301,
SQL_OFFSET = 302, SQL_ISNULL = 302,
SQL_RENAME = 303, SQL_OFFSET = 303,
SQL_SCHEMA = 304, SQL_RENAME = 304,
SQL_SELECT = 305, SQL_SCHEMA = 305,
SQL_SORTED = 306, SQL_SELECT = 306,
SQL_TABLES = 307, SQL_SORTED = 307,
SQL_UNIQUE = 308, SQL_TABLES = 308,
SQL_UNLOAD = 309, SQL_UNIQUE = 309,
SQL_UPDATE = 310, SQL_UNLOAD = 310,
SQL_VALUES = 311, SQL_UPDATE = 311,
SQL_AFTER = 312, SQL_VALUES = 312,
SQL_ALTER = 313, SQL_AFTER = 313,
SQL_CROSS = 314, SQL_ALTER = 314,
SQL_DELTA = 315, SQL_CROSS = 315,
SQL_GROUP = 316, SQL_DELTA = 316,
SQL_INDEX = 317, SQL_FLOAT = 317,
SQL_INNER = 318, SQL_GROUP = 318,
SQL_LIMIT = 319, SQL_INDEX = 319,
SQL_LOCAL = 320, SQL_INNER = 320,
SQL_MERGE = 321, SQL_LIMIT = 321,
SQL_MINUS = 322, SQL_LOCAL = 322,
SQL_ORDER = 323, SQL_MERGE = 323,
SQL_OUTER = 324, SQL_MINUS = 324,
SQL_RIGHT = 325, SQL_ORDER = 325,
SQL_TABLE = 326, SQL_OUTER = 326,
SQL_UNION = 327, SQL_RIGHT = 327,
SQL_USING = 328, SQL_TABLE = 328,
SQL_WHERE = 329, SQL_UNION = 329,
SQL_CALL = 330, SQL_USING = 330,
SQL_CASE = 331, SQL_WHERE = 331,
SQL_DATE = 332, SQL_CALL = 332,
SQL_DESC = 333, SQL_CASE = 333,
SQL_DROP = 334, SQL_CHAR = 334,
SQL_ELSE = 335, SQL_DATE = 335,
SQL_FILE = 336, SQL_DESC = 336,
SQL_FROM = 337, SQL_DROP = 337,
SQL_FULL = 338, SQL_ELSE = 338,
SQL_HASH = 339, SQL_FILE = 339,
SQL_HINT = 340, SQL_FROM = 340,
SQL_INTO = 341, SQL_FULL = 341,
SQL_JOIN = 342, SQL_HASH = 342,
SQL_LEFT = 343, SQL_HINT = 343,
SQL_LIKE = 344, SQL_INTO = 344,
SQL_LOAD = 345, SQL_JOIN = 345,
SQL_NULL = 346, SQL_LEFT = 346,
SQL_PLAN = 347, SQL_LIKE = 347,
SQL_SHOW = 348, SQL_LOAD = 348,
SQL_TEXT = 349, SQL_LONG = 349,
SQL_THEN = 350, SQL_NULL = 350,
SQL_TIME = 351, SQL_PLAN = 351,
SQL_VIEW = 352, SQL_SHOW = 352,
SQL_WHEN = 353, SQL_TEXT = 353,
SQL_WITH = 354, SQL_THEN = 354,
SQL_ADD = 355, SQL_TIME = 355,
SQL_ALL = 356, SQL_VIEW = 356,
SQL_AND = 357, SQL_WHEN = 357,
SQL_ASC = 358, SQL_WITH = 358,
SQL_CSV = 359, SQL_ADD = 359,
SQL_END = 360, SQL_ALL = 360,
SQL_FOR = 361, SQL_AND = 361,
SQL_INT = 362, SQL_ASC = 362,
SQL_KEY = 363, SQL_CSV = 363,
SQL_NOT = 364, SQL_END = 364,
SQL_OFF = 365, SQL_FOR = 365,
SQL_SET = 366, SQL_INT = 366,
SQL_TBL = 367, SQL_KEY = 367,
SQL_TOP = 368, SQL_NOT = 368,
SQL_AS = 369, SQL_OFF = 369,
SQL_BY = 370, SQL_SET = 370,
SQL_IF = 371, SQL_TBL = 371,
SQL_IN = 372, SQL_TOP = 372,
SQL_IS = 373, SQL_AS = 373,
SQL_OF = 374, SQL_BY = 374,
SQL_ON = 375, SQL_IF = 375,
SQL_OR = 376, SQL_IN = 376,
SQL_TO = 377, SQL_IS = 377,
SQL_ARRAY = 378, SQL_OF = 378,
SQL_CONCAT = 379, SQL_ON = 379,
SQL_ILIKE = 380, SQL_OR = 380,
SQL_SECOND = 381, SQL_TO = 381,
SQL_MINUTE = 382, SQL_ARRAY = 382,
SQL_HOUR = 383, SQL_CONCAT = 383,
SQL_DAY = 384, SQL_ILIKE = 384,
SQL_MONTH = 385, SQL_SECOND = 385,
SQL_YEAR = 386, SQL_MINUTE = 386,
SQL_EQUALS = 387, SQL_HOUR = 387,
SQL_NOTEQUALS = 388, SQL_DAY = 388,
SQL_LESS = 389, SQL_MONTH = 389,
SQL_GREATER = 390, SQL_YEAR = 390,
SQL_LESSEQ = 391, SQL_EQUALS = 391,
SQL_GREATEREQ = 392, SQL_NOTEQUALS = 392,
SQL_NOTNULL = 393, SQL_LESS = 393,
SQL_UMINUS = 394 SQL_GREATER = 394,
SQL_LESSEQ = 395,
SQL_GREATEREQ = 396,
SQL_NOTNULL = 397,
SQL_UMINUS = 398
}; };
#endif #endif
@ -224,7 +228,7 @@ extern int hsql_debug;
union HSQL_STYPE union HSQL_STYPE
{ {
#line 95 "bison_parser.y" /* yacc.c:1909 */ #line 95 "bison_parser.y" /* yacc.c:1919 */
double fval; double fval;
int64_t ival; int64_t ival;
@ -252,6 +256,7 @@ union HSQL_STYPE
hsql::DatetimeField datetime_field; hsql::DatetimeField datetime_field;
hsql::LimitDescription* limit; hsql::LimitDescription* limit;
hsql::ColumnDefinition* column_t; hsql::ColumnDefinition* column_t;
hsql::ColumnType column_type_t;
hsql::GroupByDescription* group_t; hsql::GroupByDescription* group_t;
hsql::UpdateClause* update_t; hsql::UpdateClause* update_t;
hsql::Alias* alias_t; hsql::Alias* alias_t;
@ -265,7 +270,7 @@ union HSQL_STYPE
std::vector<hsql::Expr*>* expr_vec; std::vector<hsql::Expr*>* expr_vec;
std::vector<hsql::OrderDescription*>* order_vec; std::vector<hsql::OrderDescription*>* order_vec;
#line 269 "bison_parser.h" /* yacc.c:1909 */ #line 274 "bison_parser.h" /* yacc.c:1919 */
}; };
typedef union HSQL_STYPE HSQL_STYPE; typedef union HSQL_STYPE HSQL_STYPE;

View File

@ -119,6 +119,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
hsql::DatetimeField datetime_field; hsql::DatetimeField datetime_field;
hsql::LimitDescription* limit; hsql::LimitDescription* limit;
hsql::ColumnDefinition* column_t; hsql::ColumnDefinition* column_t;
hsql::ColumnType column_type_t;
hsql::GroupByDescription* group_t; hsql::GroupByDescription* group_t;
hsql::UpdateClause* update_t; hsql::UpdateClause* update_t;
hsql::Alias* alias_t; hsql::Alias* alias_t;
@ -137,7 +138,7 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
/********************************* /*********************************
** Destructor symbols ** Destructor symbols
*********************************/ *********************************/
%destructor { } <fval> <ival> <uval> <bval> <order_type> <datetime_field> %destructor { } <fval> <ival> <uval> <bval> <order_type> <datetime_field> <column_type_t>
%destructor { free( ($$.name) ); free( ($$.schema) ); } <table_name> %destructor { free( ($$.name) ); free( ($$.schema) ); } <table_name>
%destructor { free( ($$) ); } <sval> %destructor { free( ($$) ); } <sval>
%destructor { %destructor {
@ -163,14 +164,14 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
%token DISTINCT NVARCHAR RESTRICT TRUNCATE ANALYZE BETWEEN %token DISTINCT NVARCHAR RESTRICT TRUNCATE ANALYZE BETWEEN
%token CASCADE COLUMNS CONTROL DEFAULT EXECUTE EXPLAIN %token CASCADE COLUMNS CONTROL DEFAULT EXECUTE EXPLAIN
%token HISTORY INTEGER NATURAL PREPARE PRIMARY SCHEMAS %token HISTORY INTEGER NATURAL PREPARE PRIMARY SCHEMAS
%token SPATIAL VIRTUAL BEFORE COLUMN CREATE DELETE DIRECT %token SPATIAL VARCHAR VIRTUAL BEFORE COLUMN CREATE DELETE DIRECT
%token DOUBLE ESCAPE EXCEPT EXISTS EXTRACT GLOBAL HAVING IMPORT %token DOUBLE ESCAPE EXCEPT EXISTS EXTRACT GLOBAL HAVING IMPORT
%token INSERT ISNULL OFFSET RENAME SCHEMA SELECT SORTED %token INSERT ISNULL OFFSET RENAME SCHEMA SELECT SORTED
%token TABLES UNIQUE UNLOAD UPDATE VALUES AFTER ALTER CROSS %token TABLES UNIQUE UNLOAD UPDATE VALUES AFTER ALTER CROSS
%token DELTA GROUP INDEX INNER LIMIT LOCAL MERGE MINUS ORDER %token DELTA FLOAT GROUP INDEX INNER LIMIT LOCAL MERGE MINUS ORDER
%token OUTER RIGHT TABLE UNION USING WHERE CALL CASE DATE %token OUTER RIGHT TABLE UNION USING WHERE CALL CASE CHAR DATE
%token DESC DROP ELSE FILE FROM FULL HASH HINT INTO JOIN %token DESC DROP ELSE FILE FROM FULL HASH HINT INTO JOIN
%token LEFT LIKE LOAD NULL PLAN SHOW TEXT THEN TIME %token LEFT LIKE LOAD LONG NULL PLAN SHOW TEXT THEN TIME
%token VIEW WHEN WITH ADD ALL AND ASC CSV END FOR INT KEY %token VIEW WHEN WITH ADD ALL AND ASC CSV END FOR INT KEY
%token NOT OFF SET TBL TOP AS BY IF IN IS OF ON OR TO %token NOT OFF SET TBL TOP AS BY IF IN IS OF ON OR TO
%token ARRAY CONCAT ILIKE SECOND MINUTE HOUR DAY MONTH YEAR %token ARRAY CONCAT ILIKE SECOND MINUTE HOUR DAY MONTH YEAR
@ -178,37 +179,38 @@ int yyerror(YYLTYPE* llocp, SQLParserResult* result, yyscan_t scanner, const cha
/********************************* /*********************************
** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html) ** Non-Terminal types (http://www.gnu.org/software/bison/manual/html_node/Type-Decl.html)
*********************************/ *********************************/
%type <stmt_vec> statement_list %type <stmt_vec> statement_list
%type <statement> statement preparable_statement %type <statement> statement preparable_statement
%type <exec_stmt> execute_statement %type <exec_stmt> execute_statement
%type <prep_stmt> prepare_statement %type <prep_stmt> prepare_statement
%type <select_stmt> select_statement select_with_paren select_no_paren select_clause select_paren_or_clause %type <select_stmt> select_statement select_with_paren select_no_paren select_clause select_paren_or_clause
%type <import_stmt> import_statement %type <import_stmt> import_statement
%type <create_stmt> create_statement %type <create_stmt> create_statement
%type <insert_stmt> insert_statement %type <insert_stmt> insert_statement
%type <delete_stmt> delete_statement truncate_statement %type <delete_stmt> delete_statement truncate_statement
%type <update_stmt> update_statement %type <update_stmt> update_statement
%type <drop_stmt> drop_statement %type <drop_stmt> drop_statement
%type <show_stmt> show_statement %type <show_stmt> show_statement
%type <table_name> table_name %type <table_name> table_name
%type <sval> file_path prepare_target_query %type <sval> file_path prepare_target_query
%type <bval> opt_not_exists opt_exists opt_distinct %type <bval> opt_not_exists opt_exists opt_distinct opt_column_nullable
%type <uval> import_file_type opt_join_type column_type %type <uval> import_file_type opt_join_type
%type <table> opt_from_clause from_clause table_ref table_ref_atomic table_ref_name nonjoin_table_ref_atomic %type <table> opt_from_clause from_clause table_ref table_ref_atomic table_ref_name nonjoin_table_ref_atomic
%type <table> join_clause table_ref_name_no_alias %type <table> join_clause table_ref_name_no_alias
%type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr extract_expr %type <expr> expr operand scalar_expr unary_expr binary_expr logic_expr exists_expr extract_expr
%type <expr> function_expr between_expr expr_alias param_expr %type <expr> function_expr between_expr expr_alias param_expr
%type <expr> column_name literal int_literal num_literal string_literal %type <expr> column_name literal int_literal num_literal string_literal
%type <expr> comp_expr opt_where join_condition opt_having case_expr case_list in_expr hint %type <expr> comp_expr opt_where join_condition opt_having case_expr case_list in_expr hint
%type <expr> array_expr array_index null_literal %type <expr> array_expr array_index null_literal
%type <limit> opt_limit opt_top %type <limit> opt_limit opt_top
%type <order> order_desc %type <order> order_desc
%type <order_type> opt_order_type %type <order_type> opt_order_type
%type <datetime_field> datetime_field %type <datetime_field> datetime_field
%type <column_t> column_def %type <column_t> column_def
%type <update_t> update_clause %type <column_type_t> column_type
%type <group_t> opt_group %type <update_t> update_clause
%type <alias_t> opt_table_alias table_alias opt_alias alias %type <group_t> opt_group
%type <alias_t> opt_table_alias table_alias opt_alias alias
%type <str_vec> ident_commalist opt_column_list %type <str_vec> ident_commalist opt_column_list
%type <expr_vec> expr_list select_list literal_list hint_list opt_hints %type <expr_vec> expr_list select_list literal_list hint_list opt_hints
@ -444,17 +446,26 @@ column_def_commalist:
; ;
column_def: column_def:
IDENTIFIER column_type { IDENTIFIER column_type opt_column_nullable {
$$ = new ColumnDefinition($1, (ColumnDefinition::DataType) $2); $$ = new ColumnDefinition($1, $2, $3);
} }
; ;
column_type: column_type:
INT { $$ = ColumnDefinition::INT; } INT { $$ = ColumnType{DataType::INT}; }
| INTEGER { $$ = ColumnDefinition::INT; } | INTEGER { $$ = ColumnType{DataType::INT}; }
| DOUBLE { $$ = ColumnDefinition::DOUBLE; } | LONG { $$ = ColumnType{DataType::LONG}; }
| TEXT { $$ = ColumnDefinition::TEXT; } | FLOAT { $$ = ColumnType{DataType::FLOAT}; }
| DOUBLE { $$ = ColumnType{DataType::DOUBLE}; }
| VARCHAR '(' INTVAL ')' { $$ = ColumnType{DataType::VARCHAR, $3}; }
| CHAR '(' INTVAL ')' { $$ = ColumnType{DataType::CHAR, $3}; }
| TEXT { $$ = ColumnType{DataType::TEXT}; }
;
opt_column_nullable:
NULL { $$ = true; }
| NOT NULL { $$ = false; }
| /* empty */ { $$ = false; }
; ;
/****************************** /******************************

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,9 @@
#define hsql_HEADER_H 1 #define hsql_HEADER_H 1
#define hsql_IN_HEADER 1 #define hsql_IN_HEADER 1
#line 6 "flex_lexer.h" #line 5 "flex_lexer.h"
#line 8 "flex_lexer.h" #line 7 "flex_lexer.h"
#define YY_INT_ALIGNED short int #define YY_INT_ALIGNED short int
@ -729,9 +729,9 @@ extern int yylex \
#undef yyTABLES_NAME #undef yyTABLES_NAME
#endif #endif
#line 225 "flex_lexer.l" #line 227 "flex_lexer.l"
#line 736 "flex_lexer.h" #line 735 "flex_lexer.h"
#undef hsql_IN_HEADER #undef hsql_IN_HEADER
#endif /* hsql_HEADER_H */ #endif /* hsql_HEADER_H */

View File

@ -80,6 +80,7 @@ PREPARE TOKEN(PREPARE)
PRIMARY TOKEN(PRIMARY) PRIMARY TOKEN(PRIMARY)
SCHEMAS TOKEN(SCHEMAS) SCHEMAS TOKEN(SCHEMAS)
SPATIAL TOKEN(SPATIAL) SPATIAL TOKEN(SPATIAL)
VARCHAR TOKEN(VARCHAR)
VIRTUAL TOKEN(VIRTUAL) VIRTUAL TOKEN(VIRTUAL)
BEFORE TOKEN(BEFORE) BEFORE TOKEN(BEFORE)
COLUMN TOKEN(COLUMN) COLUMN TOKEN(COLUMN)
@ -127,6 +128,7 @@ USING TOKEN(USING)
WHERE TOKEN(WHERE) WHERE TOKEN(WHERE)
CALL TOKEN(CALL) CALL TOKEN(CALL)
CASE TOKEN(CASE) CASE TOKEN(CASE)
CHAR TOKEN(CHAR)
DATE TOKEN(DATE) DATE TOKEN(DATE)
DESC TOKEN(DESC) DESC TOKEN(DESC)
DROP TOKEN(DROP) DROP TOKEN(DROP)

View File

@ -3,24 +3,43 @@
#include "SQLStatement.h" #include "SQLStatement.h"
#include <ostream>
// Note: Implementations of constructors and destructors can be found in statements.cpp. // Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql { namespace hsql {
struct SelectStatement; struct SelectStatement;
enum class DataType {
UNKNOWN,
INT,
LONG,
FLOAT,
DOUBLE,
CHAR,
VARCHAR,
TEXT
};
// Represents the type of a column, e.g., FLOAT or VARCHAR(10)
struct ColumnType {
ColumnType() = default;
ColumnType(DataType data_type, int64_t length = 0);
DataType data_type;
int64_t length; // Used for, e.g., VARCHAR(10)
};
bool operator==(const ColumnType& lhs, const ColumnType& rhs);
bool operator!=(const ColumnType& lhs, const ColumnType& rhs);
std::ostream& operator<<(std::ostream&, const ColumnType&);
// Represents definition of a table column // Represents definition of a table column
struct ColumnDefinition { struct ColumnDefinition {
enum DataType { ColumnDefinition(char* name, ColumnType type, bool nullable);
UNKNOWN,
TEXT,
INT,
DOUBLE
};
ColumnDefinition(char* name, DataType type);
virtual ~ColumnDefinition(); virtual ~ColumnDefinition();
char* name; char* name;
DataType type; ColumnType type;
bool nullable;
}; };
enum CreateType { enum CreateType {

View File

@ -1,17 +1,64 @@
#include "statements.h" #include "statements.h"
namespace hsql { namespace hsql {
// ColumnDefinition // ColumnDefinition
ColumnDefinition::ColumnDefinition(char* name, DataType type) : ColumnDefinition::ColumnDefinition(char* name, ColumnType type, bool nullable) :
name(name), name(name),
type(type) {}; type(type),
nullable(nullable) {};
ColumnDefinition::~ColumnDefinition() { ColumnDefinition::~ColumnDefinition() {
free(name); free(name);
} }
ColumnType::ColumnType(DataType data_type, int64_t length) :
data_type(data_type),
length(length) {};
bool operator==(const ColumnType& lhs, const ColumnType& rhs) {
if (lhs.data_type != rhs.data_type) return false;
if (lhs.data_type == DataType::VARCHAR || lhs.data_type == DataType::CHAR) {
return lhs.length == rhs.length;
}
return true;
}
bool operator!=(const ColumnType& lhs, const ColumnType& rhs) {
return !(lhs == rhs);
}
std::ostream& operator<<(std::ostream& stream, const ColumnType& column_type) {
switch (column_type.data_type) {
case DataType::UNKNOWN:
stream << "UNKNOWN";
break;
case DataType::INT:
stream << "INT";
break;
case DataType::LONG:
stream << "LONG";
break;
case DataType::FLOAT:
stream << "FLOAT";
break;
case DataType::DOUBLE:
stream << "DOUBLE";
break;
case DataType::CHAR:
stream << "CHAR(" << column_type.length << ")";
break;
case DataType::VARCHAR:
stream << "VARCHAR(" << column_type.length << ")";
break;
case DataType::TEXT:
stream << "TEXT";
break;
}
return stream;
}
// CreateStatemnet // CreateStatemnet
CreateStatement::CreateStatement(CreateType type) : CreateStatement::CreateStatement(CreateType type) :
SQLStatement(kStmtCreate), SQLStatement(kStmtCreate),

View File

@ -30,7 +30,7 @@ TEST(DeleteStatementTest) {
TEST(CreateStatementTest) { TEST(CreateStatementTest) {
SQLParserResult result; SQLParserResult result;
SQLParser::parse("CREATE TABLE students (name TEXT, student_number INT, city INTEGER, grade DOUBLE)", &result); SQLParser::parse("CREATE TABLE students (name VARCHAR(50), student_number INT, city INTEGER NULL, grade DOUBLE NOT NULL, comment TEXT)", &result);
ASSERT(result.isValid()); ASSERT(result.isValid());
ASSERT_EQ(result.size(), 1); ASSERT_EQ(result.size(), 1);
@ -40,15 +40,22 @@ TEST(CreateStatementTest) {
ASSERT_EQ(stmt->type, kCreateTable); ASSERT_EQ(stmt->type, kCreateTable);
ASSERT_STREQ(stmt->tableName, "students"); ASSERT_STREQ(stmt->tableName, "students");
ASSERT_NOTNULL(stmt->columns); ASSERT_NOTNULL(stmt->columns);
ASSERT_EQ(stmt->columns->size(), 4); ASSERT_EQ(stmt->columns->size(), 5);
ASSERT_STREQ(stmt->columns->at(0)->name, "name"); ASSERT_STREQ(stmt->columns->at(0)->name, "name");
ASSERT_STREQ(stmt->columns->at(1)->name, "student_number"); ASSERT_STREQ(stmt->columns->at(1)->name, "student_number");
ASSERT_STREQ(stmt->columns->at(2)->name, "city"); ASSERT_STREQ(stmt->columns->at(2)->name, "city");
ASSERT_STREQ(stmt->columns->at(3)->name, "grade"); ASSERT_STREQ(stmt->columns->at(3)->name, "grade");
ASSERT_EQ(stmt->columns->at(0)->type, ColumnDefinition::TEXT); ASSERT_STREQ(stmt->columns->at(4)->name, "comment");
ASSERT_EQ(stmt->columns->at(1)->type, ColumnDefinition::INT); ASSERT_EQ(stmt->columns->at(0)->type, (ColumnType{DataType::VARCHAR, 50}));
ASSERT_EQ(stmt->columns->at(2)->type, ColumnDefinition::INT); ASSERT_EQ(stmt->columns->at(1)->type, ColumnType{DataType::INT});
ASSERT_EQ(stmt->columns->at(3)->type, ColumnDefinition::DOUBLE); ASSERT_EQ(stmt->columns->at(2)->type, ColumnType{DataType::INT});
ASSERT_EQ(stmt->columns->at(3)->type, ColumnType{DataType::DOUBLE});
ASSERT_EQ(stmt->columns->at(4)->type, ColumnType{DataType::TEXT});
ASSERT_EQ(stmt->columns->at(0)->nullable, false);
ASSERT_EQ(stmt->columns->at(1)->nullable, false);
ASSERT_EQ(stmt->columns->at(2)->nullable, true);
ASSERT_EQ(stmt->columns->at(3)->nullable, false);
ASSERT_EQ(stmt->columns->at(3)->nullable, false);
} }