change var names to camelCase

This commit is contained in:
Pedro 2016-02-27 15:22:22 +01:00
parent 7d1c56d0aa
commit 4632abf92d
20 changed files with 237 additions and 303 deletions

View File

@ -60,8 +60,8 @@ format:
############ ############
test: $(BIN)/sql_tests $(BIN)/sql_grammar_test test: $(BIN)/sql_tests $(BIN)/sql_grammar_test
LD_LIBRARY_PATH=./ $(BIN)/sql_grammar_test -f "test/lib/valid_queries.sql" @LD_LIBRARY_PATH=./ $(BIN)/sql_grammar_test -f "test/lib/valid_queries.sql"
LD_LIBRARY_PATH=./ $(BIN)/sql_tests @LD_LIBRARY_PATH=./ $(BIN)/sql_tests
$(BIN)/sql_tests: library $(BIN)/sql_tests: library
@mkdir -p $(BIN)/ @mkdir -p $(BIN)/

View File

@ -1955,8 +1955,8 @@ yyreduce:
#line 296 "bison_parser.y" /* yacc.c:1646 */ #line 296 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.import_stmt) = new ImportStatement((ImportStatement::ImportType) (yyvsp[-4].uval)); (yyval.import_stmt) = new ImportStatement((ImportStatement::ImportType) (yyvsp[-4].uval));
(yyval.import_stmt)->file_path = (yyvsp[-2].sval); (yyval.import_stmt)->filePath = (yyvsp[-2].sval);
(yyval.import_stmt)->table_name = (yyvsp[0].sval); (yyval.import_stmt)->tableName = (yyvsp[0].sval);
} }
#line 1962 "bison_parser.cpp" /* yacc.c:1646 */ #line 1962 "bison_parser.cpp" /* yacc.c:1646 */
break; break;
@ -1977,9 +1977,9 @@ yyreduce:
#line 318 "bison_parser.y" /* yacc.c:1646 */ #line 318 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.create_stmt) = new CreateStatement(CreateStatement::kTableFromTbl); (yyval.create_stmt) = new CreateStatement(CreateStatement::kTableFromTbl);
(yyval.create_stmt)->if_not_exists = (yyvsp[-5].bval); (yyval.create_stmt)->ifNotExists = (yyvsp[-5].bval);
(yyval.create_stmt)->table_name = (yyvsp[-4].sval); (yyval.create_stmt)->tableName = (yyvsp[-4].sval);
(yyval.create_stmt)->file_path = (yyvsp[0].sval); (yyval.create_stmt)->filePath = (yyvsp[0].sval);
} }
#line 1985 "bison_parser.cpp" /* yacc.c:1646 */ #line 1985 "bison_parser.cpp" /* yacc.c:1646 */
break; break;
@ -1988,8 +1988,8 @@ yyreduce:
#line 324 "bison_parser.y" /* yacc.c:1646 */ #line 324 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.create_stmt) = new CreateStatement(CreateStatement::kTable); (yyval.create_stmt) = new CreateStatement(CreateStatement::kTable);
(yyval.create_stmt)->if_not_exists = (yyvsp[-4].bval); (yyval.create_stmt)->ifNotExists = (yyvsp[-4].bval);
(yyval.create_stmt)->table_name = (yyvsp[-3].sval); (yyval.create_stmt)->tableName = (yyvsp[-3].sval);
(yyval.create_stmt)->columns = (yyvsp[-1].column_vec); (yyval.create_stmt)->columns = (yyvsp[-1].column_vec);
} }
#line 1996 "bison_parser.cpp" /* yacc.c:1646 */ #line 1996 "bison_parser.cpp" /* yacc.c:1646 */
@ -2073,7 +2073,7 @@ yyreduce:
#line 379 "bison_parser.y" /* yacc.c:1646 */ #line 379 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.delete_stmt) = new DeleteStatement(); (yyval.delete_stmt) = new DeleteStatement();
(yyval.delete_stmt)->table_name = (yyvsp[-1].sval); (yyval.delete_stmt)->tableName = (yyvsp[-1].sval);
(yyval.delete_stmt)->expr = (yyvsp[0].expr); (yyval.delete_stmt)->expr = (yyvsp[0].expr);
} }
#line 2080 "bison_parser.cpp" /* yacc.c:1646 */ #line 2080 "bison_parser.cpp" /* yacc.c:1646 */
@ -2083,7 +2083,7 @@ yyreduce:
#line 387 "bison_parser.y" /* yacc.c:1646 */ #line 387 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.delete_stmt) = new DeleteStatement(); (yyval.delete_stmt) = new DeleteStatement();
(yyval.delete_stmt)->table_name = (yyvsp[0].sval); (yyval.delete_stmt)->tableName = (yyvsp[0].sval);
} }
#line 2089 "bison_parser.cpp" /* yacc.c:1646 */ #line 2089 "bison_parser.cpp" /* yacc.c:1646 */
break; break;
@ -2092,7 +2092,7 @@ yyreduce:
#line 399 "bison_parser.y" /* yacc.c:1646 */ #line 399 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertValues); (yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertValues);
(yyval.insert_stmt)->table_name = (yyvsp[-5].sval); (yyval.insert_stmt)->tableName = (yyvsp[-5].sval);
(yyval.insert_stmt)->columns = (yyvsp[-4].str_vec); (yyval.insert_stmt)->columns = (yyvsp[-4].str_vec);
(yyval.insert_stmt)->values = (yyvsp[-1].expr_vec); (yyval.insert_stmt)->values = (yyvsp[-1].expr_vec);
} }
@ -2103,7 +2103,7 @@ yyreduce:
#line 405 "bison_parser.y" /* yacc.c:1646 */ #line 405 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertSelect); (yyval.insert_stmt) = new InsertStatement(InsertStatement::kInsertSelect);
(yyval.insert_stmt)->table_name = (yyvsp[-2].sval); (yyval.insert_stmt)->tableName = (yyvsp[-2].sval);
(yyval.insert_stmt)->columns = (yyvsp[-1].str_vec); (yyval.insert_stmt)->columns = (yyvsp[-1].str_vec);
(yyval.insert_stmt)->select = (yyvsp[0].select_stmt); (yyval.insert_stmt)->select = (yyvsp[0].select_stmt);
} }
@ -2184,7 +2184,7 @@ yyreduce:
// TODO: capture type of set_operator // TODO: capture type of set_operator
// TODO: might overwrite order and limit of first select here // TODO: might overwrite order and limit of first select here
(yyval.select_stmt) = (yyvsp[-4].select_stmt); (yyval.select_stmt) = (yyvsp[-4].select_stmt);
(yyval.select_stmt)->union_select = (yyvsp[-2].select_stmt); (yyval.select_stmt)->unionSelect = (yyvsp[-2].select_stmt);
(yyval.select_stmt)->order = (yyvsp[-1].order); (yyval.select_stmt)->order = (yyvsp[-1].order);
(yyval.select_stmt)->limit = (yyvsp[0].limit); (yyval.select_stmt)->limit = (yyvsp[0].limit);
} }
@ -2195,11 +2195,11 @@ yyreduce:
#line 485 "bison_parser.y" /* yacc.c:1646 */ #line 485 "bison_parser.y" /* yacc.c:1646 */
{ {
(yyval.select_stmt) = new SelectStatement(); (yyval.select_stmt) = new SelectStatement();
(yyval.select_stmt)->select_distinct = (yyvsp[-4].bval); (yyval.select_stmt)->selectDistinct = (yyvsp[-4].bval);
(yyval.select_stmt)->select_list = (yyvsp[-3].expr_vec); (yyval.select_stmt)->selectList = (yyvsp[-3].expr_vec);
(yyval.select_stmt)->from_table = (yyvsp[-2].table); (yyval.select_stmt)->fromTable = (yyvsp[-2].table);
(yyval.select_stmt)->where_clause = (yyvsp[-1].expr); (yyval.select_stmt)->whereClause = (yyvsp[-1].expr);
(yyval.select_stmt)->group_by = (yyvsp[0].group_t); (yyval.select_stmt)->groupBy = (yyvsp[0].group_t);
} }
#line 2205 "bison_parser.cpp" /* yacc.c:1646 */ #line 2205 "bison_parser.cpp" /* yacc.c:1646 */
break; break;

