change indent to spaces=2 and indent access modifiers. minor style changes

This commit is contained in:
Pedro 2017-02-08 02:06:15 +01:00
parent 8582c7f901
commit 28214e8043
24 changed files with 953 additions and 951 deletions

View File

@ -1,8 +1,10 @@
--style=google
# indentation # indentation
--indent=spaces=4 --indent=spaces=2
--indent-namespaces --indent-namespaces
--style=java --align-reference=type
--style=attach --align-pointer=type
-A2 --pad-oper

View File

@ -8,39 +8,39 @@
namespace hsql { namespace hsql {
SQLParser::SQLParser() { SQLParser::SQLParser() {
fprintf(stderr, "SQLParser only has static methods atm! Do not initialize!\n"); fprintf(stderr, "SQLParser only has static methods atm! Do not initialize!\n");
}
SQLParserResult* SQLParser::parseSQLString(const char* text) {
SQLParserResult* result = NULL;
yyscan_t scanner;
YY_BUFFER_STATE state;
if (hsql_lex_init(&scanner)) {
// couldn't initialize
fprintf(stderr, "[Error] SQLParser: Error when initializing lexer!\n");
return NULL;
} }
state = hsql__scan_string(text, scanner);
SQLParserResult* SQLParser::parseSQLString(const char *text) { if (hsql_parse(&result, scanner)) {
SQLParserResult* result = NULL; // Returns an error stmt object
yyscan_t scanner; return result;
YY_BUFFER_STATE state;
if (hsql_lex_init(&scanner)) {
// couldn't initialize
fprintf(stderr, "[Error] SQLParser: Error when initializing lexer!\n");
return NULL;
}
state = hsql__scan_string(text, scanner);
if (hsql_parse(&result, scanner)) {
// Returns an error stmt object
return result;
}
hsql__delete_buffer(state, scanner);
hsql_lex_destroy(scanner);
return result;
} }
hsql__delete_buffer(state, scanner);
SQLParserResult* SQLParser::parseSQLString(const std::string& text) { hsql_lex_destroy(scanner);
return parseSQLString(text.c_str()); return result;
} }
SQLParserResult* SQLParser::parseSQLString(const std::string& text) {
return parseSQLString(text.c_str());
}
} // namespace hsql } // namespace hsql

View File

@ -5,17 +5,17 @@
#include "sql/statements.h" #include "sql/statements.h"
namespace hsql { namespace hsql {
/** /**
* Main class for parsing SQL strings * Main class for parsing SQL strings
*/ */
class SQLParser { class SQLParser {
public: public:
static SQLParserResult* parseSQLString(const char* sql); static SQLParserResult* parseSQLString(const char* sql);
static SQLParserResult* parseSQLString(const std::string& sql); static SQLParserResult* parseSQLString(const std::string& sql);
private: private:
SQLParser(); SQLParser();
}; };
} // namespace hsql } // namespace hsql

View File

@ -3,39 +3,39 @@
namespace hsql { namespace hsql {
SQLParserResult::SQLParserResult() : SQLParserResult::SQLParserResult() :
isValid(true), isValid(true),
errorMsg(NULL) {}; errorMsg(NULL) {};
SQLParserResult::SQLParserResult(SQLStatement* stmt) : SQLParserResult::SQLParserResult(SQLStatement* stmt) :
isValid(true), isValid(true),
errorMsg(NULL) { errorMsg(NULL) {
addStatement(stmt); addStatement(stmt);
}; };
SQLParserResult::~SQLParserResult() { SQLParserResult::~SQLParserResult() {
for (std::vector<SQLStatement*>::iterator it = statements.begin(); it != statements.end(); ++it) { for (std::vector<SQLStatement*>::iterator it = statements.begin(); it != statements.end(); ++it) {
delete *it; delete *it;
}
delete errorMsg;
} }
delete errorMsg;
void SQLParserResult::addStatement(SQLStatement* stmt) { }
statements.push_back(stmt);
}
SQLStatement* SQLParserResult::getStatement(int id) { void SQLParserResult::addStatement(SQLStatement* stmt) {
return statements[id]; statements.push_back(stmt);
} }
size_t SQLParserResult::size() { SQLStatement* SQLParserResult::getStatement(int id) {
return statements.size(); return statements[id];
} }
size_t SQLParserResult::size() {
return statements.size();
}
} // namespace hsql } // namespace hsql

View File

@ -4,31 +4,31 @@
#include "sql/SQLStatement.h" #include "sql/SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* Represents the result of the SQLParser. * Represents the result of the SQLParser.
* If parsing was successful it contains a list of SQLStatement. * If parsing was successful it contains a list of SQLStatement.
*/ */
class SQLParserResult { class SQLParserResult {
public: public:
SQLParserResult(); SQLParserResult();
SQLParserResult(SQLStatement* stmt); SQLParserResult(SQLStatement* stmt);
virtual ~SQLParserResult(); virtual ~SQLParserResult();
void addStatement(SQLStatement* stmt); void addStatement(SQLStatement* stmt);
SQLStatement* getStatement(int id); SQLStatement* getStatement(int id);
size_t size(); size_t size();
// public properties // public properties
std::vector<SQLStatement*> statements; std::vector<SQLStatement*> statements;
bool isValid; bool isValid;
const char* errorMsg; const char* errorMsg;
int errorLine; int errorLine;
int errorColumn; int errorColumn;
}; };
} // namespace hsql } // namespace hsql

View File

@ -5,39 +5,39 @@
// 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 {
// Represents definition of a table column // Represents definition of a table column
struct ColumnDefinition { struct ColumnDefinition {
enum DataType { enum DataType {
TEXT, TEXT,
INT, INT,
DOUBLE DOUBLE
};
ColumnDefinition(char* name, DataType type);
virtual ~ColumnDefinition();
char* name;
DataType type;
}; };
ColumnDefinition(char* name, DataType type);
virtual ~ColumnDefinition();
// Represents SQL Create statements. char* name;
// Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)" DataType type;
struct CreateStatement : SQLStatement { };
enum CreateType {
kTable,
kTableFromTbl // Hyrise file format
};
CreateStatement(CreateType type);
virtual ~CreateStatement();
CreateType type; // Represents SQL Create statements.
bool ifNotExists; // default: false // Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)"
const char* filePath; // default: NULL struct CreateStatement : SQLStatement {
const char* tableName; // default: NULL enum CreateType {
std::vector<ColumnDefinition*>* columns; // default: NULL kTable,
kTableFromTbl // Hyrise file format
}; };
CreateStatement(CreateType type);
virtual ~CreateStatement();
CreateType type;
bool ifNotExists; // default: false
const char* filePath; // default: NULL
const char* tableName; // default: NULL
std::vector<ColumnDefinition*>* columns; // default: NULL
};
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -5,16 +5,16 @@
// 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 {
// Represents SQL Delete statements. // Represents SQL Delete statements.
// Example: "DELETE FROM students WHERE grade > 3.0" // Example: "DELETE FROM students WHERE grade > 3.0"
// Note: if (expr == NULL) => delete all rows (truncate) // Note: if (expr == NULL) => delete all rows (truncate)
struct DeleteStatement : SQLStatement { struct DeleteStatement : SQLStatement {
DeleteStatement(); DeleteStatement();
virtual ~DeleteStatement(); virtual ~DeleteStatement();
char* tableName; char* tableName;
Expr* expr; Expr* expr;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -5,23 +5,23 @@
// 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 {
// Represents SQL Delete statements. // Represents SQL Delete statements.
// Example "DROP TABLE students;" // Example "DROP TABLE students;"
struct DropStatement : SQLStatement { struct DropStatement : SQLStatement {
enum EntityType { enum EntityType {
kTable, kTable,
kSchema, kSchema,
kIndex, kIndex,
kView, kView,
kPreparedStatement kPreparedStatement
};
DropStatement(EntityType type);
virtual ~DropStatement();
EntityType type;
const char* name;
}; };
DropStatement(EntityType type);
virtual ~DropStatement();
EntityType type;
const char* name;
};
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,17 +4,17 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* Represents SQL Execute statements. * Represents SQL Execute statements.
* Example: "EXECUTE ins_prep(100, "test", 2.3);" * Example: "EXECUTE ins_prep(100, "test", 2.3);"
*/ */
struct ExecuteStatement : SQLStatement { struct ExecuteStatement : SQLStatement {
ExecuteStatement(); ExecuteStatement();
virtual ~ExecuteStatement(); virtual ~ExecuteStatement();
const char* name; const char* name;
std::vector<Expr*>* parameters; std::vector<Expr*>* parameters;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -5,127 +5,127 @@
namespace hsql { namespace hsql {
Expr::Expr(ExprType type) : Expr::Expr(ExprType type) :
type(type), type(type),
expr(NULL), expr(NULL),
expr2(NULL), expr2(NULL),
name(NULL), name(NULL),
table(NULL), table(NULL),
alias(NULL) {}; alias(NULL) {};
Expr::~Expr() { Expr::~Expr() {
delete expr; delete expr;
delete expr2; delete expr2;
delete name; delete name;
delete table; delete table;
} }
Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) { Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->op_type = op; e->op_type = op;
e->expr = expr; e->expr = expr;
e->expr2 = NULL; e->expr2 = NULL;
return e; return e;
} }
Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) { Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->op_type = op; e->op_type = op;
e->op_char = 0; e->op_char = 0;
e->expr = expr1; e->expr = expr1;
e->expr2 = expr2; e->expr2 = expr2;
return e; return e;
} }
Expr* Expr::makeOpBinary(Expr* expr1, char op, Expr* expr2) { Expr* Expr::makeOpBinary(Expr* expr1, char op, Expr* expr2) {
Expr* e = new Expr(kExprOperator); Expr* e = new Expr(kExprOperator);
e->op_type = SIMPLE_OP; e->op_type = SIMPLE_OP;
e->op_char = op; e->op_char = op;
e->expr = expr1; e->expr = expr1;
e->expr2 = expr2; e->expr2 = expr2;
return e; return e;
} }
Expr* Expr::makeLiteral(int64_t val) { Expr* Expr::makeLiteral(int64_t val) {
Expr* e = new Expr(kExprLiteralInt); Expr* e = new Expr(kExprLiteralInt);
e->ival = val; e->ival = val;
return e; return e;
} }
Expr* Expr::makeLiteral(double value) { Expr* Expr::makeLiteral(double value) {
Expr* e = new Expr(kExprLiteralFloat); Expr* e = new Expr(kExprLiteralFloat);
e->fval = value; e->fval = value;
return e; return e;
} }
Expr* Expr::makeLiteral(char* string) { Expr* Expr::makeLiteral(char* string) {
Expr* e = new Expr(kExprLiteralString); Expr* e = new Expr(kExprLiteralString);
e->name = string; e->name = string;
return e; return e;
} }
Expr* Expr::makeColumnRef(char* name) { Expr* Expr::makeColumnRef(char* name) {
Expr* e = new Expr(kExprColumnRef); Expr* e = new Expr(kExprColumnRef);
e->name = name; e->name = name;
return e; return e;
} }
Expr* Expr::makeColumnRef(char* table, char* name) { Expr* Expr::makeColumnRef(char* table, char* name) {
Expr* e = new Expr(kExprColumnRef); Expr* e = new Expr(kExprColumnRef);
e->name = name; e->name = name;
e->table = table; e->table = table;
return e; return e;
} }
Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) { Expr* Expr::makeFunctionRef(char* func_name, Expr* expr, bool distinct) {
Expr* e = new Expr(kExprFunctionRef); Expr* e = new Expr(kExprFunctionRef);
e->name = func_name; e->name = func_name;
e->expr = expr; e->expr = expr;
e->distinct = distinct; e->distinct = distinct;
return e; return e;
} }
Expr* Expr::makePlaceholder(int id) { Expr* Expr::makePlaceholder(int id) {
Expr* e = new Expr(kExprPlaceholder); Expr* e = new Expr(kExprPlaceholder);
e->ival = id; e->ival = id;
return e; return e;
} }
bool Expr::isType(ExprType e_type) { bool Expr::isType(ExprType e_type) {
return e_type == type; return e_type == type;
} }
bool Expr::isLiteral() { bool Expr::isLiteral() {
return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || isType(kExprLiteralString) || isType(kExprPlaceholder); return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || isType(kExprLiteralString) || isType(kExprPlaceholder);
} }
bool Expr::hasAlias() { bool Expr::hasAlias() {
return alias != NULL; return alias != NULL;
} }
bool Expr::hasTable() { bool Expr::hasTable() {
return table != NULL; return table != NULL;
} }
char* Expr::getName() { char* Expr::getName() {
if (alias != NULL) return alias; if (alias != NULL) return alias;
else return name; else return name;
} }
bool Expr::isSimpleOp() { bool Expr::isSimpleOp() {
return op_type == SIMPLE_OP; return op_type == SIMPLE_OP;
} }
bool Expr::isSimpleOp(char op) { bool Expr::isSimpleOp(char op) {
return isSimpleOp() && op_char == op; return isSimpleOp() && op_char == op;
} }
char* substr(const char* source, int from, int to) { char* substr(const char* source, int from, int to) {
int len = to-from; int len = to - from;
char* copy = new char[len+1]; char* copy = new char[len + 1];
strncpy(copy, source+from, len); strncpy(copy, source + from, len);
copy[len] = '\0'; copy[len] = '\0';
return copy; return copy;
} }
} // namespace hsql } // namespace hsql