View File

@ -295,8 +295,8 @@ execute_statement:
import_statement: import_statement:
IMPORT FROM import_file_type FILE file_path INTO table_name { IMPORT FROM import_file_type FILE file_path INTO table_name {
$$ = new ImportStatement((ImportStatement::ImportType) $3); $$ = new ImportStatement((ImportStatement::ImportType) $3);
$$->file_path = $5; $$->filePath = $5;
$$->table_name = $7; $$->tableName = $7;
} }
; ;
@ -317,14 +317,14 @@ file_path:
create_statement: create_statement:
CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path { CREATE TABLE opt_not_exists table_name FROM TBL FILE file_path {
$$ = new CreateStatement(CreateStatement::kTableFromTbl); $$ = new CreateStatement(CreateStatement::kTableFromTbl);
$$->if_not_exists = $3; $$->ifNotExists = $3;
$$->table_name = $4; $$->tableName = $4;
$$->file_path = $8; $$->filePath = $8;
} }
| CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' { | CREATE TABLE opt_not_exists table_name '(' column_def_commalist ')' {
$$ = new CreateStatement(CreateStatement::kTable); $$ = new CreateStatement(CreateStatement::kTable);
$$->if_not_exists = $3; $$->ifNotExists = $3;
$$->table_name = $4; $$->tableName = $4;
$$->columns = $6; $$->columns = $6;
} }
; ;
@ -378,7 +378,7 @@ drop_statement:
delete_statement: delete_statement:
DELETE FROM table_name opt_where { DELETE FROM table_name opt_where {
$$ = new DeleteStatement(); $$ = new DeleteStatement();
$$->table_name = $3; $$->tableName = $3;
$$->expr = $4; $$->expr = $4;
} }
; ;
@ -386,7 +386,7 @@ delete_statement:
truncate_statement: truncate_statement:
TRUNCATE table_name { TRUNCATE table_name {
$$ = new DeleteStatement(); $$ = new DeleteStatement();
$$->table_name = $2; $$->tableName = $2;
} }
; ;
@ -398,13 +398,13 @@ truncate_statement:
insert_statement: insert_statement:
INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' { INSERT INTO table_name opt_column_list VALUES '(' literal_list ')' {
$$ = new InsertStatement(InsertStatement::kInsertValues); $$ = new InsertStatement(InsertStatement::kInsertValues);
$$->table_name = $3; $$->tableName = $3;
$$->columns = $4; $$->columns = $4;
$$->values = $7; $$->values = $7;
} }
| INSERT INTO table_name opt_column_list select_no_paren { | INSERT INTO table_name opt_column_list select_no_paren {
$$ = new InsertStatement(InsertStatement::kInsertSelect); $$ = new InsertStatement(InsertStatement::kInsertSelect);
$$->table_name = $3; $$->tableName = $3;
$$->columns = $4; $$->columns = $4;
$$->select = $5; $$->select = $5;
} }
@ -469,7 +469,7 @@ select_no_paren:
// TODO: capture type of set_operator // TODO: capture type of set_operator
// TODO: might overwrite order and limit of first select here // TODO: might overwrite order and limit of first select here
$$ = $1; $$ = $1;
$$->union_select = $3; $$->unionSelect = $3;
$$->order = $4; $$->order = $4;
$$->limit = $5; $$->limit = $5;
} }
@ -484,11 +484,11 @@ set_operator:
select_clause: select_clause:
SELECT opt_distinct select_list from_clause opt_where opt_group { SELECT opt_distinct select_list from_clause opt_where opt_group {
$$ = new SelectStatement(); $$ = new SelectStatement();
$$->select_distinct = $2; $$->selectDistinct = $2;
$$->select_list = $3; $$->selectList = $3;
$$->from_table = $4; $$->fromTable = $4;
$$->where_clause = $5; $$->whereClause = $5;
$$->group_by = $6; $$->groupBy = $6;
} }
; ;