View File

@ -6,111 +6,111 @@
namespace hsql { namespace hsql {
// Helper function used by the lexer. // Helper function used by the lexer.
// TODO: move to more appropriate place. // TODO: move to more appropriate place.
char* substr(const char* source, int from, int to); char* substr(const char* source, int from, int to);
enum ExprType { enum ExprType {
kExprLiteralFloat, kExprLiteralFloat,
kExprLiteralString, kExprLiteralString,
kExprLiteralInt, kExprLiteralInt,
kExprStar, kExprStar,
kExprPlaceholder, kExprPlaceholder,
kExprColumnRef, kExprColumnRef,
kExprFunctionRef, kExprFunctionRef,
kExprOperator kExprOperator
};
typedef struct Expr Expr;
// Represents SQL expressions (i.e. literals, operators, column_refs).
// TODO: When destructing a placeholder expression, we might need to alter the placeholder_list.
struct Expr {
// Operator types. These are important for expressions of type kExprOperator.
// Trivial types are those that can be described by a single character e.g:
// + - * / < > = %
// Non-trivial are: <> <= >= LIKE ISNULL NOT
enum OperatorType {
SIMPLE_OP,
// Binary operators.
NOT_EQUALS,
LESS_EQ,
GREATER_EQ,
LIKE,
NOT_LIKE,
AND,
OR,
// Unary operators.
NOT,
UMINUS,
ISNULL
}; };
typedef struct Expr Expr;
// Represents SQL expressions (i.e. literals, operators, column_refs).
// TODO: When destructing a placeholder expression, we might need to alter the placeholder_list.
struct Expr {
// Operator types. These are important for expressions of type kExprOperator.
// Trivial types are those that can be described by a single character e.g:
// + - * / < > = %
// Non-trivial are: <> <= >= LIKE ISNULL NOT
enum OperatorType {
SIMPLE_OP,
// Binary operators.
NOT_EQUALS,
LESS_EQ,
GREATER_EQ,
LIKE,
NOT_LIKE,
AND,
OR,
// Unary operators.
NOT,
UMINUS,
ISNULL
};
Expr(ExprType type);
Expr(ExprType type); // Interesting side-effect:
// Making the destructor virtual used to cause segmentation faults.
// TODO: inspect.
~Expr();
// Interesting side-effect: ExprType type;
// Making the destructor virtual used to cause segmentation faults.
// TODO: inspect.
~Expr();
ExprType type; Expr* expr;
Expr* expr2;
char* name;
char* table;
char* alias;
float fval;
int64_t ival;
int64_t ival2;
Expr* expr; OperatorType op_type;
Expr* expr2; char op_char;
char* name; bool distinct;
char* table;
char* alias;
float fval;
int64_t ival;
int64_t ival2;
OperatorType op_type; // Convenience accessor methods.
char op_char;
bool distinct;
// Convenience accessor methods. bool isType(ExprType e_type);
bool isType(ExprType e_type); bool isLiteral();
bool isLiteral(); bool hasAlias();
bool hasAlias(); bool hasTable();
bool hasTable(); char* getName();
char* getName(); bool isSimpleOp();
bool isSimpleOp(); bool isSimpleOp(char op);
bool isSimpleOp(char op);
// Static constructors. // Static constructors.
static Expr* makeOpUnary(OperatorType op, Expr* expr); static Expr* makeOpUnary(OperatorType op, Expr* expr);
static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2); static Expr* makeOpBinary(Expr* expr1, char op, Expr* expr2);
static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2); static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2);
static Expr* makeLiteral(int64_t val); static Expr* makeLiteral(int64_t val);
static Expr* makeLiteral(double val); static Expr* makeLiteral(double val);
static Expr* makeLiteral(char* val); static Expr* makeLiteral(char* val);
static Expr* makeColumnRef(char* name); static Expr* makeColumnRef(char* name);
static Expr* makeColumnRef(char* table, char* name); static Expr* makeColumnRef(char* table, char* name);
static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct); static Expr* makeFunctionRef(char* func_name, Expr* expr, bool distinct);
static Expr* makePlaceholder(int id); static Expr* makePlaceholder(int id);
}; };
// Zero initializes an Expr object and assigns it to a space in the heap // Zero initializes an Expr object and assigns it to a space in the heap
// For Hyrise we still had to put in the explicit NULL constructor // For Hyrise we still had to put in the explicit NULL constructor

View File

@ -4,23 +4,23 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* Represents SQL Import statements. * Represents SQL Import statements.
*/ */
struct ImportStatement : SQLStatement { struct ImportStatement : SQLStatement {
enum ImportType { enum ImportType {
kImportCSV, kImportCSV,
kImportTbl, // Hyrise file format kImportTbl, // Hyrise file format
};
ImportStatement(ImportType type);
virtual ~ImportStatement();
ImportType type;
const char* filePath;
const char* tableName;
}; };
ImportStatement(ImportType type);
virtual ~ImportStatement();
ImportType type;
const char* filePath;
const char* tableName;
};
} // namespace hsql } // namespace hsql

View File

@ -5,25 +5,25 @@
#include "SelectStatement.h" #include "SelectStatement.h"
namespace hsql { namespace hsql {
/** /**
* Represents SQL Insert statements. * Represents SQL Insert statements.
* Example: "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 {
kInsertValues, kInsertValues,
kInsertSelect kInsertSelect
};
InsertStatement(InsertType type);
virtual ~InsertStatement();
InsertType type;
const char* tableName;
std::vector<char*>* columns;
std::vector<Expr*>* values;
SelectStatement* select;
}; };
InsertStatement(InsertType type);
virtual ~InsertStatement();
InsertType type;
const char* tableName;
std::vector<char*>* columns;
std::vector<Expr*>* values;
SelectStatement* select;
};
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -7,26 +7,26 @@
#include <algorithm> #include <algorithm>
namespace hsql { namespace hsql {
/**
* Represents SQL Prepare statements.
* Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?"
*/
struct PrepareStatement : SQLStatement {
PrepareStatement();
virtual ~PrepareStatement();
/** /**
* Represents SQL Prepare statements. * When setting the placeholders we need to make sure that they are in the correct order.
* Example: "PREPARE ins_prep: SELECT * FROM t1 WHERE c1 = ? AND c2 = ?" * 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
*/ */
struct PrepareStatement : SQLStatement { void setPlaceholders(std::vector<void*> ph);
PrepareStatement();
virtual ~PrepareStatement();
/** const char* name;
* When setting the placeholders we need to make sure that they are in the correct order. SQLParserResult* query;
* To ensure that, during parsing we store the character position use that to sort the list here. std::vector<Expr*> placeholders;
* };
* @param vector of placeholders that the parser found
*/
void setPlaceholders(std::vector<void*> ph);
const char* name;
SQLParserResult* query;
std::vector<Expr*> placeholders;
};
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -5,35 +5,35 @@
#include <vector> #include <vector>
namespace hsql { namespace hsql {
enum StatementType { enum StatementType {
kStmtError, // unused kStmtError, // unused
kStmtSelect, kStmtSelect,
kStmtImport, kStmtImport,
kStmtInsert, kStmtInsert,
kStmtUpdate, kStmtUpdate,
kStmtDelete, kStmtDelete,
kStmtCreate, kStmtCreate,
kStmtDrop, kStmtDrop,
kStmtPrepare, kStmtPrepare,
kStmtExecute, kStmtExecute,
kStmtExport, kStmtExport,
kStmtRename, kStmtRename,
kStmtAlter kStmtAlter
}; };
/** /**
* Base struct for every SQL statement * Base struct for every SQL statement
*/ */
struct SQLStatement { struct SQLStatement {
SQLStatement(StatementType type); SQLStatement(StatementType type);
virtual ~SQLStatement(); virtual ~SQLStatement();
virtual StatementType type(); virtual StatementType type();
private: private:
StatementType _type; StatementType _type;
}; };
} // namespace hsql } // namespace hsql
#endif // __SQLSTATEMENT_H__ #endif // __SQLSTATEMENT_H__

View File

@ -6,66 +6,66 @@
#include "Table.h" #include "Table.h"
namespace hsql { namespace hsql {
enum OrderType { enum OrderType {
kOrderAsc, kOrderAsc,
kOrderDesc kOrderDesc
}; };
/** /**
* Description of the order by clause within a select statement * Description of the order by clause within a select statement
* TODO: hold multiple expressions to be sorted by * TODO: hold multiple expressions to be sorted by
*/ */
struct OrderDescription { struct OrderDescription {
OrderDescription(OrderType type, Expr* expr); OrderDescription(OrderType type, Expr* expr);
virtual ~OrderDescription(); virtual ~OrderDescription();
OrderType type; OrderType type;
Expr* expr; Expr* expr;
}; };
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 * 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);
int64_t limit; int64_t limit;
int64_t offset; int64_t offset;
}; };
/** /**
* Description of the group-by clause within a select statement * Description of the group-by clause within a select statement
*/ */
struct GroupByDescription { struct GroupByDescription {
GroupByDescription(); GroupByDescription();
// TODO: make virtual // TODO: make virtual
~GroupByDescription(); ~GroupByDescription();
std::vector<Expr*>* columns; std::vector<Expr*>* columns;
Expr* having; Expr* having;
}; };
/** /**
* Representation of a full SQL select statement. * Representation of a full SQL select statement.
* TODO: add union_order and union_limit * TODO: add union_order and union_limit
*/ */
struct SelectStatement : SQLStatement { struct SelectStatement : SQLStatement {
SelectStatement(); SelectStatement();
virtual ~SelectStatement(); virtual ~SelectStatement();
TableRef* fromTable; TableRef* fromTable;
bool selectDistinct; bool selectDistinct;
std::vector<Expr*>* selectList; std::vector<Expr*>* selectList;
Expr* whereClause; Expr* whereClause;
GroupByDescription* groupBy; GroupByDescription* groupBy;
SelectStatement* unionSelect; SelectStatement* unionSelect;
OrderDescription* order; OrderDescription* order;
LimitDescription* limit; LimitDescription* limit;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -7,59 +7,59 @@
namespace hsql { namespace hsql {
struct SelectStatement; struct SelectStatement;
struct JoinDefinition; struct JoinDefinition;
struct TableRef; struct TableRef;
// Possible table reference types. // Possible table reference types.
enum TableRefType { enum TableRefType {
kTableName, kTableName,
kTableSelect, kTableSelect,
kTableJoin, kTableJoin,
kTableCrossProduct kTableCrossProduct
}; };
// Holds reference to tables. Can be either table names or a select statement. // Holds reference to tables. Can be either table names or a select statement.
struct TableRef { struct TableRef {
TableRef(TableRefType type); TableRef(TableRefType type);
virtual ~TableRef(); virtual ~TableRef();
TableRefType type; TableRefType type;
char* schema; char* schema;
char* name; char* name;
char* alias; char* alias;
SelectStatement* select; SelectStatement* select;
std::vector<TableRef*>* list; std::vector<TableRef*>* list;
JoinDefinition* join; JoinDefinition* join;
// Returns true if a schema is set. // Returns true if a schema is set.
bool hasSchema(); bool hasSchema();
// Returns the alias, if it is set. Otherwise the name. // Returns the alias, if it is set. Otherwise the name.
char* getName(); char* getName();
}; };
// Possible types of joins. // Possible types of joins.
enum JoinType { enum JoinType {
kJoinInner, kJoinInner,
kJoinOuter, kJoinOuter,
kJoinLeft, kJoinLeft,
kJoinRight, kJoinRight,
}; };
// Definition of a join construct. // Definition of a join construct.
struct JoinDefinition { struct JoinDefinition {
JoinDefinition(); JoinDefinition();
virtual ~JoinDefinition(); virtual ~JoinDefinition();
TableRef* left; TableRef* left;
TableRef* right; TableRef* right;
Expr* condition; Expr* condition;
JoinType type; JoinType type;
}; };
} // namespace hsql } // namespace hsql
#endif #endif

View File

@ -4,26 +4,26 @@
#include "SQLStatement.h" #include "SQLStatement.h"
namespace hsql { namespace hsql {
/** /**
* Represents "column = value" expressions * Represents "column = value" expressions
*/ */
struct UpdateClause { struct UpdateClause {
char* column; char* column;
Expr* value; Expr* value;
}; };
/** /**
* Represents SQL Update statements. * Represents SQL Update statements.
*/ */
struct UpdateStatement : SQLStatement { struct UpdateStatement : SQLStatement {
UpdateStatement(); UpdateStatement();
virtual ~UpdateStatement(); virtual ~UpdateStatement();
// TODO: switch to char* instead of TableRef // TODO: switch to char* instead of TableRef
TableRef* table; TableRef* table;
std::vector<UpdateClause*>* updates; std::vector<UpdateClause*>* updates;
Expr* where; Expr* where;
}; };
} // namsepace hsql } // namsepace hsql
#endif #endif

View File

@ -3,220 +3,220 @@
namespace hsql { namespace hsql {
// SQLStatement // SQLStatement
SQLStatement::SQLStatement(StatementType type) : SQLStatement::SQLStatement(StatementType type) :
_type(type) {}; _type(type) {};
SQLStatement::~SQLStatement() {} SQLStatement::~SQLStatement() {}
StatementType SQLStatement::type() { StatementType SQLStatement::type() {
return _type; return _type;
}
// ColumnDefinition
ColumnDefinition::ColumnDefinition(char* name, DataType type) :
name(name),
type(type) {};
ColumnDefinition::~ColumnDefinition() {
delete name;
}
// CreateStatemnet
CreateStatement::CreateStatement(CreateType type) :
SQLStatement(kStmtCreate),
type(type),
ifNotExists(false),
filePath(NULL),
tableName(NULL),
columns(NULL) {};
CreateStatement::~CreateStatement() {
delete columns;
delete filePath;
delete tableName;
}
// DeleteStatement
DeleteStatement::DeleteStatement() :
SQLStatement(kStmtDelete),
tableName(NULL),
expr(NULL) {};
DeleteStatement::~DeleteStatement() {
delete tableName;
delete expr;
}
// DropStatament
DropStatement::DropStatement(EntityType type) :
SQLStatement(kStmtDrop),
type(type),
name(NULL) {}
DropStatement::~DropStatement() {
delete name;
}
// ExecuteStatement
ExecuteStatement::ExecuteStatement() :
SQLStatement(kStmtExecute),
name(NULL),
parameters(NULL) {}
ExecuteStatement::~ExecuteStatement() {
delete name;
delete parameters;
}
// ImportStatement
ImportStatement::ImportStatement(ImportType type) :
SQLStatement(kStmtImport),
type(type),
filePath(NULL),
tableName(NULL) {};
ImportStatement::~ImportStatement() {
delete filePath;
delete tableName;
}
// InsertStatement
InsertStatement::InsertStatement(InsertType type) :
SQLStatement(kStmtInsert),
type(type),
tableName(NULL),
columns(NULL),
values(NULL),
select(NULL) {}
InsertStatement::~InsertStatement() {
delete tableName;
delete columns;
delete values;
delete select;
}
// PrepareStatement
PrepareStatement::PrepareStatement() :
SQLStatement(kStmtPrepare),
name(NULL),
query(NULL) {}
PrepareStatement::~PrepareStatement() {
delete query;
delete name;
}
void PrepareStatement::setPlaceholders(std::vector<void*> ph) {
for (void* e : ph) {
if (e != NULL)
placeholders.push_back((Expr*) e);
} }
// Sort by col-id
std::sort(placeholders.begin(), placeholders.end(), [](Expr * i, Expr * j) -> bool { return (i->ival < j->ival); });
// ColumnDefinition // Set the placeholder id on the Expr. This replaces the previously stored column id
ColumnDefinition::ColumnDefinition(char* name, DataType type) : for (uintmax_t i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i;
name(name), }
type(type) {};
ColumnDefinition::~ColumnDefinition() { // SelectStatement.h
delete name;
}
// CreateStatemnet // OrderDescription
CreateStatement::CreateStatement(CreateType type) : OrderDescription::OrderDescription(OrderType type, Expr* expr) :
SQLStatement(kStmtCreate), type(type),
type(type), expr(expr) {}
ifNotExists(false),
filePath(NULL),
tableName(NULL),
columns(NULL) {};
CreateStatement::~CreateStatement() { OrderDescription::~OrderDescription() {
delete columns; delete expr;
delete filePath; }
delete tableName;
}
// DeleteStatement // LimitDescription
DeleteStatement::DeleteStatement() : LimitDescription::LimitDescription(int64_t limit, int64_t offset) :
SQLStatement(kStmtDelete), limit(limit),
tableName(NULL), offset(offset) {}
expr(NULL) {};
DeleteStatement::~DeleteStatement() { // GroypByDescription
delete tableName; GroupByDescription::GroupByDescription() :
delete expr; columns(NULL),
} having(NULL) {}
// DropStatament GroupByDescription::~GroupByDescription() {
DropStatement::DropStatement(EntityType type) : delete columns;
SQLStatement(kStmtDrop), delete having;
type(type), }
name(NULL) {}
DropStatement::~DropStatement() { // SelectStatement
delete name; SelectStatement::SelectStatement() :
} SQLStatement(kStmtSelect),
fromTable(NULL),
selectDistinct(false),
selectList(NULL),
whereClause(NULL),
groupBy(NULL),
unionSelect(NULL),
order(NULL),
limit(NULL) {};
// ExecuteStatement SelectStatement::~SelectStatement() {
ExecuteStatement::ExecuteStatement() : delete fromTable;
SQLStatement(kStmtExecute), delete selectList;
name(NULL), delete whereClause;
parameters(NULL) {} delete groupBy;
delete order;
delete limit;
}
ExecuteStatement::~ExecuteStatement() { // UpdateStatement
delete name; UpdateStatement::UpdateStatement() :
delete parameters; SQLStatement(kStmtUpdate),
} table(NULL),
updates(NULL),
where(NULL) {}
// ImportStatement UpdateStatement::~UpdateStatement() {
ImportStatement::ImportStatement(ImportType type) : delete table;
SQLStatement(kStmtImport), delete updates;
type(type), delete where;
filePath(NULL), }
tableName(NULL) {};
ImportStatement::~ImportStatement() { // TableRef
delete filePath; TableRef::TableRef(TableRefType type) :
delete tableName; type(type),
} schema(NULL),
name(NULL),
alias(NULL),
select(NULL),
list(NULL),
join(NULL) {}
// InsertStatement TableRef::~TableRef() {
InsertStatement::InsertStatement(InsertType type) : delete name;
SQLStatement(kStmtInsert), delete alias;
type(type), delete select;
tableName(NULL), delete list;
columns(NULL), }
values(NULL),
select(NULL) {}
InsertStatement::~InsertStatement() { bool TableRef::hasSchema() {
delete tableName; return schema != NULL;
delete columns; }
delete values;
delete select;
}
// PrepareStatement char* TableRef::getName() {
PrepareStatement::PrepareStatement() : if (alias != NULL) return alias;
SQLStatement(kStmtPrepare), else return name;
name(NULL), }
query(NULL) {}
PrepareStatement::~PrepareStatement() { // JoinDefinition
delete query; JoinDefinition::JoinDefinition() :
delete name; left(NULL),
} right(NULL),
condition(NULL),
type(kJoinInner) {}
void PrepareStatement::setPlaceholders(std::vector<void*> ph) { JoinDefinition::~JoinDefinition() {
for (void* e : ph) { delete left;
if (e != NULL) delete right;
placeholders.push_back((Expr*) e); delete condition;
} }
// Sort by col-id
std::sort(placeholders.begin(), placeholders.end(), [](Expr* i, Expr* j) -> bool { return (i->ival < j->ival); });
// Set the placeholder id on the Expr. This replaces the previously stored column id
for (uintmax_t i = 0; i < placeholders.size(); ++i) placeholders[i]->ival = i;
}
// SelectStatement.h
// OrderDescription
OrderDescription::OrderDescription(OrderType type, Expr* expr) :
type(type),
expr(expr) {}
OrderDescription::~OrderDescription() {
delete expr;
}
// LimitDescription
LimitDescription::LimitDescription(int64_t limit, int64_t offset) :
limit(limit),
offset(offset) {}
// GroypByDescription
GroupByDescription::GroupByDescription() :
columns(NULL),
having(NULL) {}
GroupByDescription::~GroupByDescription() {
delete columns;
delete having;
}
// SelectStatement
SelectStatement::SelectStatement() :
SQLStatement(kStmtSelect),
fromTable(NULL),
selectDistinct(false),
selectList(NULL),
whereClause(NULL),
groupBy(NULL),
unionSelect(NULL),
order(NULL),
limit(NULL) {};
SelectStatement::~SelectStatement() {
delete fromTable;
delete selectList;
delete whereClause;
delete groupBy;
delete order;
delete limit;
}
// UpdateStatement
UpdateStatement::UpdateStatement() :
SQLStatement(kStmtUpdate),
table(NULL),
updates(NULL),
where(NULL) {}
UpdateStatement::~UpdateStatement() {
delete table;
delete updates;
delete where;
}
// TableRef
TableRef::TableRef(TableRefType type) :
type(type),
schema(NULL),
name(NULL),
alias(NULL),
select(NULL),
list(NULL),
join(NULL) {}
TableRef::~TableRef() {
delete name;
delete alias;
delete select;
delete list;
}
bool TableRef::hasSchema() {
return schema != NULL;
}
char* TableRef::getName() {
if (alias != NULL) return alias;
else return name;
}
// JoinDefinition
JoinDefinition::JoinDefinition() :
left(NULL),
right(NULL),
condition(NULL),
type(kJoinInner) {}
JoinDefinition::~JoinDefinition() {
delete left;
delete right;
delete condition;
}
} // namespace hsql } // namespace hsql

View File

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

View File

@ -5,12 +5,12 @@
namespace hsql { namespace hsql {
void printStatementInfo(SQLStatement* stmt); void printStatementInfo(SQLStatement* stmt);
void printSelectStatementInfo(SelectStatement* stmt, uintmax_t num_indent); void printSelectStatementInfo(SelectStatement* stmt, uintmax_t num_indent);
void printImportStatementInfo(ImportStatement* stmt, uintmax_t num_indent); void printImportStatementInfo(ImportStatement* stmt, uintmax_t num_indent);
void printInsertStatementInfo(InsertStatement* stmt, uintmax_t num_indent); void printInsertStatementInfo(InsertStatement* stmt, uintmax_t num_indent);
void printCreateStatementInfo(CreateStatement* stmt, uintmax_t num_indent); void printCreateStatementInfo(CreateStatement* stmt, uintmax_t num_indent);
void printExpression(Expr* expr, uintmax_t num_indent); void printExpression(Expr* expr, uintmax_t num_indent);
} // namespace hsql } // namespace hsql

View File

@ -7,40 +7,40 @@
using namespace hsql; 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->whereClause); ASSERT_NULL(stmt->whereClause);
ASSERT_NULL(stmt->groupBy); 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->selectDistinct); ASSERT_FALSE(stmt->selectDistinct);
GroupByDescription* group = stmt->groupBy; 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('<'));
ASSERT(group->having->expr->isType(kExprFunctionRef)); ASSERT(group->having->expr->isType(kExprFunctionRef));
ASSERT(group->having->expr2->isType(kExprLiteralFloat)); ASSERT(group->having->expr2->isType(kExprLiteralFloat));
} }
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->selectDistinct); ASSERT(stmt->selectDistinct);
ASSERT_NULL(stmt->whereClause); 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->selectDistinct); ASSERT_FALSE(stmt->selectDistinct);
ASSERT_EQ(stmt->selectList->size(), 3); ASSERT_EQ(stmt->selectList->size(), 3);
ASSERT(!stmt->selectList->at(1)->distinct); ASSERT(!stmt->selectList->at(1)->distinct);
ASSERT(stmt->selectList->at(2)->distinct); ASSERT(stmt->selectList->at(2)->distinct);
} }