View File

@ -4,10 +4,8 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct ColumnDefinition * Represents definition of a table column
* @brief Represents definition of a table column
*/ */
struct ColumnDefinition { struct ColumnDefinition {
enum DataType { enum DataType {
@ -28,41 +26,37 @@ namespace hsql {
DataType type; DataType type;
}; };
/** /**
* @struct CreateStatement * Represents SQL Create statements.
* @brief Represents "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)" * Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)"
*/ */
struct CreateStatement : SQLStatement { struct CreateStatement : SQLStatement {
enum CreateType { enum CreateType {
kTable, kTable,
kTableFromTbl, // Hyrise file format kTableFromTbl // Hyrise file format
}; };
CreateStatement(CreateType type) : CreateStatement(CreateType type) :
SQLStatement(kStmtCreate), SQLStatement(kStmtCreate),
type(type), type(type),
if_not_exists(false), ifNotExists(false),
columns(NULL), filePath(NULL),
file_path(NULL), tableName(NULL),
table_name(NULL) {}; columns(NULL) {};
virtual ~CreateStatement() { virtual ~CreateStatement() {
delete columns; delete columns;
delete file_path; delete filePath;
delete table_name; delete tableName;
} }
CreateType type; CreateType type;
bool if_not_exists;
bool ifNotExists;
const char* filePath;
const char* tableName;
std::vector<ColumnDefinition*>* columns; std::vector<ColumnDefinition*>* columns;
const char* file_path;
const char* table_name;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,31 +4,26 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct DeleteStatement * Represents SQL Delete statements.
* @brief Represents "DELETE FROM students WHERE grade > 3.0" * Example: "DELETE FROM students WHERE grade > 3.0"
* *
* If expr == NULL => delete all rows (truncate) * Note: if (expr == NULL) => delete all rows (truncate)
*/ */
struct DeleteStatement : SQLStatement { struct DeleteStatement : SQLStatement {
DeleteStatement() : DeleteStatement() :
SQLStatement(kStmtDelete), SQLStatement(kStmtDelete),
table_name(NULL), tableName(NULL),
expr(NULL) {}; expr(NULL) {};
virtual ~DeleteStatement() { virtual ~DeleteStatement() {
delete table_name; delete tableName;
delete expr; delete expr;
} }
char* tableName;
char* table_name;
Expr* expr; Expr* expr;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,11 +4,9 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct DropStatement * Represents SQL Delete statements.
* @brief Represents "DROP TABLE" * Example "DROP TABLE students;"
*/ */
struct DropStatement : SQLStatement { struct DropStatement : SQLStatement {
enum EntityType { enum EntityType {
@ -19,7 +17,6 @@ namespace hsql {
kPreparedStatement kPreparedStatement
}; };
DropStatement(EntityType type) : DropStatement(EntityType type) :
SQLStatement(kStmtDrop), SQLStatement(kStmtDrop),
type(type), type(type),
@ -29,14 +26,9 @@ namespace hsql {
delete name; delete name;
} }
EntityType type; EntityType type;
const char* name; const char* name;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,11 +4,9 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct ExecuteStatement * Represents SQL Execute statements.
* @brief Represents "EXECUTE ins_prep(100, "test", 2.3);" * Example: "EXECUTE ins_prep(100, "test", 2.3);"
*/ */
struct ExecuteStatement : SQLStatement { struct ExecuteStatement : SQLStatement {
ExecuteStatement() : ExecuteStatement() :
@ -25,8 +23,5 @@ namespace hsql {
std::vector<Expr*>* parameters; std::vector<Expr*>* parameters;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -4,13 +4,8 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct ImportStatement * Represents SQL Import statements.
* @brief Represents "IMPORT"
*/ */
struct ImportStatement : SQLStatement { struct ImportStatement : SQLStatement {
enum ImportType { enum ImportType {
@ -18,26 +13,22 @@ namespace hsql {
kImportTbl, // Hyrise file format kImportTbl, // Hyrise file format
}; };
ImportStatement(ImportType type) : ImportStatement(ImportType type) :
SQLStatement(kStmtImport), SQLStatement(kStmtImport),
type(type), type(type),
file_path(NULL), filePath(NULL),
table_name(NULL) {}; tableName(NULL) {};
virtual ~ImportStatement() { virtual ~ImportStatement() {
delete file_path; delete filePath;
delete table_name; delete tableName;
} }
ImportType type; ImportType type;
const char* file_path; const char* filePath;
const char* table_name; const char* tableName;
}; };
} // namespace hsql } // namespace hsql

View File

@ -5,11 +5,9 @@
#include "SelectStatement.h" #include "SelectStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct InsertStatement * Represents SQL Insert statements.
* @brief Represents "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)" * Example: "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)"
*/ */
struct InsertStatement : SQLStatement { struct InsertStatement : SQLStatement {
enum InsertType { enum InsertType {
@ -20,27 +18,24 @@ namespace hsql {
InsertStatement(InsertType type) : InsertStatement(InsertType type) :
SQLStatement(kStmtInsert), SQLStatement(kStmtInsert),
type(type), type(type),
table_name(NULL), tableName(NULL),
columns(NULL), columns(NULL),
values(NULL), values(NULL),
select(NULL) {} select(NULL) {}
virtual ~InsertStatement() { virtual ~InsertStatement() {
delete table_name; delete tableName;
delete columns; delete columns;
delete values; delete values;
delete select; delete select;
} }
InsertType type; InsertType type;
const char* table_name; const char* tableName;
std::vector<char*>* columns; std::vector<char*>* columns;
std::vector<Expr*>* values; std::vector<Expr*>* values;
SelectStatement* select; SelectStatement* select;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -7,11 +7,9 @@
#include <algorithm> #include <algorithm>
namespace hsql { namespace hsql {
/** /**
* @struct PrepareStatement * Represents SQL Prepare statements.
* @brief Represents "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?" * Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?"
*/ */
struct PrepareStatement : SQLStatement { struct PrepareStatement : SQLStatement {
PrepareStatement() : PrepareStatement() :
@ -25,10 +23,10 @@ namespace hsql {
} }
/** /**
* @param vector of placeholders that the parser found
*
* When setting the placeholders we need to make sure that they are in the correct order. * When setting the placeholders we need to make sure that they are in the correct order.
* To ensure that, during parsing we store the character position use that to sort the list here. * To ensure that, during parsing we store the character position use that to sort the list here.
*
* @param vector of placeholders that the parser found
*/ */
void setPlaceholders(std::vector<void*> ph) { void setPlaceholders(std::vector<void*> ph) {
for (void* e : ph) { for (void* e : ph) {
@ -47,8 +45,5 @@ namespace hsql {
std::vector<Expr*> placeholders; std::vector<Expr*> placeholders;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -5,7 +5,6 @@
#include <vector> #include <vector>
namespace hsql { namespace hsql {
typedef enum { typedef enum {
kStmtError, // unused kStmtError, // unused
kStmtSelect, kStmtSelect,
@ -22,7 +21,6 @@ namespace hsql {
kStmtAlter kStmtAlter
} StatementType; } StatementType;
/** /**
* Base struct for every SQL statement * Base struct for every SQL statement
*/ */
@ -41,5 +39,4 @@ namespace hsql {
}; };
} // namespace hsql } // namespace hsql
#endif // __SQLSTATEMENT_H__ #endif // __SQLSTATEMENT_H__

View File

@ -6,20 +6,15 @@
#include "Table.h" #include "Table.h"
namespace hsql { namespace hsql {
/**
* @struct OrderDescription
* @brief Description of the order by clause within a select statement
*
* TODO: hold multiple expressions to be sorted by
*/
typedef enum { typedef enum {
kOrderAsc, kOrderAsc,
kOrderDesc kOrderDesc
} OrderType; } OrderType;
/**
* Description of the order by clause within a select statement
* TODO: hold multiple expressions to be sorted by
*/
struct OrderDescription { struct OrderDescription {
OrderDescription(OrderType type, Expr* expr) : OrderDescription(OrderType type, Expr* expr) :
type(type), type(type),
@ -33,12 +28,12 @@ namespace hsql {
Expr* expr; Expr* expr;
}; };
/**
* @struct LimitDescription
* @brief Description of the limit clause within a select statement
*/
const int64_t kNoLimit = -1; const int64_t kNoLimit = -1;
const int64_t kNoOffset = -1; const int64_t kNoOffset = -1;
/**
* Description of the limit clause within a select statement
*/
struct LimitDescription { struct LimitDescription {
LimitDescription(int64_t limit, int64_t offset) : LimitDescription(int64_t limit, int64_t offset) :
limit(limit), limit(limit),
@ -49,7 +44,7 @@ namespace hsql {
}; };
/** /**
* @struct GroupByDescription * Description of the group-by clause within a select statement
*/ */
struct GroupByDescription { struct GroupByDescription {
GroupByDescription() : GroupByDescription() :
@ -66,43 +61,40 @@ namespace hsql {
}; };
/** /**
* @struct SelectStatement * Representation of a full SQL select statement.
* @brief Representation of a full select statement.
*
* TODO: add union_order and union_limit * TODO: add union_order and union_limit
*/ */
struct SelectStatement : SQLStatement { struct SelectStatement : SQLStatement {
SelectStatement() : SelectStatement() :
SQLStatement(kStmtSelect), SQLStatement(kStmtSelect),
from_table(NULL), fromTable(NULL),
select_list(NULL), selectDistinct(false),
where_clause(NULL), selectList(NULL),
group_by(NULL), whereClause(NULL),
union_select(NULL), groupBy(NULL),
unionSelect(NULL),
order(NULL), order(NULL),
limit(NULL) {}; limit(NULL) {};
virtual ~SelectStatement() { virtual ~SelectStatement() {
delete from_table; delete fromTable;
delete select_list; delete selectList;
delete where_clause; delete whereClause;
delete group_by; delete groupBy;
delete order; delete order;
delete limit; delete limit;
} }
TableRef* from_table; TableRef* fromTable;
bool select_distinct; bool selectDistinct;
std::vector<Expr*>* select_list; std::vector<Expr*>* selectList;
Expr* where_clause; Expr* whereClause;
GroupByDescription* group_by; GroupByDescription* groupBy;
SelectStatement* union_select; SelectStatement* unionSelect;
OrderDescription* order; OrderDescription* order;
LimitDescription* limit; LimitDescription* limit;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,21 +4,16 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* @struct UpdateClause * Represents "column = value" expressions
* @brief Represents "column = value" expressions
*/ */
struct UpdateClause { struct UpdateClause {
char* column; char* column;
Expr* value; Expr* value;
}; };
/** /**
* @struct UpdateStatement * Represents SQL Update statements.
* @brief Represents "UPDATE"
*/ */
struct UpdateStatement : SQLStatement { struct UpdateStatement : SQLStatement {
UpdateStatement() : UpdateStatement() :
@ -39,7 +34,5 @@ namespace hsql {
Expr* where; Expr* where;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -5,183 +5,183 @@
namespace hsql { namespace hsql {
void printOperatorExpression(Expr* expr, uint num_indent); void printOperatorExpression(Expr* expr, uint numIndent);
std::string indent(uint num_indent) { std::string indent(uint numIndent) {
return std::string(num_indent, '\t'); return std::string(numIndent, '\t');
} }
void inprint(int64_t val, uint num_indent) { void inprint(int64_t val, uint numIndent) {
printf("%s%ld \n", indent(num_indent).c_str(), val); printf("%s%ld \n", indent(numIndent).c_str(), val);
} }
void inprint(float val, uint num_indent) { void inprint(float val, uint numIndent) {
printf("%s%f\n", indent(num_indent).c_str(), val); printf("%s%f\n", indent(numIndent).c_str(), val);
} }
void inprint(const char* val, uint num_indent) { void inprint(const char* val, uint numIndent) {
printf("%s%s\n", indent(num_indent).c_str(), val); printf("%s%s\n", indent(numIndent).c_str(), val);
} }
void inprint(const char* val, const char* val2, uint num_indent) { void inprint(const char* val, const char* val2, uint numIndent) {
printf("%s%s->%s\n", indent(num_indent).c_str(), val, val2); printf("%s%s->%s\n", indent(numIndent).c_str(), val, val2);
} }
void inprintC(char val, uint num_indent) { void inprintC(char val, uint numIndent) {
printf("%s%c\n", indent(num_indent).c_str(), val); printf("%s%c\n", indent(numIndent).c_str(), val);
} }
void inprintU(uint64_t val, uint num_indent) { void inprintU(uint64_t val, uint numIndent) {
printf("%s%lu\n", indent(num_indent).c_str(), val); printf("%s%lu\n", indent(numIndent).c_str(), val);
} }
void printTableRefInfo(TableRef* table, uint num_indent) { void printTableRefInfo(TableRef* table, uint numIndent) {
switch (table->type) { switch (table->type) {
case kTableName: case kTableName:
inprint(table->name, num_indent); inprint(table->name, numIndent);
break; break;
case kTableSelect: case kTableSelect:
printSelectStatementInfo(table->select, num_indent); printSelectStatementInfo(table->select, numIndent);
break; break;
case kTableJoin: case kTableJoin:
inprint("Join Table", num_indent); inprint("Join Table", numIndent);
inprint("Left", num_indent+1); inprint("Left", numIndent+1);
printTableRefInfo(table->join->left, num_indent+2); printTableRefInfo(table->join->left, numIndent+2);
inprint("Right", num_indent+1); inprint("Right", numIndent+1);
printTableRefInfo(table->join->right, num_indent+2); printTableRefInfo(table->join->right, numIndent+2);
inprint("Join Condition", num_indent+1); inprint("Join Condition", numIndent+1);
printExpression(table->join->condition, num_indent+2); printExpression(table->join->condition, numIndent+2);
break; break;
case kTableCrossProduct: case kTableCrossProduct:
for (TableRef* tbl : *table->list) printTableRefInfo(tbl, num_indent); for (TableRef* tbl : *table->list) printTableRefInfo(tbl, numIndent);
break; break;
} }
if (table->alias != NULL) { if (table->alias != NULL) {
inprint("Alias", num_indent+1); inprint("Alias", numIndent+1);
inprint(table->alias, num_indent+2); inprint(table->alias, numIndent+2);
} }
} }
void printOperatorExpression(Expr* expr, uint num_indent) { void printOperatorExpression(Expr* expr, uint numIndent) {
if (expr == NULL) { if (expr == NULL) {
inprint("null", num_indent); inprint("null", numIndent);
return; return;
} }
switch (expr->op_type) { switch (expr->op_type) {
case Expr::SIMPLE_OP: case Expr::SIMPLE_OP:
inprintC(expr->op_char, num_indent); inprintC(expr->op_char, numIndent);
break; break;
case Expr::AND: case Expr::AND:
inprint("AND", num_indent); inprint("AND", numIndent);
break; break;
case Expr::OR: case Expr::OR:
inprint("OR", num_indent); inprint("OR", numIndent);
break; break;
case Expr::NOT: case Expr::NOT:
inprint("NOT", num_indent); inprint("NOT", numIndent);
break; break;
default: default:
inprintU(expr->op_type, num_indent); inprintU(expr->op_type, numIndent);
break; break;
} }
printExpression(expr->expr, num_indent+1); printExpression(expr->expr, numIndent+1);
if (expr->expr2 != NULL) printExpression(expr->expr2, num_indent+1); if (expr->expr2 != NULL) printExpression(expr->expr2, numIndent+1);
} }
void printExpression(Expr* expr, uint num_indent) { void printExpression(Expr* expr, uint numIndent) {
switch (expr->type) { switch (expr->type) {
case kExprStar: case kExprStar:
inprint("*", num_indent); inprint("*", numIndent);
break; break;
case kExprColumnRef: case kExprColumnRef:
inprint(expr->name, num_indent); inprint(expr->name, numIndent);
break; break;
// case kExprTableColumnRef: inprint(expr->table, expr->name, num_indent); break; // case kExprTableColumnRef: inprint(expr->table, expr->name, numIndent); break;
case kExprLiteralFloat: case kExprLiteralFloat:
inprint(expr->fval, num_indent); inprint(expr->fval, numIndent);
break; break;
case kExprLiteralInt: case kExprLiteralInt:
inprint(expr->ival, num_indent); inprint(expr->ival, numIndent);
break; break;
case kExprLiteralString: case kExprLiteralString:
inprint(expr->name, num_indent); inprint(expr->name, numIndent);
break; break;
case kExprFunctionRef: case kExprFunctionRef:
inprint(expr->name, num_indent); inprint(expr->name, numIndent);
inprint(expr->expr->name, num_indent+1); inprint(expr->expr->name, numIndent+1);
break; break;
case kExprOperator: case kExprOperator:
printOperatorExpression(expr, num_indent); printOperatorExpression(expr, numIndent);
break; break;
default: default:
fprintf(stderr, "Unrecognized expression type %d\n", expr->type); fprintf(stderr, "Unrecognized expression type %d\n", expr->type);
return; return;
} }
if (expr->alias != NULL) { if (expr->alias != NULL) {
inprint("Alias", num_indent+1); inprint("Alias", numIndent+1);
inprint(expr->alias, num_indent+2); inprint(expr->alias, numIndent+2);
} }
} }
void printSelectStatementInfo(SelectStatement* stmt, uint num_indent) { void printSelectStatementInfo(SelectStatement* stmt, uint numIndent) {
inprint("SelectStatement", num_indent); inprint("SelectStatement", numIndent);
inprint("Fields:", num_indent+1); inprint("Fields:", numIndent+1);
for (Expr* expr : *stmt->select_list) printExpression(expr, num_indent+2); for (Expr* expr : *stmt->selectList) printExpression(expr, numIndent+2);
inprint("Sources:", num_indent+1); inprint("Sources:", numIndent+1);
printTableRefInfo(stmt->from_table, num_indent+2); printTableRefInfo(stmt->fromTable, numIndent+2);
if (stmt->where_clause != NULL) { if (stmt->whereClause != NULL) {
inprint("Search Conditions:", num_indent+1); inprint("Search Conditions:", numIndent+1);
printExpression(stmt->where_clause, num_indent+2); printExpression(stmt->whereClause, numIndent+2);
} }
if (stmt->union_select != NULL) { if (stmt->unionSelect != NULL) {
inprint("Union:", num_indent+1); inprint("Union:", numIndent+1);
printSelectStatementInfo(stmt->union_select, num_indent+2); printSelectStatementInfo(stmt->unionSelect, numIndent+2);
} }
if (stmt->order != NULL) { if (stmt->order != NULL) {
inprint("OrderBy:", num_indent+1); inprint("OrderBy:", numIndent+1);
printExpression(stmt->order->expr, num_indent+2); printExpression(stmt->order->expr, numIndent+2);
if (stmt->order->type == kOrderAsc) inprint("ascending", num_indent+2); if (stmt->order->type == kOrderAsc) inprint("ascending", numIndent+2);
else inprint("descending", num_indent+2); else inprint("descending", numIndent+2);
} }
if (stmt->limit != NULL) { if (stmt->limit != NULL) {
inprint("Limit:", num_indent+1); inprint("Limit:", numIndent+1);
inprint(stmt->limit->limit, num_indent+2); inprint(stmt->limit->limit, numIndent+2);
} }
} }
void printImportStatementInfo(ImportStatement* stmt, uint num_indent) { void printImportStatementInfo(ImportStatement* stmt, uint numIndent) {
inprint("ImportStatment", num_indent); inprint("ImportStatment", numIndent);
inprint(stmt->file_path, num_indent+1); inprint(stmt->filePath, numIndent+1);
inprint(stmt->table_name, num_indent+1); inprint(stmt->tableName, numIndent+1);
} }
void printCreateStatementInfo(CreateStatement* stmt, uint num_indent) { void printCreateStatementInfo(CreateStatement* stmt, uint numIndent) {
inprint("CreateStatment", num_indent); inprint("CreateStatment", numIndent);
inprint(stmt->table_name, num_indent+1); inprint(stmt->tableName, numIndent+1);
inprint(stmt->file_path, num_indent+1); inprint(stmt->filePath, numIndent+1);
} }
void printInsertStatementInfo(InsertStatement* stmt, uint num_indent) { void printInsertStatementInfo(InsertStatement* stmt, uint numIndent) {
inprint("InsertStatment", num_indent); inprint("InsertStatment", numIndent);
inprint(stmt->table_name, num_indent+1); inprint(stmt->tableName, numIndent+1);
if (stmt->columns != NULL) { if (stmt->columns != NULL) {
inprint("Columns", num_indent+1); inprint("Columns", numIndent+1);
for (char* col_name : *stmt->columns) { for (char* col_name : *stmt->columns) {
inprint(col_name, num_indent+2); inprint(col_name, numIndent+2);
} }
} }
switch (stmt->type) { switch (stmt->type) {
case InsertStatement::kInsertValues: case InsertStatement::kInsertValues:
inprint("Values", num_indent+1); inprint("Values", numIndent+1);
for (Expr* expr : *stmt->values) { for (Expr* expr : *stmt->values) {
printExpression(expr, num_indent+2); printExpression(expr, numIndent+2);
} }
break; break;
case InsertStatement::kInsertSelect: case InsertStatement::kInsertSelect:
printSelectStatementInfo(stmt->select, num_indent+1); printSelectStatementInfo(stmt->select, numIndent+1);
break; break;
} }
} }

View File

@ -2,21 +2,21 @@
#define __HELPER_H__ #define __HELPER_H__
#define TEST_PARSE_SQL_QUERY(query, output_var, num_statements) \ #define TEST_PARSE_SQL_QUERY(query, outputVar, numStatements) \
SQLParserResult* output_var = SQLParser::parseSQLString(query); \ SQLParserResult* outputVar = SQLParser::parseSQLString(query); \
ASSERT(output_var->isValid); \ ASSERT(outputVar->isValid); \
ASSERT_EQ(output_var->size(), num_statements); ASSERT_EQ(outputVar->size(), numStatements);
#define TEST_PARSE_SINGLE_SQL(query, stmt_type, stmt_class, output_var) \ #define TEST_PARSE_SINGLE_SQL(query, stmtType, stmtClass, outputVar) \
TEST_PARSE_SQL_QUERY(query, stmt_list, 1); \ TEST_PARSE_SQL_QUERY(query, stmt_list, 1); \
ASSERT_EQ(stmt_list->getStatement(0)->type(), stmt_type); \ ASSERT_EQ(stmt_list->getStatement(0)->type(), stmtType); \
stmt_class* output_var = (stmt_class*) stmt_list->getStatement(0); stmtClass* outputVar = (stmtClass*) stmt_list->getStatement(0);
#define TEST_CAST_STMT(stmt_list, stmt_index, stmt_type, stmt_class, output_var) \ #define TEST_CAST_STMT(stmt_list, stmt_index, stmtType, stmtClass, outputVar) \
ASSERT_EQ(stmt_list->getStatement(stmt_index)->type(), stmt_type); \ ASSERT_EQ(stmt_list->getStatement(stmt_index)->type(), stmtType); \
stmt_class* output_var = (stmt_class*) stmt_list->getStatement(stmt_index); stmtClass* outputVar = (stmtClass*) stmt_list->getStatement(stmt_index);
#endif #endif

View File

@ -9,16 +9,16 @@ using namespace hsql;
TEST(SelectTest) { TEST(SelectTest) {
TEST_PARSE_SINGLE_SQL("SELECT * FROM students;", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT * FROM students;", kStmtSelect, SelectStatement, stmt);
ASSERT_NULL(stmt->where_clause); ASSERT_NULL(stmt->whereClause);
ASSERT_NULL(stmt->group_by); ASSERT_NULL(stmt->groupBy);
} }
TEST(SelectHavingTest) { TEST(SelectHavingTest) {
TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT city, AVG(grade) AS avg_grade FROM students GROUP BY city HAVING AVG(grade) < 2.0", kStmtSelect, SelectStatement, stmt);
ASSERT_FALSE(stmt->select_distinct); ASSERT_FALSE(stmt->selectDistinct);
GroupByDescription* group = stmt->group_by; GroupByDescription* group = stmt->groupBy;
ASSERT_NOTNULL(group); ASSERT_NOTNULL(group);
ASSERT_EQ(group->columns->size(), 1); ASSERT_EQ(group->columns->size(), 1);
ASSERT(group->having->isSimpleOp('<')); ASSERT(group->having->isSimpleOp('<'));
@ -30,17 +30,17 @@ TEST(SelectHavingTest) {
TEST(SelectDistinctTest) { TEST(SelectDistinctTest) {
TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT DISTINCT grade, city FROM students;", kStmtSelect, SelectStatement, stmt);
ASSERT(stmt->select_distinct); ASSERT(stmt->selectDistinct);
ASSERT_NULL(stmt->where_clause); ASSERT_NULL(stmt->whereClause);
} }
TEST(SelectGroupDistinctTest) { TEST(SelectGroupDistinctTest) {
TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt); TEST_PARSE_SINGLE_SQL("SELECT city, COUNT(name), COUNT(DISTINCT grade) FROM students GROUP BY city;", kStmtSelect, SelectStatement, stmt);
ASSERT_FALSE(stmt->select_distinct); ASSERT_FALSE(stmt->selectDistinct);
ASSERT_EQ(stmt->select_list->size(), 3); ASSERT_EQ(stmt->selectList->size(), 3);
ASSERT(!stmt->select_list->at(1)->distinct); ASSERT(!stmt->selectList->at(1)->distinct);
ASSERT(stmt->select_list->at(2)->distinct); ASSERT(stmt->selectList->at(2)->distinct);
} }

View File

@ -7,9 +7,9 @@ class TestsManager {
// http://www.parashift.com/c++-faq-lite/static-init-order.html // http://www.parashift.com/c++-faq-lite/static-init-order.html
// http://www.parashift.com/c++-faq-lite/static-init-order-on-first-use.html // http://www.parashift.com/c++-faq-lite/static-init-order-on-first-use.html
public: public:
static std::vector<std::string>& test_names() { static std::vector<std::string>& testNames() {
static std::vector<std::string>* test_names = new std::vector<std::string>; static std::vector<std::string>* _testNames = new std::vector<std::string>;
return *test_names; return *_testNames;
} }
static std::vector<void (*)(void)>& tests() { static std::vector<void (*)(void)>& tests() {
@ -22,26 +22,26 @@ public:
int AddTest(void (*foo)(void), std::string name) { int AddTest(void (*foo)(void), std::string name) {
TestsManager::tests().push_back(foo); TestsManager::tests().push_back(foo);
TestsManager::test_names().push_back(name); TestsManager::testNames().push_back(name);
return 0; return 0;
} }
void RunTests() { void RunTests() {
size_t num_failed = 0; size_t numFailed = 0;
for (size_t i = 0; i < TestsManager::tests().size(); ++i) { for (size_t i = 0; i < TestsManager::tests().size(); ++i) {
printf("\033[0;32m{ running}\033[0m %s\n", TestsManager::test_names()[i].c_str()); printf("\033[0;32m{ running}\033[0m %s\n", TestsManager::testNames()[i].c_str());
try { try {
// Run test // Run test
(*TestsManager::tests()[i])(); (*TestsManager::tests()[i])();
printf("\033[0;32m{ ok}\033[0m %s\n", TestsManager::test_names()[i].c_str()); printf("\033[0;32m{ ok}\033[0m %s\n", TestsManager::testNames()[i].c_str());
} catch (AssertionFailedException& e) { } catch (AssertionFailedException& e) {
printf("\033[1;31m{ failed} %s\n", TestsManager::test_names()[i].c_str()); printf("\033[1;31m{ failed} %s\n", TestsManager::testNames()[i].c_str());
printf("\tAssertion failed: %s\n\033[0m", e.what()); printf("\tAssertion failed: %s\n\033[0m", e.what());
num_failed++; numFailed++;
} }
} }

View File

@ -44,11 +44,6 @@ protected:
std::string _msg; std::string _msg;
}; };
int AddTest(void (*foo)(void), std::string name); int AddTest(void (*foo)(void), std::string name);
#endif #endif

View File

@ -33,17 +33,17 @@ int main(int argc, char *argv[]) {
return -1; return -1;
} }
bool expect_false = false; bool expectFalse = false;
bool use_file = false; bool useFile = false;
std::string file_path = ""; std::string filePath = "";
// Parse command line arguments // Parse command line arguments
int i = 1; int i = 1;
for (; i < argc; ++i) { for (; i < argc; ++i) {
if (STREQ(argv[i], "--false")) expect_false = true; if (STREQ(argv[i], "--false")) expectFalse = true;
else if (STREQ(argv[i], "-f")) { else if (STREQ(argv[i], "-f")) {
use_file = true; useFile = true;
file_path = argv[++i]; filePath = argv[++i];
} else { } else {
break; break;
} }
@ -52,15 +52,15 @@ int main(int argc, char *argv[]) {
// Read list of queries for this rest // Read list of queries for this rest
std::vector<std::string> queries; std::vector<std::string> queries;
if (use_file) { if (useFile) {
queries = readlines(file_path); queries = readlines(filePath);
} else { } else {
for (; i < argc; ++i) queries.push_back(argv[i]); for (; i < argc; ++i) queries.push_back(argv[i]);
} }
// Execute queries // Execute queries
int num_failed = 0; int numFailed = 0;
for (std::string sql : queries) { for (std::string sql : queries) {
// Measuring the parsing time // Measuring the parsing time
std::chrono::time_point<std::chrono::system_clock> start, end; std::chrono::time_point<std::chrono::system_clock> start, end;
@ -73,21 +73,21 @@ int main(int argc, char *argv[]) {
std::chrono::duration<double> elapsed_seconds = end-start; std::chrono::duration<double> elapsed_seconds = end-start;
double us = elapsed_seconds.count() * 1000 * 1000; double us = elapsed_seconds.count() * 1000 * 1000;
if (expect_false == stmt_list->isValid) { if (expectFalse == stmt_list->isValid) {
printf("\033[0;31m{ failed}\033[0m\n"); printf("\033[0;31m{ failed}\033[0m\n");
printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->errorMsg, stmt_list->errorLine, stmt_list->errorColumn); printf("\t\033[0;31m%s (L%d:%d)\n\033[0m", stmt_list->errorMsg, stmt_list->errorLine, stmt_list->errorColumn);
printf("\t%s\n", sql.c_str()); printf("\t%s\n", sql.c_str());
num_failed++; numFailed++;
} else { } else {
// TODO: indicate whether expect_false was set // TODO: indicate whether expectFalse was set
printf("\033[0;32m{ ok} (%.1fus)\033[0m %s\n", us, sql.c_str()); printf("\033[0;32m{ ok} (%.1fus)\033[0m %s\n", us, sql.c_str());
} }
} }
if (num_failed == 0) { if (numFailed == 0) {
printf("\033[0;32m{ ok} \033[0mAll %lu grammar tests completed successfully!\n", queries.size()); printf("\033[0;32m{ ok} \033[0mAll %lu grammar tests completed successfully!\n", queries.size());
} else { } else {
fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", num_failed, queries.size()); fprintf(stderr, "\033[0;31m{ failed} \033[0mSome grammar tests failed! %d out of %lu tests failed!\n", numFailed, queries.size());
} }

View File

@ -17,7 +17,7 @@ TEST(DeleteStatementTest) {
ASSERT(result->getStatement(0)->type() == kStmtDelete); ASSERT(result->getStatement(0)->type() == kStmtDelete);
DeleteStatement* stmt = (DeleteStatement*) result->getStatement(0); DeleteStatement* stmt = (DeleteStatement*) result->getStatement(0);
ASSERT_STREQ(stmt->table_name, "students"); ASSERT_STREQ(stmt->tableName, "students");
ASSERT_NOTNULL(stmt->expr); ASSERT_NOTNULL(stmt->expr);
ASSERT(stmt->expr->isType(kExprOperator)); ASSERT(stmt->expr->isType(kExprOperator));
ASSERT_STREQ(stmt->expr->expr->name, "grade"); ASSERT_STREQ(stmt->expr->expr->name, "grade");
@ -32,7 +32,7 @@ TEST(CreateStatementTest) {
CreateStatement* stmt = (CreateStatement*) result->getStatement(0); CreateStatement* stmt = (CreateStatement*) result->getStatement(0);
ASSERT_EQ(stmt->type, CreateStatement::kTable); ASSERT_EQ(stmt->type, CreateStatement::kTable);
ASSERT_STREQ(stmt->table_name, "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(), 4);
ASSERT_STREQ(stmt->columns->at(0)->name, "name"); ASSERT_STREQ(stmt->columns->at(0)->name, "name");
@ -114,18 +114,18 @@ TEST(PrepareStatementTest) {
TEST_CAST_STMT(prep1->query, 1, kStmtSelect, SelectStatement, select); TEST_CAST_STMT(prep1->query, 1, kStmtSelect, SelectStatement, select);
ASSERT(insert->values->at(0)->isType(kExprPlaceholder)); ASSERT(insert->values->at(0)->isType(kExprPlaceholder));
ASSERT(select->select_list->at(0)->isType(kExprPlaceholder)); ASSERT(select->selectList->at(0)->isType(kExprPlaceholder));
ASSERT(select->where_clause->expr2->isType(kExprPlaceholder)); ASSERT(select->whereClause->expr2->isType(kExprPlaceholder));
// Check IDs of placeholders // Check IDs of placeholders
ASSERT_EQ(insert->values->at(0)->ival, 0); ASSERT_EQ(insert->values->at(0)->ival, 0);
ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]); ASSERT_EQ(insert->values->at(0), prep1->placeholders[0]);
ASSERT_EQ(select->select_list->at(0)->ival, 1); ASSERT_EQ(select->selectList->at(0)->ival, 1);
ASSERT_EQ(select->select_list->at(0), prep1->placeholders[1]); ASSERT_EQ(select->selectList->at(0), prep1->placeholders[1]);
ASSERT_EQ(select->where_clause->expr2->ival, 2); ASSERT_EQ(select->whereClause->expr2->ival, 2);
ASSERT_EQ(select->where_clause->expr2, prep1->placeholders[2]); ASSERT_EQ(select->whereClause->expr2, prep1->placeholders[2]);
// Prepare Statement #2 // Prepare Statement #2
ASSERT_STREQ(prep2->name, "stmt"); ASSERT_STREQ(prep2->name, "stmt");