View File

@ -3,57 +3,57 @@
class TestsManager { class TestsManager {
// Note: static initialization fiasco // Note: static initialization fiasco
// 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>& testNames() { static std::vector<std::string>& testNames() {
static std::vector<std::string>* _testNames = new std::vector<std::string>; static std::vector<std::string>* _testNames = new std::vector<std::string>;
return *_testNames; return *_testNames;
} }
static std::vector<void (*)(void)>& tests() { static std::vector<void (*)(void)>& tests() {
static std::vector<void (*)(void)>* tests = new std::vector<void (*)(void)>; static std::vector<void (*)(void)>* tests = new std::vector<void (*)(void)>;
return *tests; return *tests;
} }
}; };
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::testNames().push_back(name); TestsManager::testNames().push_back(name);
return 0; return 0;
} }
size_t RunTests() { size_t RunTests() {
size_t numFailed = 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::testNames()[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::testNames()[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::testNames()[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());
numFailed++; numFailed++;
}
} }
return numFailed; }
return numFailed;
} }
int main() { int main() {
size_t numFailed = RunTests(); size_t numFailed = RunTests();
if (numFailed == 0) { if (numFailed == 0) {
return 0; return 0;
} else { } else {
return -1; return -1;
} }
} }

View File

@ -31,17 +31,17 @@
class AssertionFailedException: public std::exception { class AssertionFailedException: public std::exception {
public: public:
AssertionFailedException(std::string msg) : AssertionFailedException(std::string msg) :
std::exception(), std::exception(),
_msg(msg) {}; _msg(msg) {};
virtual const char* what() const throw() { virtual const char* what() const throw() {
return _msg.c_str(); return _msg.c_str();
} }
protected: protected:
std::string _msg; std::string _msg;
}; };
int AddTest(void (*foo)(void), std::string name); int AddTest(void (*foo)(void), std::string name);