fix(SQLParser): move to Data dir; add extradirs, remove vs 140,150 build scripts generation

This commit is contained in:
Alex Fabijanic
2024-02-13 14:04:23 +01:00
parent 3261ebbd42
commit ee39b611f2
167 changed files with 780 additions and 792 deletions

View File

@@ -0,0 +1,74 @@
#include "SQLParser.h"
#include <stdio.h>
#include <string>
#include "parser/bison_parser.h"
#include "parser/flex_lexer.h"
namespace hsql {
SQLParser::SQLParser() { fprintf(stderr, "SQLParser only has static methods atm! Do not initialize!\n"); }
// static
bool SQLParser::parse(const std::string& sql, SQLParserResult* result) {
yyscan_t scanner;
YY_BUFFER_STATE state;
if (hsql_lex_init(&scanner)) {
// Couldn't initialize the lexer.
fprintf(stderr, "SQLParser: Error when initializing lexer!\n");
return false;
}
const char* text = sql.c_str();
state = hsql__scan_string(text, scanner);
// Parse the tokens.
// If parsing fails, the result will contain an error object.
int ret = hsql_parse(result, scanner);
bool success = (ret == 0);
result->setIsValid(success);
hsql__delete_buffer(state, scanner);
hsql_lex_destroy(scanner);
return true;
}
// static
bool SQLParser::parseSQLString(const char* sql, SQLParserResult* result) { return parse(sql, result); }
bool SQLParser::parseSQLString(const std::string& sql, SQLParserResult* result) { return parse(sql, result); }
// static
bool SQLParser::tokenize(const std::string& sql, std::vector<int16_t>* tokens) {
// Initialize the scanner.
yyscan_t scanner;
if (hsql_lex_init(&scanner)) {
fprintf(stderr, "SQLParser: Error when initializing lexer!\n");
return false;
}
YY_BUFFER_STATE state;
state = hsql__scan_string(sql.c_str(), scanner);
YYSTYPE yylval;
YYLTYPE yylloc;
// Step through the string until EOF is read.
// Note: hsql_lex returns int, but we know that its range is within 16 bit.
int16_t token = hsql_lex(&yylval, &yylloc, scanner);
while (token != 0) {
tokens->push_back(token);
token = hsql_lex(&yylval, &yylloc, scanner);
if (token == SQL_IDENTIFIER || token == SQL_STRING) {
free(yylval.sval);
}
}
hsql__delete_buffer(state, scanner);
hsql_lex_destroy(scanner);
return true;
}
} // namespace hsql

View File

@@ -0,0 +1,35 @@
#ifndef SQLPARSER_SQLPARSER_H
#define SQLPARSER_SQLPARSER_H
#include "SQLParserResult.h"
#include "sql/statements.h"
namespace hsql {
// Static methods used to parse SQL strings.
class SQLParser_API SQLParser {
public:
// Parses a given constant character SQL string into the result object.
// Returns true if the lexer and parser could run without internal errors.
// This does NOT mean that the SQL string was valid SQL. To check that
// you need to check result->isValid();
static bool parse(const std::string& sql, SQLParserResult* result);
// Run tokenization on the given string and store the tokens in the output vector.
static bool tokenize(const std::string& sql, std::vector<int16_t>* tokens);
// Deprecated.
// Old method to parse SQL strings. Replaced by parse().
static bool parseSQLString(const char* sql, SQLParserResult* result);
// Deprecated.
// Old method to parse SQL strings. Replaced by parse().
static bool parseSQLString(const std::string& sql, SQLParserResult* result);
private:
SQLParser();
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,133 @@
#include "SQLParserResult.h"
#include <algorithm>
#include <string.h>
namespace hsql {
SQLParserResult::SQLParserResult() :
statements_(new std::vector<SQLStatement*>),
isValid_(false),
errorMsg_(nullptr),
errorLine_(-1),
errorColumn_(-1),
parameters_(new std::vector<Expr*>)
{
}
SQLParserResult::SQLParserResult(SQLStatement* stmt) :
statements_(new std::vector<SQLStatement*>),
isValid_(false),
errorMsg_(nullptr),
errorLine_(-1),
errorColumn_(-1),
parameters_(new std::vector<Expr*>)
{
addStatement(stmt);
}
// Move constructor.
SQLParserResult::SQLParserResult(SQLParserResult&& moved) { *this = std::forward<SQLParserResult>(moved); }
SQLParserResult& SQLParserResult::operator=(SQLParserResult&& moved) {
isValid_ = moved.isValid_;
errorMsg_ = moved.errorMsg_;
statements_ = moved.statements_;
parameters_ = moved.parameters_;
moved.reset(true);
return *this;
}
SQLParserResult::~SQLParserResult() { reset(); }
void SQLParserResult::addStatement(SQLStatement* stmt) {
if (!statements_) statements_ = new std::vector<SQLStatement*>;
statements_->push_back(stmt);
}
const SQLStatement* SQLParserResult::getStatement(size_t index) const {
return statements_ ? (*statements_)[index] : nullptr;
}
SQLStatement* SQLParserResult::getMutableStatement(size_t index) {
return statements_ ? (*statements_)[index] : nullptr;
}
size_t SQLParserResult::size() const { return statements_ ? statements_->size() : 0u; }
bool SQLParserResult::isValid() const { return isValid_; }
const char* SQLParserResult::errorMsg() const { return errorMsg_; }
int SQLParserResult::errorLine() const { return errorLine_; }
int SQLParserResult::errorColumn() const { return errorColumn_; }
void SQLParserResult::setIsValid(bool isValid) { isValid_ = isValid; }
void SQLParserResult::setErrorDetails(char* errorMsg, int errorLine, int errorColumn) {
if (errorMsg_) free(errorMsg);
errorMsg_ = errorMsg;
errorLine_ = errorLine;
errorColumn_ = errorColumn;
}
const std::vector<SQLStatement*>& SQLParserResult::getStatements() const {
if (!statements_) statements_ = new std::vector<SQLStatement*>;
return *statements_;
}
std::vector<SQLStatement*> SQLParserResult::releaseStatements() {
std::vector<SQLStatement*> copy;
if (statements_)
{
copy = *statements_;
statements_->clear();
}
return copy;
}
void SQLParserResult::reset(bool mv) {
if (statements_)
{
if (!mv)
{
for (SQLStatement* statement : *statements_) {
delete statement;
}
delete statements_;
}
statements_ = nullptr;
}
if (parameters_)
{
if (!mv) delete parameters_;
parameters_ = nullptr;
}
isValid_ = false;
if (errorMsg_)
{
if (!mv) free(errorMsg_);
errorMsg_ = nullptr;
}
errorLine_ = -1;
errorColumn_ = -1;
}
// Does NOT take ownership.
void SQLParserResult::addParameter(Expr* parameter) {
if (!parameters_) parameters_ = new std::vector<Expr*>;
parameters_->push_back(parameter);
std::sort(parameters_->begin(), parameters_->end(), [](const Expr* a, const Expr* b) { return a->ival < b->ival; });
}
const std::vector<Expr*>& SQLParserResult::parameters() {
if (!parameters_) parameters_ = new std::vector<Expr*>;
return *parameters_;
}
} // namespace hsql

View File

@@ -0,0 +1,95 @@
#ifndef SQLPARSER_SQLPARSER_RESULT_H
#define SQLPARSER_SQLPARSER_RESULT_H
#include "sqlparser_win.h"
#include "sql/SQLStatement.h"
namespace hsql {
// Represents the result of the SQLParser.
// If parsing was successful it contains a list of SQLStatement.
class SQLParser_API SQLParserResult {
public:
// Initialize with empty statement list.
SQLParserResult();
// Initialize with a single statement.
// Takes ownership of the statement.
SQLParserResult(SQLStatement* stmt);
// Move constructor.
SQLParserResult(SQLParserResult&& moved);
SQLParserResult& operator=(SQLParserResult&& moved);
// Deletes all statements in the result.
virtual ~SQLParserResult();
// Set whether parsing was successful.
void setIsValid(bool isValid);
// Returns true if parsing was successful.
bool isValid() const;
// Returns the number of statements in the result.
size_t size() const;
// Set the details of the error, if available.
// Takes ownership of errorMsg.
void setErrorDetails(char* errorMsg, int errorLine, int errorColumn);
// Returns the error message, if an error occurred.
const char* errorMsg() const;
// Returns the line number of the occurrance of the error in the query.
int errorLine() const;
// Returns the column number of the occurrance of the error in the query.
int errorColumn() const;
// Adds a statement to the result list of statements.
// SQLParserResult takes ownership of the statement.
void addStatement(SQLStatement* stmt);
// Gets the SQL statement with the given index.
const SQLStatement* getStatement(size_t index) const;
// Gets the non const SQL statement with the given index.
SQLStatement* getMutableStatement(size_t index);
// Get the list of all statements.
const std::vector<SQLStatement*>& getStatements() const;
// Returns a copy of the list of all statements in this result.
// Removes them from this result.
std::vector<SQLStatement*> releaseStatements();
// Deletes all statements and other data within the result.
void reset(bool mv = false);
// Does NOT take ownership.
void addParameter(Expr* parameter);
const std::vector<Expr*>& parameters();
private:
// List of statements within the result.
mutable std::vector<SQLStatement*>* statements_;
// Flag indicating the parsing was successful.
bool isValid_;
// Error message, if an error occurred.
char* errorMsg_;
// Line number of the occurrance of the error in the query.
int errorLine_;
// Column number of the occurrance of the error in the query.
int errorColumn_;
// Does NOT have ownership.
std::vector<Expr*>* parameters_;
};
} // namespace hsql
#endif // SQLPARSER_SQLPARSER_RESULT_H

2
Data/SQLParser/src/parser/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.output
conflict_test.cpp

View File

@@ -0,0 +1,39 @@
# bison's version is too old on OSX, allow user to pass in custom path
BISON?=bison
FLEX?=flex
OS_TYPE=$(shell uname)
ifeq ($(OS_TYPE), Darwin)
BREW_PREFIX=$(shell brew --prefix)
BREW_INSTALLED=$(shell echo $(BREW_PREFIX) | wc -w | xargs)
ifeq ($(BREW_INSTALLED), 0)
$(error On macOS, Homebrew (see https://brew.sh) is required to install recent Bison and Flex versions)
endif
endif
BISON_VERSION=$(shell $(BISON) --version | head -n 1 | grep -o '[0-9]\.[0-9]\+')
BISON_VERSION_SUPPORTED=$(shell awk -v a=$(BISON_VERSION) -v b="3.0" 'BEGIN { print (a >= b) ? 1 : 0 }')
ifneq ($(BISON_VERSION_SUPPORTED), 1)
$(error Bison version $(BISON_VERSION) not supported. If you are using macOS, `bison` uses the system default instead of the brew version. Run BISON=$(BREW_PREFIX)/opt/bison/bin/bison make)
endif
FLEX_VERSION=$(shell $(FLEX) --version | head -n 1 | grep -o '[0-9]\.[0-9]\+')
FLEX_VERSION_SUPPORTED=$(shell awk -v a=$(FLEX_VERSION) -v b="2.6" 'BEGIN { print (a >= b) ? 1 : 0 }')
ifneq ($(FLEX_VERSION_SUPPORTED), 1)
$(error Flex version $(FLEX_VERSION) not supported. If you are using macOS, `flex` uses the system default instead of the brew version. Run FLEX=$(BREW_PREFIX)/opt/flex/bin/flex make)
endif
all: bison_parser.cpp flex_lexer.cpp
bison_parser.cpp: bison_parser.y
$(BISON) bison_parser.y --output=bison_parser.cpp --defines=bison_parser.h --verbose
flex_lexer.cpp: flex_lexer.l
! $(FLEX) flex_lexer.l 2>&1 | grep "warning"
clean:
rm -f bison_parser.cpp flex_lexer.cpp bison_parser.h flex_lexer.h *.output
# Tests if the parser builds correctly and doesn't contain conflicts.
test:
! $(BISON) bison_parser.y -v --output=conflict_test.cpp 2>&1 | grep "conflict" >&2

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,370 @@
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_HSQL_BISON_PARSER_H_INCLUDED
# define YY_HSQL_BISON_PARSER_H_INCLUDED
/* Debug traces. */
#ifndef HSQL_DEBUG
# if defined YYDEBUG
#if YYDEBUG
# define HSQL_DEBUG 1
# else
# define HSQL_DEBUG 0
# endif
# else /* ! defined YYDEBUG */
# define HSQL_DEBUG 0
# endif /* ! defined YYDEBUG */
#endif /* ! defined HSQL_DEBUG */
#if HSQL_DEBUG
extern int hsql_debug;
#endif
/* "%code requires" blocks. */
#line 38 "bison_parser.y"
// %code requires block
#include "../SQLParserResult.h"
#include "../sql/statements.h"
#include "parser_typedef.h"
// Auto update column and line number
#define YY_USER_ACTION \
yylloc->first_line = yylloc->last_line; \
yylloc->first_column = yylloc->last_column; \
for (int i = 0; yytext[i] != '\0'; i++) { \
yylloc->total_column++; \
yylloc->string_length++; \
if (yytext[i] == '\n') { \
yylloc->last_line++; \
yylloc->last_column = 0; \
} else { \
yylloc->last_column++; \
} \
}
#line 80 "bison_parser.h"
/* Token kinds. */
#ifndef HSQL_TOKENTYPE
# define HSQL_TOKENTYPE
enum hsql_tokentype
{
SQL_HSQL_EMPTY = -2,
SQL_YYEOF = 0, /* "end of file" */
SQL_HSQL_error = 256, /* error */
SQL_HSQL_UNDEF = 257, /* "invalid token" */
SQL_IDENTIFIER = 258, /* IDENTIFIER */
SQL_STRING = 259, /* STRING */
SQL_FLOATVAL = 260, /* FLOATVAL */
SQL_INTVAL = 261, /* INTVAL */
SQL_DEALLOCATE = 262, /* DEALLOCATE */
SQL_PARAMETERS = 263, /* PARAMETERS */
SQL_INTERSECT = 264, /* INTERSECT */
SQL_TEMPORARY = 265, /* TEMPORARY */
SQL_TIMESTAMP = 266, /* TIMESTAMP */
SQL_DISTINCT = 267, /* DISTINCT */
SQL_NVARCHAR = 268, /* NVARCHAR */
SQL_RESTRICT = 269, /* RESTRICT */
SQL_TRUNCATE = 270, /* TRUNCATE */
SQL_ANALYZE = 271, /* ANALYZE */
SQL_BETWEEN = 272, /* BETWEEN */
SQL_CASCADE = 273, /* CASCADE */
SQL_COLUMNS = 274, /* COLUMNS */
SQL_CONTROL = 275, /* CONTROL */
SQL_DEFAULT = 276, /* DEFAULT */
SQL_EXECUTE = 277, /* EXECUTE */
SQL_EXPLAIN = 278, /* EXPLAIN */
SQL_INTEGER = 279, /* INTEGER */
SQL_NATURAL = 280, /* NATURAL */
SQL_PREPARE = 281, /* PREPARE */
SQL_PRIMARY = 282, /* PRIMARY */
SQL_SCHEMAS = 283, /* SCHEMAS */
SQL_CHARACTER_VARYING = 284, /* CHARACTER_VARYING */
SQL_REAL = 285, /* REAL */
SQL_DECIMAL = 286, /* DECIMAL */
SQL_SMALLINT = 287, /* SMALLINT */
SQL_BIGINT = 288, /* BIGINT */
SQL_SPATIAL = 289, /* SPATIAL */
SQL_VARCHAR = 290, /* VARCHAR */
SQL_VIRTUAL = 291, /* VIRTUAL */
SQL_DESCRIBE = 292, /* DESCRIBE */
SQL_BEFORE = 293, /* BEFORE */
SQL_COLUMN = 294, /* COLUMN */
SQL_CREATE = 295, /* CREATE */
SQL_DELETE = 296, /* DELETE */
SQL_DIRECT = 297, /* DIRECT */
SQL_DOUBLE = 298, /* DOUBLE */
SQL_ESCAPE = 299, /* ESCAPE */
SQL_EXCEPT = 300, /* EXCEPT */
SQL_EXISTS = 301, /* EXISTS */
SQL_EXTRACT = 302, /* EXTRACT */
SQL_CAST = 303, /* CAST */
SQL_FORMAT = 304, /* FORMAT */
SQL_GLOBAL = 305, /* GLOBAL */
SQL_HAVING = 306, /* HAVING */
SQL_IMPORT = 307, /* IMPORT */
SQL_INSERT = 308, /* INSERT */
SQL_ISNULL = 309, /* ISNULL */
SQL_OFFSET = 310, /* OFFSET */
SQL_RENAME = 311, /* RENAME */
SQL_SCHEMA = 312, /* SCHEMA */
SQL_SELECT = 313, /* SELECT */
SQL_SORTED = 314, /* SORTED */
SQL_TABLES = 315, /* TABLES */
SQL_UNIQUE = 316, /* UNIQUE */
SQL_UNLOAD = 317, /* UNLOAD */
SQL_UPDATE = 318, /* UPDATE */
SQL_VALUES = 319, /* VALUES */
SQL_AFTER = 320, /* AFTER */
SQL_ALTER = 321, /* ALTER */
SQL_CROSS = 322, /* CROSS */
SQL_DELTA = 323, /* DELTA */
SQL_FLOAT = 324, /* FLOAT */
SQL_GROUP = 325, /* GROUP */
SQL_INDEX = 326, /* INDEX */
SQL_INNER = 327, /* INNER */
SQL_LIMIT = 328, /* LIMIT */
SQL_LOCAL = 329, /* LOCAL */
SQL_MERGE = 330, /* MERGE */
SQL_MINUS = 331, /* MINUS */
SQL_ORDER = 332, /* ORDER */
SQL_OVER = 333, /* OVER */
SQL_OUTER = 334, /* OUTER */
SQL_RIGHT = 335, /* RIGHT */
SQL_TABLE = 336, /* TABLE */
SQL_UNION = 337, /* UNION */
SQL_USING = 338, /* USING */
SQL_WHERE = 339, /* WHERE */
SQL_CALL = 340, /* CALL */
SQL_CASE = 341, /* CASE */
SQL_CHAR = 342, /* CHAR */
SQL_COPY = 343, /* COPY */
SQL_DATE = 344, /* DATE */
SQL_DATETIME = 345, /* DATETIME */
SQL_DESC = 346, /* DESC */
SQL_DROP = 347, /* DROP */
SQL_ELSE = 348, /* ELSE */
SQL_FILE = 349, /* FILE */
SQL_FROM = 350, /* FROM */
SQL_FULL = 351, /* FULL */
SQL_HASH = 352, /* HASH */
SQL_HINT = 353, /* HINT */
SQL_INTO = 354, /* INTO */
SQL_JOIN = 355, /* JOIN */
SQL_LEFT = 356, /* LEFT */
SQL_LIKE = 357, /* LIKE */
SQL_LOAD = 358, /* LOAD */
SQL_LONG = 359, /* LONG */
SQL_NULL = 360, /* NULL */
SQL_PARTITION = 361, /* PARTITION */
SQL_PLAN = 362, /* PLAN */
SQL_SHOW = 363, /* SHOW */
SQL_TEXT = 364, /* TEXT */
SQL_THEN = 365, /* THEN */
SQL_TIME = 366, /* TIME */
SQL_VIEW = 367, /* VIEW */
SQL_WHEN = 368, /* WHEN */
SQL_WITH = 369, /* WITH */
SQL_ADD = 370, /* ADD */
SQL_ALL = 371, /* ALL */
SQL_AND = 372, /* AND */
SQL_ASC = 373, /* ASC */
SQL_END = 374, /* END */
SQL_FOR = 375, /* FOR */
SQL_INT = 376, /* INT */
SQL_KEY = 377, /* KEY */
SQL_NOT = 378, /* NOT */
SQL_OFF = 379, /* OFF */
SQL_SET = 380, /* SET */
SQL_TOP = 381, /* TOP */
SQL_AS = 382, /* AS */
SQL_BY = 383, /* BY */
SQL_IF = 384, /* IF */
SQL_IN = 385, /* IN */
SQL_IS = 386, /* IS */
SQL_OF = 387, /* OF */
SQL_ON = 388, /* ON */
SQL_OR = 389, /* OR */
SQL_TO = 390, /* TO */
SQL_NO = 391, /* NO */
SQL_ARRAY = 392, /* ARRAY */
SQL_CONCAT = 393, /* CONCAT */
SQL_ILIKE = 394, /* ILIKE */
SQL_SECOND = 395, /* SECOND */
SQL_MINUTE = 396, /* MINUTE */
SQL_HOUR = 397, /* HOUR */
SQL_DAY = 398, /* DAY */
SQL_MONTH = 399, /* MONTH */
SQL_YEAR = 400, /* YEAR */
SQL_SECONDS = 401, /* SECONDS */
SQL_MINUTES = 402, /* MINUTES */
SQL_HOURS = 403, /* HOURS */
SQL_DAYS = 404, /* DAYS */
SQL_MONTHS = 405, /* MONTHS */
SQL_YEARS = 406, /* YEARS */
SQL_INTERVAL = 407, /* INTERVAL */
SQL_TRUE = 408, /* TRUE */
SQL_FALSE = 409, /* FALSE */
SQL_BOOLEAN = 410, /* BOOLEAN */
SQL_TRANSACTION = 411, /* TRANSACTION */
SQL_BEGIN = 412, /* BEGIN */
SQL_COMMIT = 413, /* COMMIT */
SQL_ROLLBACK = 414, /* ROLLBACK */
SQL_NOWAIT = 415, /* NOWAIT */
SQL_SKIP = 416, /* SKIP */
SQL_LOCKED = 417, /* LOCKED */
SQL_SHARE = 418, /* SHARE */
SQL_RANGE = 419, /* RANGE */
SQL_ROWS = 420, /* ROWS */
SQL_GROUPS = 421, /* GROUPS */
SQL_UNBOUNDED = 422, /* UNBOUNDED */
SQL_FOLLOWING = 423, /* FOLLOWING */
SQL_PRECEDING = 424, /* PRECEDING */
SQL_CURRENT_ROW = 425, /* CURRENT_ROW */
SQL_EQUALS = 426, /* EQUALS */
SQL_NOTEQUALS = 427, /* NOTEQUALS */
SQL_LESS = 428, /* LESS */
SQL_GREATER = 429, /* GREATER */
SQL_LESSEQ = 430, /* LESSEQ */
SQL_GREATEREQ = 431, /* GREATEREQ */
SQL_NOTNULL = 432, /* NOTNULL */
SQL_UMINUS = 433 /* UMINUS */
};
typedef enum hsql_tokentype hsql_token_kind_t;
#endif
/* Value type. */
#if ! defined HSQL_STYPE && ! defined HSQL_STYPE_IS_DECLARED
union HSQL_STYPE
{
#line 96 "bison_parser.y"
// clang-format on
bool bval;
char* sval;
double fval;
int64_t ival;
uintmax_t uval;
// statements
hsql::AlterStatement* alter_stmt;
hsql::CreateStatement* create_stmt;
hsql::DeleteStatement* delete_stmt;
hsql::DropStatement* drop_stmt;
hsql::ExecuteStatement* exec_stmt;
hsql::ExportStatement* export_stmt;
hsql::ImportStatement* import_stmt;
hsql::InsertStatement* insert_stmt;
hsql::PrepareStatement* prep_stmt;
hsql::SelectStatement* select_stmt;
hsql::ShowStatement* show_stmt;
hsql::SQLStatement* statement;
hsql::TransactionStatement* transaction_stmt;
hsql::UpdateStatement* update_stmt;
hsql::Alias* alias_t;
hsql::AlterAction* alter_action_t;
hsql::ColumnDefinition* column_t;
hsql::ColumnType column_type_t;
hsql::ConstraintType column_constraint_t;
hsql::DatetimeField datetime_field;
hsql::DropColumnAction* drop_action_t;
hsql::Expr* expr;
hsql::FrameBound* frame_bound;
hsql::FrameDescription* frame_description;
hsql::FrameType frame_type;
hsql::GroupByDescription* group_t;
hsql::ImportType import_type_t;
hsql::JoinType join_type;
hsql::LimitDescription* limit;
hsql::LockingClause* locking_t;
hsql::OrderDescription* order;
hsql::OrderType order_type;
hsql::SetOperation* set_operator_t;
hsql::TableConstraint* table_constraint_t;
hsql::TableElement* table_element_t;
hsql::TableName table_name;
hsql::TableRef* table;
hsql::UpdateClause* update_t;
hsql::WindowDescription* window_description;
hsql::WithDescription* with_description_t;
std::vector<char*>* str_vec;
std::unordered_set<hsql::ConstraintType>* column_constraint_set;
std::vector<hsql::Expr*>* expr_vec;
std::vector<hsql::OrderDescription*>* order_vec;
std::vector<hsql::SQLStatement*>* stmt_vec;
std::vector<hsql::TableElement*>* table_element_vec;
std::vector<hsql::TableRef*>* table_vec;
std::vector<hsql::UpdateClause*>* update_vec;
std::vector<hsql::WithDescription*>* with_description_vec;
std::vector<hsql::LockingClause*>* locking_clause_vec;
std::pair<int64_t, int64_t>* ival_pair;
hsql::RowLockMode lock_mode_t;
hsql::RowLockWaitPolicy lock_wait_policy_t;
#line 343 "bison_parser.h"
};
typedef union HSQL_STYPE HSQL_STYPE;
# define HSQL_STYPE_IS_TRIVIAL 1
# define HSQL_STYPE_IS_DECLARED 1
#endif
/* Location type. */
#if ! defined HSQL_LTYPE && ! defined HSQL_LTYPE_IS_DECLARED
typedef struct HSQL_LTYPE HSQL_LTYPE;
struct HSQL_LTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
};
# define HSQL_LTYPE_IS_DECLARED 1
# define HSQL_LTYPE_IS_TRIVIAL 1
#endif
int hsql_parse (hsql::SQLParserResult* result, yyscan_t scanner);
#endif /* !YY_HSQL_BISON_PARSER_H_INCLUDED */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,742 @@
#ifndef hsql_HEADER_H
#define hsql_HEADER_H 1
#define hsql_IN_HEADER 1
#line 5 "flex_lexer.h"
#line 7 "flex_lexer.h"
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
#define YY_FLEX_SUBMINOR_VERSION 4
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
#ifdef yy_create_buffer
#define hsql__create_buffer_ALREADY_DEFINED
#else
#define yy_create_buffer hsql__create_buffer
#endif
#ifdef yy_delete_buffer
#define hsql__delete_buffer_ALREADY_DEFINED
#else
#define yy_delete_buffer hsql__delete_buffer
#endif
#ifdef yy_scan_buffer
#define hsql__scan_buffer_ALREADY_DEFINED
#else
#define yy_scan_buffer hsql__scan_buffer
#endif
#ifdef yy_scan_string
#define hsql__scan_string_ALREADY_DEFINED
#else
#define yy_scan_string hsql__scan_string
#endif
#ifdef yy_scan_bytes
#define hsql__scan_bytes_ALREADY_DEFINED
#else
#define yy_scan_bytes hsql__scan_bytes
#endif
#ifdef yy_init_buffer
#define hsql__init_buffer_ALREADY_DEFINED
#else
#define yy_init_buffer hsql__init_buffer
#endif
#ifdef yy_flush_buffer
#define hsql__flush_buffer_ALREADY_DEFINED
#else
#define yy_flush_buffer hsql__flush_buffer
#endif
#ifdef yy_load_buffer_state
#define hsql__load_buffer_state_ALREADY_DEFINED
#else
#define yy_load_buffer_state hsql__load_buffer_state
#endif
#ifdef yy_switch_to_buffer
#define hsql__switch_to_buffer_ALREADY_DEFINED
#else
#define yy_switch_to_buffer hsql__switch_to_buffer
#endif
#ifdef yypush_buffer_state
#define hsql_push_buffer_state_ALREADY_DEFINED
#else
#define yypush_buffer_state hsql_push_buffer_state
#endif
#ifdef yypop_buffer_state
#define hsql_pop_buffer_state_ALREADY_DEFINED
#else
#define yypop_buffer_state hsql_pop_buffer_state
#endif
#ifdef yyensure_buffer_stack
#define hsql_ensure_buffer_stack_ALREADY_DEFINED
#else
#define yyensure_buffer_stack hsql_ensure_buffer_stack
#endif
#ifdef yylex
#define hsql_lex_ALREADY_DEFINED
#else
#define yylex hsql_lex
#endif
#ifdef yyrestart
#define hsql_restart_ALREADY_DEFINED
#else
#define yyrestart hsql_restart
#endif
#ifdef yylex_init
#define hsql_lex_init_ALREADY_DEFINED
#else
#define yylex_init hsql_lex_init
#endif
#ifdef yylex_init_extra
#define hsql_lex_init_extra_ALREADY_DEFINED
#else
#define yylex_init_extra hsql_lex_init_extra
#endif
#ifdef yylex_destroy
#define hsql_lex_destroy_ALREADY_DEFINED
#else
#define yylex_destroy hsql_lex_destroy
#endif
#ifdef yyget_debug
#define hsql_get_debug_ALREADY_DEFINED
#else
#define yyget_debug hsql_get_debug
#endif
#ifdef yyset_debug
#define hsql_set_debug_ALREADY_DEFINED
#else
#define yyset_debug hsql_set_debug
#endif
#ifdef yyget_extra
#define hsql_get_extra_ALREADY_DEFINED
#else
#define yyget_extra hsql_get_extra
#endif
#ifdef yyset_extra
#define hsql_set_extra_ALREADY_DEFINED
#else
#define yyset_extra hsql_set_extra
#endif
#ifdef yyget_in
#define hsql_get_in_ALREADY_DEFINED
#else
#define yyget_in hsql_get_in
#endif
#ifdef yyset_in
#define hsql_set_in_ALREADY_DEFINED
#else
#define yyset_in hsql_set_in
#endif
#ifdef yyget_out
#define hsql_get_out_ALREADY_DEFINED
#else
#define yyget_out hsql_get_out
#endif
#ifdef yyset_out
#define hsql_set_out_ALREADY_DEFINED
#else
#define yyset_out hsql_set_out
#endif
#ifdef yyget_leng
#define hsql_get_leng_ALREADY_DEFINED
#else
#define yyget_leng hsql_get_leng
#endif
#ifdef yyget_text
#define hsql_get_text_ALREADY_DEFINED
#else
#define yyget_text hsql_get_text
#endif
#ifdef yyget_lineno
#define hsql_get_lineno_ALREADY_DEFINED
#else
#define yyget_lineno hsql_get_lineno
#endif
#ifdef yyset_lineno
#define hsql_set_lineno_ALREADY_DEFINED
#else
#define yyset_lineno hsql_set_lineno
#endif
#ifdef yyget_column
#define hsql_get_column_ALREADY_DEFINED
#else
#define yyget_column hsql_get_column
#endif
#ifdef yyset_column
#define hsql_set_column_ALREADY_DEFINED
#else
#define yyset_column hsql_set_column
#endif
#ifdef yywrap
#define hsql_wrap_ALREADY_DEFINED
#else
#define yywrap hsql_wrap
#endif
#ifdef yyget_lval
#define hsql_get_lval_ALREADY_DEFINED
#else
#define yyget_lval hsql_get_lval
#endif
#ifdef yyset_lval
#define hsql_set_lval_ALREADY_DEFINED
#else
#define yyset_lval hsql_set_lval
#endif
#ifdef yyget_lloc
#define hsql_get_lloc_ALREADY_DEFINED
#else
#define yyget_lloc hsql_get_lloc
#endif
#ifdef yyset_lloc
#define hsql_set_lloc_ALREADY_DEFINED
#else
#define yyset_lloc hsql_set_lloc
#endif
#ifdef yyalloc
#define hsql_alloc_ALREADY_DEFINED
#else
#define yyalloc hsql_alloc
#endif
#ifdef yyrealloc
#define hsql_realloc_ALREADY_DEFINED
#else
#define yyrealloc hsql_realloc
#endif
#ifdef yyfree
#define hsql_free_ALREADY_DEFINED
#else
#define yyfree hsql_free
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
/* flex integer type definitions */
#ifndef FLEXINT_H
#define FLEXINT_H
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;
typedef int16_t flex_int16_t;
typedef uint16_t flex_uint16_t;
typedef int32_t flex_int32_t;
typedef uint32_t flex_uint32_t;
#else
typedef signed char flex_int8_t;
typedef short int flex_int16_t;
typedef int flex_int32_t;
typedef unsigned char flex_uint8_t;
typedef unsigned short int flex_uint16_t;
typedef unsigned int flex_uint32_t;
/* Limits of integral types. */
#ifndef INT8_MIN
#define INT8_MIN (-128)
#endif
#ifndef INT16_MIN
#define INT16_MIN (-32767-1)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-2147483647-1)
#endif
#ifndef INT8_MAX
#define INT8_MAX (127)
#endif
#ifndef INT16_MAX
#define INT16_MAX (32767)
#endif
#ifndef INT32_MAX
#define INT32_MAX (2147483647)
#endif
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#ifndef UINT16_MAX
#define UINT16_MAX (65535U)
#endif
#ifndef UINT32_MAX
#define UINT32_MAX (4294967295U)
#endif
#ifndef SIZE_MAX
#define SIZE_MAX (~(size_t)0)
#endif
#endif /* ! C99 */
#endif /* ! FLEXINT_H */
/* begin standard C++ headers. */
/* TODO: this is always defined, so inline it */
#define yyconst const
#if defined(__GNUC__) && __GNUC__ >= 3
#define yynoreturn __attribute__((__noreturn__))
#else
#define yynoreturn
#endif
/* An opaque pointer. */
#ifndef YY_TYPEDEF_YY_SCANNER_T
#define YY_TYPEDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
/* For convenience, these vars (plus the bison vars far below)
are macros in the reentrant scanner. */
#define yyin yyg->yyin_r
#define yyout yyg->yyout_r
#define yyextra yyg->yyextra_r
#define yyleng yyg->yyleng_r
#define yytext yyg->yytext_r
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
#define yy_flex_debug yyg->yy_flex_debug_r
/* Size of default input buffer. */
#ifndef YY_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k.
* Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
* Ditto for the __ia64__ case accordingly.
*/
#define YY_BUF_SIZE 32768
#else
#define YY_BUF_SIZE 16384
#endif /* __ia64__ */
#endif
#ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
#endif
#ifndef YY_TYPEDEF_YY_SIZE_T
#define YY_TYPEDEF_YY_SIZE_T
typedef size_t yy_size_t;
#endif
#ifndef YY_STRUCT_YY_BUFFER_STATE
#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
char *yy_ch_buf; /* input buffer */
char *yy_buf_pos; /* current position in input buffer */
/* Size of input buffer in bytes, not including room for EOB
* characters.
*/
int yy_buf_size;
/* Number of characters read into yy_ch_buf, not including EOB
* characters.
*/
int yy_n_chars;
/* Whether we "own" the buffer - i.e., we know we created it,
* and can realloc() it to grow it, and should free() it to
* delete it.
*/
int yy_is_our_buffer;
/* Whether this is an "interactive" input source; if so, and
* if we're using stdio for input, then we want to use getc()
* instead of fread(), to make sure we stop fetching input after
* each newline.
*/
int yy_is_interactive;
/* Whether we're considered to be at the beginning of a line.
* If so, '^' rules will be active on the next match, otherwise
* not.
*/
int yy_at_bol;
int yy_bs_lineno; /**< The line count. */
int yy_bs_column; /**< The column count. */
/* Whether to try to fill the input buffer when we reach the
* end of it.
*/
int yy_fill_buffer;
int yy_buffer_status;
};
#endif /* !YY_STRUCT_YY_BUFFER_STATE */
void yyrestart ( FILE *input_file , yyscan_t yyscanner );
void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
void yypop_buffer_state ( yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
void *yyalloc ( yy_size_t , yyscan_t yyscanner );
void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
void yyfree ( void * , yyscan_t yyscanner );
/* Begin user sect3 */
#define hsql_wrap(yyscanner) (/*CONSTCOND*/1)
#define YY_SKIP_YYWRAP
#define yytext_ptr yytext_r
#ifdef YY_HEADER_EXPORT_START_CONDITIONS
#define INITIAL 0
#define singlequotedstring 1
#define COMMENT 2
#endif
#ifndef YY_NO_UNISTD_H
/* Special case for "unistd.h", since it is non-ANSI. We include it way
* down here because we want the user's section 1 to have been scanned first.
* The user has a chance to override it with an option.
*/
#if defined(_WIN32) || defined(_WIN64)
#include <io.h>
#else
#include <unistd.h>
#endif
#endif
#ifndef YY_EXTRA_TYPE
#define YY_EXTRA_TYPE void *
#endif
int yylex_init (yyscan_t* scanner);
int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
/* Accessor methods to globals.
These are made visible to non-reentrant scanners for convenience. */
int yylex_destroy ( yyscan_t yyscanner );
int yyget_debug ( yyscan_t yyscanner );
void yyset_debug ( int debug_flag , yyscan_t yyscanner );
YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
FILE *yyget_in ( yyscan_t yyscanner );
void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
FILE *yyget_out ( yyscan_t yyscanner );
void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
int yyget_leng ( yyscan_t yyscanner );
char *yyget_text ( yyscan_t yyscanner );
int yyget_lineno ( yyscan_t yyscanner );
void yyset_lineno ( int _line_number , yyscan_t yyscanner );
int yyget_column ( yyscan_t yyscanner );
void yyset_column ( int _column_no , yyscan_t yyscanner );
YYSTYPE * yyget_lval ( yyscan_t yyscanner );
void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
YYLTYPE *yyget_lloc ( yyscan_t yyscanner );
void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner );
/* Macros after this point can all be overridden by user definitions in
* section 1.
*/
#ifndef YY_SKIP_YYWRAP
#ifdef __cplusplus
extern "C" int yywrap ( yyscan_t yyscanner );
#else
extern int yywrap ( yyscan_t yyscanner );
#endif
#endif
#ifndef yytext_ptr
static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
#endif
#ifdef YY_NEED_STRLEN
static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
#endif
#ifndef YY_NO_INPUT
#endif
/* Amount of stuff to slurp up with each read. */
#ifndef YY_READ_BUF_SIZE
#ifdef __ia64__
/* On IA-64, the buffer size is 16k, not 8k */
#define YY_READ_BUF_SIZE 16384
#else
#define YY_READ_BUF_SIZE 8192
#endif /* __ia64__ */
#endif
/* Number of entries by which start-condition stack grows. */
#ifndef YY_START_STACK_INCR
#define YY_START_STACK_INCR 25
#endif
/* Default declaration of generated scanner - a define so the user can
* easily add parameters.
*/
#ifndef YY_DECL
#define YY_DECL_IS_OURS 1
extern int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner);
#define YY_DECL int yylex \
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
#endif /* !YY_DECL */
/* yy_get_previous_state - get the state just before the EOB char was reached */
#undef YY_NEW_FILE
#undef YY_FLUSH_BUFFER
#undef yy_set_bol
#undef yy_new_buffer
#undef yy_set_interactive
#undef YY_DO_BEFORE_ACTION
#ifdef YY_DECL_IS_OURS
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
#ifndef hsql__create_buffer_ALREADY_DEFINED
#undef yy_create_buffer
#endif
#ifndef hsql__delete_buffer_ALREADY_DEFINED
#undef yy_delete_buffer
#endif
#ifndef hsql__scan_buffer_ALREADY_DEFINED
#undef yy_scan_buffer
#endif
#ifndef hsql__scan_string_ALREADY_DEFINED
#undef yy_scan_string
#endif
#ifndef hsql__scan_bytes_ALREADY_DEFINED
#undef yy_scan_bytes
#endif
#ifndef hsql__init_buffer_ALREADY_DEFINED
#undef yy_init_buffer
#endif
#ifndef hsql__flush_buffer_ALREADY_DEFINED
#undef yy_flush_buffer
#endif
#ifndef hsql__load_buffer_state_ALREADY_DEFINED
#undef yy_load_buffer_state
#endif
#ifndef hsql__switch_to_buffer_ALREADY_DEFINED
#undef yy_switch_to_buffer
#endif
#ifndef hsql_push_buffer_state_ALREADY_DEFINED
#undef yypush_buffer_state
#endif
#ifndef hsql_pop_buffer_state_ALREADY_DEFINED
#undef yypop_buffer_state
#endif
#ifndef hsql_ensure_buffer_stack_ALREADY_DEFINED
#undef yyensure_buffer_stack
#endif
#ifndef hsql_lex_ALREADY_DEFINED
#undef yylex
#endif
#ifndef hsql_restart_ALREADY_DEFINED
#undef yyrestart
#endif
#ifndef hsql_lex_init_ALREADY_DEFINED
#undef yylex_init
#endif
#ifndef hsql_lex_init_extra_ALREADY_DEFINED
#undef yylex_init_extra
#endif
#ifndef hsql_lex_destroy_ALREADY_DEFINED
#undef yylex_destroy
#endif
#ifndef hsql_get_debug_ALREADY_DEFINED
#undef yyget_debug
#endif
#ifndef hsql_set_debug_ALREADY_DEFINED
#undef yyset_debug
#endif
#ifndef hsql_get_extra_ALREADY_DEFINED
#undef yyget_extra
#endif
#ifndef hsql_set_extra_ALREADY_DEFINED
#undef yyset_extra
#endif
#ifndef hsql_get_in_ALREADY_DEFINED
#undef yyget_in
#endif
#ifndef hsql_set_in_ALREADY_DEFINED
#undef yyset_in
#endif
#ifndef hsql_get_out_ALREADY_DEFINED
#undef yyget_out
#endif
#ifndef hsql_set_out_ALREADY_DEFINED
#undef yyset_out
#endif
#ifndef hsql_get_leng_ALREADY_DEFINED
#undef yyget_leng
#endif
#ifndef hsql_get_text_ALREADY_DEFINED
#undef yyget_text
#endif
#ifndef hsql_get_lineno_ALREADY_DEFINED
#undef yyget_lineno
#endif
#ifndef hsql_set_lineno_ALREADY_DEFINED
#undef yyset_lineno
#endif
#ifndef hsql_get_column_ALREADY_DEFINED
#undef yyget_column
#endif
#ifndef hsql_set_column_ALREADY_DEFINED
#undef yyset_column
#endif
#ifndef hsql_wrap_ALREADY_DEFINED
#undef yywrap
#endif
#ifndef hsql_get_lval_ALREADY_DEFINED
#undef yyget_lval
#endif
#ifndef hsql_set_lval_ALREADY_DEFINED
#undef yyset_lval
#endif
#ifndef hsql_get_lloc_ALREADY_DEFINED
#undef yyget_lloc
#endif
#ifndef hsql_set_lloc_ALREADY_DEFINED
#undef yyset_lloc
#endif
#ifndef hsql_alloc_ALREADY_DEFINED
#undef yyalloc
#endif
#ifndef hsql_realloc_ALREADY_DEFINED
#undef yyrealloc
#endif
#ifndef hsql_free_ALREADY_DEFINED
#undef yyfree
#endif
#ifndef hsql_text_ALREADY_DEFINED
#undef yytext
#endif
#ifndef hsql_leng_ALREADY_DEFINED
#undef yyleng
#endif
#ifndef hsql_in_ALREADY_DEFINED
#undef yyin
#endif
#ifndef hsql_out_ALREADY_DEFINED
#undef yyout
#endif
#ifndef hsql__flex_debug_ALREADY_DEFINED
#undef yy_flex_debug
#endif
#ifndef hsql_lineno_ALREADY_DEFINED
#undef yylineno
#endif
#ifndef hsql_tables_fload_ALREADY_DEFINED
#undef yytables_fload
#endif
#ifndef hsql_tables_destroy_ALREADY_DEFINED
#undef yytables_destroy
#endif
#ifndef hsql_TABLES_NAME_ALREADY_DEFINED
#undef yyTABLES_NAME
#endif
#line 285 "flex_lexer.l"
#line 736 "flex_lexer.h"
#undef hsql_IN_HEADER
#endif /* hsql_HEADER_H */

View File

@@ -0,0 +1,292 @@
/**
* lexer
*
*
*/
/***************************
** Section 1: Definitions
***************************/
%{
#include "../sql/Expr.h"
#include "bison_parser.h"
#include <climits>
#include <stdio.h>
#include <sstream>
#define TOKEN(name) { return SQL_##name; }
static thread_local std::stringstream strbuf;
%}
%x singlequotedstring
/***************************
** Section 2: Rules
***************************/
/* Define the output files */
%option header-file="flex_lexer.h"
%option outfile="flex_lexer.cpp"
/* Make reentrant */
%option reentrant
%option bison-bridge
/* performance tweeks */
%option never-interactive
%option batch
/* other flags */
%option noyywrap
%option nounput
%option warn
%option case-insensitive
%option prefix="hsql_"
%option bison-locations
/* %option nodefault */
%s COMMENT
/***************************
** Section 3: Rules
***************************/
%%
-- BEGIN(COMMENT);
<COMMENT>[^\n]* /* skipping comment content until a end of line is read */;
<COMMENT>\n BEGIN(INITIAL);
[ \t\n]+ /* skip whitespace */;
ADD TOKEN(ADD)
AFTER TOKEN(AFTER)
ALL TOKEN(ALL)
ALTER TOKEN(ALTER)
ANALYZE TOKEN(ANALYZE)
AND TOKEN(AND)
ARRAY TOKEN(ARRAY)
AS TOKEN(AS)
ASC TOKEN(ASC)
BEFORE TOKEN(BEFORE)
BEGIN TOKEN(BEGIN)
BETWEEN TOKEN(BETWEEN)
BIGINT TOKEN(BIGINT)
BOOLEAN TOKEN(BOOLEAN)
BY TOKEN(BY)
CALL TOKEN(CALL)
CASCADE TOKEN(CASCADE)
CASE TOKEN(CASE)
CAST TOKEN(CAST)
CHAR TOKEN(CHAR)
COLUMN TOKEN(COLUMN)
COLUMNS TOKEN(COLUMNS)
COMMIT TOKEN(COMMIT)
CONTROL TOKEN(CONTROL)
COPY TOKEN(COPY)
CREATE TOKEN(CREATE)
CROSS TOKEN(CROSS)
DATE TOKEN(DATE)
DATETIME TOKEN(DATETIME)
DAY TOKEN(DAY)
DAYS TOKEN(DAYS)
DEALLOCATE TOKEN(DEALLOCATE)
DECIMAL TOKEN(DECIMAL)
DEFAULT TOKEN(DEFAULT)
DELETE TOKEN(DELETE)
DELTA TOKEN(DELTA)
DESC TOKEN(DESC)
DESCRIBE TOKEN(DESCRIBE)
DIRECT TOKEN(DIRECT)
DISTINCT TOKEN(DISTINCT)
DOUBLE TOKEN(DOUBLE)
DROP TOKEN(DROP)
ELSE TOKEN(ELSE)
END TOKEN(END)
ESCAPE TOKEN(ESCAPE)
EXCEPT TOKEN(EXCEPT)
EXECUTE TOKEN(EXECUTE)
EXISTS TOKEN(EXISTS)
EXPLAIN TOKEN(EXPLAIN)
EXTRACT TOKEN(EXTRACT)
FALSE TOKEN(FALSE)
FILE TOKEN(FILE)
FLOAT TOKEN(FLOAT)
FOLLOWING TOKEN(FOLLOWING)
FOR TOKEN(FOR)
FORMAT TOKEN(FORMAT)
FROM TOKEN(FROM)
FULL TOKEN(FULL)
GLOBAL TOKEN(GLOBAL)
GROUP TOKEN(GROUP)
GROUPS TOKEN(GROUPS)
HASH TOKEN(HASH)
HAVING TOKEN(HAVING)
HINT TOKEN(HINT)
HOUR TOKEN(HOUR)
HOURS TOKEN(HOURS)
IF TOKEN(IF)
ILIKE TOKEN(ILIKE)
IMPORT TOKEN(IMPORT)
IN TOKEN(IN)
INDEX TOKEN(INDEX)
INNER TOKEN(INNER)
INSERT TOKEN(INSERT)
INT TOKEN(INT)
INTEGER TOKEN(INTEGER)
INTERSECT TOKEN(INTERSECT)
INTERVAL TOKEN(INTERVAL)
INTO TOKEN(INTO)
IS TOKEN(IS)
ISNULL TOKEN(ISNULL)
JOIN TOKEN(JOIN)
KEY TOKEN(KEY)
LEFT TOKEN(LEFT)
LIKE TOKEN(LIKE)
LIMIT TOKEN(LIMIT)
LOAD TOKEN(LOAD)
LOCAL TOKEN(LOCAL)
LOCKED TOKEN(LOCKED)
LONG TOKEN(LONG)
MERGE TOKEN(MERGE)
MINUS TOKEN(MINUS)
MINUTE TOKEN(MINUTE)
MINUTES TOKEN(MINUTES)
MONTH TOKEN(MONTH)
MONTHS TOKEN(MONTHS)
NATURAL TOKEN(NATURAL)
NO TOKEN(NO)
NOT TOKEN(NOT)
NOWAIT TOKEN(NOWAIT)
NULL TOKEN(NULL)
NVARCHAR TOKEN(NVARCHAR)
OF TOKEN(OF)
OFF TOKEN(OFF)
OFFSET TOKEN(OFFSET)
ON TOKEN(ON)
OR TOKEN(OR)
ORDER TOKEN(ORDER)
OUTER TOKEN(OUTER)
OVER TOKEN(OVER)
PARAMETERS TOKEN(PARAMETERS)
PARTITION TOKEN(PARTITION)
PLAN TOKEN(PLAN)
PRECEDING TOKEN(PRECEDING)
PREPARE TOKEN(PREPARE)
PRIMARY TOKEN(PRIMARY)
RANGE TOKEN(RANGE)
REAL TOKEN(REAL)
RENAME TOKEN(RENAME)
RESTRICT TOKEN(RESTRICT)
RIGHT TOKEN(RIGHT)
ROLLBACK TOKEN(ROLLBACK)
ROWS TOKEN(ROWS)
SCHEMA TOKEN(SCHEMA)
SCHEMAS TOKEN(SCHEMAS)
SECOND TOKEN(SECOND)
SECONDS TOKEN(SECONDS)
SELECT TOKEN(SELECT)
SET TOKEN(SET)
SHARE TOKEN(SHARE)
SHOW TOKEN(SHOW)
SKIP TOKEN(SKIP)
SMALLINT TOKEN(SMALLINT)
SORTED TOKEN(SORTED)
SPATIAL TOKEN(SPATIAL)
TABLE TOKEN(TABLE)
TABLES TOKEN(TABLES)
TEMPORARY TOKEN(TEMPORARY)
TEXT TOKEN(TEXT)
THEN TOKEN(THEN)
TIME TOKEN(TIME)
TIMESTAMP TOKEN(TIMESTAMP)
TO TOKEN(TO)
TOP TOKEN(TOP)
TRANSACTION TOKEN(TRANSACTION)
TRUE TOKEN(TRUE)
TRUNCATE TOKEN(TRUNCATE)
UNBOUNDED TOKEN(UNBOUNDED)
UNION TOKEN(UNION)
UNIQUE TOKEN(UNIQUE)
UNLOAD TOKEN(UNLOAD)
UPDATE TOKEN(UPDATE)
USING TOKEN(USING)
VALUES TOKEN(VALUES)
VARCHAR TOKEN(VARCHAR)
VIEW TOKEN(VIEW)
VIRTUAL TOKEN(VIRTUAL)
WHEN TOKEN(WHEN)
WHERE TOKEN(WHERE)
WITH TOKEN(WITH)
YEAR TOKEN(YEAR)
YEARS TOKEN(YEARS)
CURRENT[ \t\n]+ROW TOKEN(CURRENT_ROW)
CHARACTER[ \t\n]+VARYING TOKEN(CHARACTER_VARYING)
/* Allow =/== see https://sqlite.org/lang_expr.html#collateop */
"==" TOKEN(EQUALS)
"!=" TOKEN(NOTEQUALS)
"<>" TOKEN(NOTEQUALS)
"<=" TOKEN(LESSEQ)
">=" TOKEN(GREATEREQ)
"||" TOKEN(CONCAT)
[-+*/(){},.;<>=^%:?[\]|] { return yytext[0]; }
[0-9]+"."[0-9]* |
"."[0-9]* {
yylval->fval = atof(yytext);
return SQL_FLOATVAL;
}
/*
* Regularly, negative literals are treated as <unary minus> <positive literal>. This does not work for LLONG_MIN, as it has no
* positive equivalent. We thus match for LLONG_MIN specifically. This is not an issue for floats, where
* numeric_limits<double>::lowest() == -numeric_limits<double>::max();
*/
-9223372036854775808 {
yylval->ival = LLONG_MIN;
return SQL_INTVAL;
}
[0-9]+ {
errno = 0;
yylval->ival = strtoll(yytext, nullptr, 0);
if (errno) {
return fprintf(stderr, "[SQL-Lexer-Error] Integer cannot be parsed - is it out of range?");
return 0;
}
return SQL_INTVAL;
}
\"[^\"\n]+\" {
// Crop the leading and trailing quote char
yylval->sval = hsql::substr(yytext, 1, strlen(yytext)-1);
return SQL_IDENTIFIER;
}
[A-Za-z][A-Za-z0-9_]* {
yylval->sval = strdup(yytext);
return SQL_IDENTIFIER;
}
\' { BEGIN singlequotedstring; strbuf.clear(); strbuf.str(""); } // Clear strbuf manually, see #170
<singlequotedstring>\'\' { strbuf << '\''; }
<singlequotedstring>[^']* { strbuf << yytext; }
<singlequotedstring>\' { BEGIN 0; yylval->sval = strdup(strbuf.str().c_str()); return SQL_STRING; }
<singlequotedstring><<EOF>> { fprintf(stderr, "[SQL-Lexer-Error] Unterminated string\n"); return 0; }
. { fprintf(stderr, "[SQL-Lexer-Error] Unknown Character: %c\n", yytext[0]); return 0; }
%%
/***************************
** Section 3: User code
***************************/
int yyerror(const char *msg) {
fprintf(stderr, "[SQL-Lexer-Error] %s\n",msg); return 0;
}

View File

@@ -0,0 +1,46 @@
from __future__ import print_function
import math
with open("sql_keywords.txt", 'r') as fh:
keywords = [line.strip() for line in fh.readlines() if not line.strip().startswith("//") and len(line.strip()) > 0]
keywords = sorted(set(keywords)) # Sort by name
keywords = sorted(keywords, key=lambda x: len(x), reverse=True) # Sort by length
#################
# Flex
max_len = len(max(keywords, key=lambda x: len(x))) + 1
max_len = 4 * int(math.ceil(max_len / 4.0))
for keyword in keywords:
len_diff = (max_len) - len(keyword)
num_tabs = int(math.floor(len_diff / 4.0))
if len_diff % 4 != 0: num_tabs += 1
tabs = ''.join(['\t' for _ in range(num_tabs)])
print("%s%sTOKEN(%s)" % (keyword, tabs, keyword))
#
#################
#################
# Bison
line = "%token"
max_len = 60
print("/* SQL Keywords */")
for keyword in keywords:
if len(line + " " + keyword) > max_len:
print(line)
line = "%token " + keyword
else:
line = line + " " + keyword
print(line)
#
#################

View File

@@ -0,0 +1,33 @@
#ifndef __PARSER_TYPEDEF_H__
#define __PARSER_TYPEDEF_H__
#include <vector>
#ifndef YYtypeDEF_YY_SCANNER_T
#define YYtypeDEF_YY_SCANNER_T
typedef void* yyscan_t;
#endif
#define YYSTYPE HSQL_STYPE
#define YYLTYPE HSQL_LTYPE
struct HSQL_CUST_LTYPE {
int first_line;
int first_column;
int last_line;
int last_column;
int total_column;
// Length of the string in the SQL query string
int string_length;
// Parameters.
// int param_id;
std::vector<void*> param_list;
};
#define HSQL_LTYPE HSQL_CUST_LTYPE
#define HSQL_LTYPE_IS_DECLARED 1
#endif

View File

@@ -0,0 +1,163 @@
// Possible source for more tokens https://www.sqlite.org/lang_keywords.html
//////////////////////////
// Select Statement
SELECT
TOP
FROM
WHERE
GROUP
BY
HAVING
ORDER
ASC
DESC
LIMIT
DISTINCT
OFFSET
UNION
ALL
EXCEPT
MINUS
INTERSECT
// Join clause
JOIN
ON
INNER
OUTER
LEFT
RIGHT
FULL
CROSS
USING
NATURAL
// Select Statement
//////////////////////
// Data Definition
CREATE
TABLE
SCHEMA
INDEX
VIEW
IF
NOT
EXISTS
GLOBAL
LOCAL
TEMPORARY
UNIQUE
VIRTUAL
INDEX
UNIQUE
HASH
SPATIAL
PRIMARY
KEY
ON
DROP
TABLE
SCHEMA
RESTRICT
CASCADE
ALTER
ADD
COLUMN
BEFORE
AFTER
// Data Definition
////////////////////////
// Data Manipulation
INSERT
VALUES
DIRECT
SORTED
COPY
FORMAT
IMPORT
FILE
CONTROL
UPDATE
SET
DELETE
TRUNCATE
MERGE
DELTA
OF
LOAD
UNLOAD
DELETE
// Prepared Statements
DEALLOCATE
PREPARE
EXECUTE
///////////////////////////////
// other statements
RENAME
EXPLAIN
PLAN
ANALYZE
SHOW
SCHEMAS
TABLES
COLUMNS
// misc.
COLUMN
INTO
AS
SET
DEFAULT
CALL
FOR
TO
ARRAY
// Expressions
NOT
AND
OR
NULL
LIKE
IN
IS
ISNULL
BETWEEN
ESCAPE
CASE
WHEN
THEN
ELSE
END
// With
WITH
HINT
PARAMETERS
ON
OFF
// Data types
DATE
TIME
TIMESTAMP
INTEGER
INT
DOUBLE
NVARCHAR
TEXT

View File

@@ -0,0 +1,40 @@
#ifndef SQLPARSER_ALTER_STATEMENT_H
#define SQLPARSER_ALTER_STATEMENT_H
#include "SQLStatement.h"
// Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql {
enum ActionType {
DropColumn,
};
struct AlterAction {
AlterAction(ActionType type);
ActionType type;
virtual ~AlterAction();
};
struct DropColumnAction : AlterAction {
DropColumnAction(char* column_name);
char* columnName;
bool ifExists;
~DropColumnAction() override;
};
// Represents SQL Alter Table statements.
// Example "ALTER TABLE students DROP COLUMN name;"
struct SQLParser_API AlterStatement : SQLStatement {
AlterStatement(char* name, AlterAction* action);
~AlterStatement() override;
char* schema;
bool ifTableExists;
char* name;
AlterAction* action;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,43 @@
#ifndef SQLPARSER_COLUMN_TYPE_H
#define SQLPARSER_COLUMN_TYPE_H
#include"sqlparser_win.h"
#include <ostream>
namespace hsql {
enum class DataType {
UNKNOWN,
BIGINT,
BOOLEAN,
CHAR,
DATE,
DATETIME,
DECIMAL,
DOUBLE,
FLOAT,
INT,
LONG,
REAL,
SMALLINT,
TEXT,
TIME,
VARCHAR,
};
// Represents the type of a column, e.g., FLOAT or VARCHAR(10)
struct SQLParser_API ColumnType {
ColumnType() = default;
ColumnType(DataType data_type, int64_t length = 0, int64_t precision = 0, int64_t scale = 0);
DataType data_type;
int64_t length; // Used for, e.g., VARCHAR(10)
int64_t precision; // Used for, e.g., DECIMAL (6, 4) or TIME (5)
int64_t scale; // Used for DECIMAL (6, 4)
};
bool operator==(const ColumnType& lhs, const ColumnType& rhs);
bool operator!=(const ColumnType& lhs, const ColumnType& rhs);
std::ostream& operator<<(std::ostream&, const ColumnType&);
} // namespace hsql
#endif

View File

@@ -0,0 +1,70 @@
#include "CreateStatement.h"
#include "SelectStatement.h"
namespace hsql {
// CreateStatemnet
CreateStatement::CreateStatement(CreateType type)
: SQLStatement(kStmtCreate),
type(type),
ifNotExists(false),
filePath(nullptr),
schema(nullptr),
tableName(nullptr),
indexName(nullptr),
indexColumns(nullptr),
columns(nullptr),
tableConstraints(nullptr),
viewColumns(nullptr),
select(nullptr) {}
CreateStatement::~CreateStatement() {
free(filePath);
free(schema);
free(tableName);
free(indexName);
delete select;
if (columns) {
for (ColumnDefinition* def : *columns) {
delete def;
}
delete columns;
}
if (tableConstraints) {
for (TableConstraint* def : *tableConstraints) {
delete def;
}
delete tableConstraints;
}
if (indexColumns) {
for (char* column : *indexColumns) {
free(column);
}
delete indexColumns;
}
if (viewColumns) {
for (char* column : *viewColumns) {
free(column);
}
delete viewColumns;
}
}
void CreateStatement::setColumnDefsAndConstraints(std::vector<TableElement*>* tableElements) {
columns = new std::vector<ColumnDefinition*>();
tableConstraints = new std::vector<TableConstraint*>();
for (auto tableElem : *tableElements) {
if (auto* colDef = dynamic_cast<ColumnDefinition*>(tableElem)) {
columns->emplace_back(colDef);
} else if (auto* tableConstraint = dynamic_cast<TableConstraint*>(tableElem)) {
tableConstraints->emplace_back(tableConstraint);
}
}
}
} // namespace hsql

View File

@@ -0,0 +1,86 @@
#ifndef SQLPARSER_CREATE_STATEMENT_H
#define SQLPARSER_CREATE_STATEMENT_H
#include "ColumnType.h"
#include "SQLStatement.h"
#include <ostream>
#include <unordered_set>
// Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql {
struct SQLParser_API SelectStatement;
enum struct ConstraintType { None, NotNull, Null, PrimaryKey, Unique };
// Superclass for both TableConstraint and Column Definition
struct SQLParser_API TableElement {
virtual ~TableElement() {}
};
// Represents definition of a table constraint
struct SQLParser_API TableConstraint : TableElement {
TableConstraint(ConstraintType keyType, std::vector<char*>* columnNames);
~TableConstraint() override;
ConstraintType type;
std::vector<char*>* columnNames;
};
// Represents definition of a table column
struct SQLParser_API ColumnDefinition : TableElement {
ColumnDefinition(char* name, ColumnType type, std::unordered_set<ConstraintType>* column_constraints);
~ColumnDefinition() override;
// By default, columns are nullable. However, we track if a column is explicitly requested to be nullable to
// notice conflicts with PRIMARY KEY table constraints.
bool trySetNullableExplicit() {
if (column_constraints->count(ConstraintType::NotNull) || column_constraints->count(ConstraintType::PrimaryKey)) {
if (column_constraints->count(ConstraintType::Null)) {
return false;
}
nullable = false;
}
return true;
}
std::unordered_set<ConstraintType>* column_constraints;
char* name;
ColumnType type;
bool nullable;
};
enum CreateType {
kCreateTable,
kCreateTableFromTbl, // Hyrise file format
kCreateView,
kCreateIndex
};
// Represents SQL Create statements.
// Example: "CREATE TABLE students (name TEXT, student_number INTEGER, city TEXT, grade DOUBLE)"
struct CreateStatement : SQLStatement {
CreateStatement(CreateType type);
~CreateStatement() override;
void setColumnDefsAndConstraints(std::vector<TableElement*>* tableElements);
CreateType type;
bool ifNotExists; // default: false
char* filePath; // default: nullptr
char* schema; // default: nullptr
char* tableName; // default: nullptr
char* indexName; // default: nullptr
std::vector<char*>* indexColumns; // default: nullptr
std::vector<ColumnDefinition*>* columns; // default: nullptr
std::vector<TableConstraint*>* tableConstraints; // default: nullptr
std::vector<char*>* viewColumns;
SelectStatement* select;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,23 @@
#ifndef SQLPARSER_DELETE_STATEMENT_H
#define SQLPARSER_DELETE_STATEMENT_H
#include "SQLStatement.h"
// Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql {
// Represents SQL Delete statements.
// Example: "DELETE FROM students WHERE grade > 3.0"
// Note: if (expr == nullptr) => delete all rows (truncate)
struct SQLParser_API DeleteStatement : SQLStatement {
DeleteStatement();
~DeleteStatement() override;
char* schema;
char* tableName;
Expr* expr;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,25 @@
#ifndef SQLPARSER_DROP_STATEMENT_H
#define SQLPARSER_DROP_STATEMENT_H
#include "SQLStatement.h"
// Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql {
enum DropType { kDropTable, kDropSchema, kDropIndex, kDropView, kDropPreparedStatement };
// Represents SQL Delete statements.
// Example "DROP TABLE students;"
struct SQLParser_API DropStatement : SQLStatement {
DropStatement(DropType type);
~DropStatement() override;
DropType type;
bool ifExists;
char* schema;
char* name;
char* indexName;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,20 @@
#ifndef SQLPARSER_EXECUTE_STATEMENT_H
#define SQLPARSER_EXECUTE_STATEMENT_H
#include "SQLStatement.h"
namespace hsql {
// Represents SQL Execute statements.
// Example: "EXECUTE ins_prep(100, "test", 2.3);"
struct SQLParser_API ExecuteStatement : SQLStatement {
ExecuteStatement();
~ExecuteStatement() override;
char* name;
std::vector<Expr*>* parameters;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,24 @@
#ifndef SQLPARSER_EXPORT_STATEMENT_H
#define SQLPARSER_EXPORT_STATEMENT_H
#include "ImportStatement.h"
#include "SQLStatement.h"
#include "SelectStatement.h"
namespace hsql {
// Represents SQL Export statements.
struct SQLParser_API ExportStatement : SQLStatement {
ExportStatement(ImportType type);
~ExportStatement() override;
// ImportType is used for compatibility reasons
ImportType type;
char* filePath;
char* schema;
char* tableName;
SelectStatement* select;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,315 @@
#include "Expr.h"
#include <stdio.h>
#include <string.h>
#include "SelectStatement.h"
namespace hsql {
FrameBound::FrameBound(int64_t offset, FrameBoundType type, bool unbounded)
: offset{offset}, type{type}, unbounded{unbounded} {}
FrameDescription::FrameDescription(FrameType type, FrameBound* start, FrameBound* end)
: type{type}, start{start}, end{end} {}
FrameDescription::~FrameDescription() {
delete start;
delete end;
}
WindowDescription::WindowDescription(std::vector<Expr*>* partitionList, std::vector<OrderDescription*>* orderList,
FrameDescription* frameDescription)
: partitionList{partitionList}, orderList{orderList}, frameDescription{frameDescription} {}
WindowDescription::~WindowDescription() {
if (partitionList) {
for (Expr* e : *partitionList) {
delete e;
}
delete partitionList;
}
if (orderList) {
for (OrderDescription* orderDescription : *orderList) {
delete orderDescription;
}
delete orderList;
}
delete frameDescription;
}
Expr::Expr(ExprType type)
: type(type),
expr(nullptr),
expr2(nullptr),
exprList(nullptr),
select(nullptr),
name(nullptr),
table(nullptr),
alias(nullptr),
fval(0),
ival(0),
ival2(0),
datetimeField(kDatetimeNone),
columnType(DataType::UNKNOWN, 0),
isBoolLiteral(false),
opType(kOpNone),
distinct(false),
windowDescription(nullptr) {}
Expr::~Expr() {
delete expr;
delete expr2;
delete select;
delete windowDescription;
free(name);
free(table);
free(alias);
if (exprList) {
for (Expr* e : *exprList) {
delete e;
}
delete exprList;
}
}
Expr* Expr::make(ExprType type) {
Expr* e = new Expr(type);
return e;
}
Expr* Expr::makeOpUnary(OperatorType op, Expr* expr) {
Expr* e = new Expr(kExprOperator);
e->opType = op;
e->expr = expr;
e->expr2 = nullptr;
return e;
}
Expr* Expr::makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2) {
Expr* e = new Expr(kExprOperator);
e->opType = op;
e->expr = expr1;
e->expr2 = expr2;
return e;
}
Expr* Expr::makeBetween(Expr* expr, Expr* left, Expr* right) {
Expr* e = new Expr(kExprOperator);
e->expr = expr;
e->opType = kOpBetween;
e->exprList = new std::vector<Expr*>();
e->exprList->push_back(left);
e->exprList->push_back(right);
return e;
}
Expr* Expr::makeCaseList(Expr* caseListElement) {
Expr* e = new Expr(kExprOperator);
// Case list expressions are temporary and will be integrated into the case
// expressions exprList - thus assign operator type kOpNone
e->opType = kOpNone;
e->exprList = new std::vector<Expr*>();
e->exprList->push_back(caseListElement);
return e;
}
Expr* Expr::makeCaseListElement(Expr* when, Expr* then) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpCaseListElement;
e->expr = when;
e->expr2 = then;
return e;
}
Expr* Expr::caseListAppend(Expr* caseList, Expr* caseListElement) {
caseList->exprList->push_back(caseListElement);
return caseList;
}
Expr* Expr::makeCase(Expr* expr, Expr* caseList, Expr* elseExpr) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpCase;
e->expr = expr;
e->expr2 = elseExpr;
e->exprList = caseList->exprList;
caseList->exprList = nullptr;
delete caseList;
return e;
}
Expr* Expr::makeLiteral(int64_t val) {
Expr* e = new Expr(kExprLiteralInt);
e->ival = val;
return e;
}
Expr* Expr::makeLiteral(double value) {
Expr* e = new Expr(kExprLiteralFloat);
e->fval = value;
return e;
}
Expr* Expr::makeLiteral(char* string) {
Expr* e = new Expr(kExprLiteralString);
e->name = string;
return e;
}
Expr* Expr::makeLiteral(bool val) {
Expr* e = new Expr(kExprLiteralInt);
e->ival = (int)val;
e->isBoolLiteral = true;
return e;
}
Expr* Expr::makeNullLiteral() {
Expr* e = new Expr(kExprLiteralNull);
return e;
}
Expr* Expr::makeDateLiteral(char* string) {
Expr* e = new Expr(kExprLiteralDate);
e->name = string;
return e;
}
Expr* Expr::makeIntervalLiteral(int64_t duration, DatetimeField unit) {
Expr* e = new Expr(kExprLiteralInterval);
e->ival = duration;
e->datetimeField = unit;
return e;
}
Expr* Expr::makeColumnRef(char* name) {
Expr* e = new Expr(kExprColumnRef);
e->name = name;
return e;
}
Expr* Expr::makeColumnRef(char* table, char* name) {
Expr* e = new Expr(kExprColumnRef);
e->name = name;
e->table = table;
return e;
}
Expr* Expr::makeStar(void) {
Expr* e = new Expr(kExprStar);
return e;
}
Expr* Expr::makeStar(char* table) {
Expr* e = new Expr(kExprStar);
e->table = table;
return e;
}
Expr* Expr::makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct, WindowDescription* window) {
Expr* e = new Expr(kExprFunctionRef);
e->name = func_name;
e->exprList = exprList;
e->distinct = distinct;
e->windowDescription = window;
return e;
}
Expr* Expr::makeArray(std::vector<Expr*>* exprList) {
Expr* e = new Expr(kExprArray);
e->exprList = exprList;
return e;
}
Expr* Expr::makeArrayIndex(Expr* expr, int64_t index) {
Expr* e = new Expr(kExprArrayIndex);
e->expr = expr;
e->ival = index;
return e;
}
Expr* Expr::makeParameter(int id) {
Expr* e = new Expr(kExprParameter);
e->ival = id;
return e;
}
Expr* Expr::makeSelect(SelectStatement* select) {
Expr* e = new Expr(kExprSelect);
e->select = select;
return e;
}
Expr* Expr::makeExists(SelectStatement* select) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpExists;
e->select = select;
return e;
}
Expr* Expr::makeInOperator(Expr* expr, std::vector<Expr*>* exprList) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpIn;
e->expr = expr;
e->exprList = exprList;
return e;
}
Expr* Expr::makeInOperator(Expr* expr, SelectStatement* select) {
Expr* e = new Expr(kExprOperator);
e->opType = kOpIn;
e->expr = expr;
e->select = select;
return e;
}
Expr* Expr::makeExtract(DatetimeField datetimeField, Expr* expr) {
Expr* e = new Expr(kExprExtract);
e->datetimeField = datetimeField;
e->expr = expr;
return e;
}
Expr* Expr::makeCast(Expr* expr, ColumnType columnType) {
Expr* e = new Expr(kExprCast);
e->columnType = columnType;
e->expr = expr;
return e;
}
bool Expr::isType(ExprType exprType) const { return exprType == type; }
bool Expr::isLiteral() const {
return isType(kExprLiteralInt) || isType(kExprLiteralFloat) || isType(kExprLiteralString) || isType(kExprParameter) ||
isType(kExprLiteralNull) || isType(kExprLiteralDate) || isType(kExprLiteralInterval);
}
bool Expr::hasAlias() const { return alias != nullptr; }
bool Expr::hasTable() const { return table != nullptr; }
const char* Expr::getName() const {
if (alias)
return alias;
else
return name;
}
char* substr(const char* source, int from, int to) {
int len = to - from;
char* copy = (char*)malloc(len + 1);
;
#if defined(_WIN32) || defined(_WIN64)
#pragma warning(disable : 4996)
#endif
strncpy(copy, source + from, len);
copy[len] = '\0';
return copy;
#if defined(_WIN32) || defined(_WIN64)
#pragma warning(default : 4996)
#endif
}
} // namespace hsql

View File

@@ -0,0 +1,237 @@
#ifndef SQLPARSER_EXPR_H
#define SQLPARSER_EXPR_H
#include <stdlib.h>
#include <memory>
#include <vector>
#include "ColumnType.h"
namespace hsql {
struct SelectStatement;
struct OrderDescription;
// Helper function used by the lexer.
// TODO: move to more appropriate place.
char* substr(const char* source, int from, int to);
enum ExprType {
kExprLiteralFloat,
kExprLiteralString,
kExprLiteralInt,
kExprLiteralNull,
kExprLiteralDate,
kExprLiteralInterval,
kExprStar,
kExprParameter,
kExprColumnRef,
kExprFunctionRef,
kExprOperator,
kExprSelect,
kExprHint,
kExprArray,
kExprArrayIndex,
kExprExtract,
kExprCast
};
// Operator types. These are important for expressions of type kExprOperator.
enum OperatorType {
kOpNone,
// Ternary operator
kOpBetween,
// n-nary special case
kOpCase,
kOpCaseListElement, // `WHEN expr THEN expr`
// Binary operators.
kOpPlus,
kOpMinus,
kOpAsterisk,
kOpSlash,
kOpPercentage,
kOpCaret,
kOpEquals,
kOpNotEquals,
kOpLess,
kOpLessEq,
kOpGreater,
kOpGreaterEq,
kOpLike,
kOpNotLike,
kOpILike,
kOpAnd,
kOpOr,
kOpIn,
kOpConcat,
// Unary operators.
kOpNot,
kOpUnaryMinus,
kOpIsNull,
kOpExists
};
enum DatetimeField {
kDatetimeNone,
kDatetimeSecond,
kDatetimeMinute,
kDatetimeHour,
kDatetimeDay,
kDatetimeMonth,
kDatetimeYear,
};
// Description of the frame clause within a window expression.
enum FrameBoundType { kFollowing, kPreceding, kCurrentRow };
struct FrameBound {
FrameBound(int64_t offset, FrameBoundType type, bool unbounded);
int64_t offset;
FrameBoundType type;
bool unbounded;
};
enum FrameType { kRange, kRows, kGroups };
struct SQLParser_API FrameDescription {
FrameDescription(FrameType type, FrameBound* start, FrameBound* end);
virtual ~FrameDescription();
FrameType type;
FrameBound* start;
FrameBound* end;
};
typedef struct Expr Expr;
// Description of additional fields for a window expression.
struct SQLParser_API WindowDescription {
WindowDescription(std::vector<Expr*>* partitionList, std::vector<OrderDescription*>* orderList,
FrameDescription* frameDescription);
virtual ~WindowDescription();
std::vector<Expr*>* partitionList;
std::vector<OrderDescription*>* orderList;
FrameDescription* frameDescription;
};
// Represents SQL expressions (i.e. literals, operators, column_refs).
// TODO: When destructing a placeholder expression, we might need to alter the
// placeholder_list.
struct SQLParser_API Expr {
Expr(ExprType type);
virtual ~Expr();
ExprType type;
// TODO: Replace expressions by list.
Expr* expr;
Expr* expr2;
std::vector<Expr*>* exprList;
SelectStatement* select;
char* name;
char* table;
char* alias;
double fval;
int64_t ival;
int64_t ival2;
DatetimeField datetimeField;
ColumnType columnType;
bool isBoolLiteral;
OperatorType opType;
bool distinct;
WindowDescription* windowDescription;
// Convenience accessor methods.
bool isType(ExprType exprType) const;
bool isLiteral() const;
bool hasAlias() const;
bool hasTable() const;
const char* getName() const;
// Static constructors.
static Expr* make(ExprType type);
static Expr* makeOpUnary(OperatorType op, Expr* expr);
static Expr* makeOpBinary(Expr* expr1, OperatorType op, Expr* expr2);
static Expr* makeBetween(Expr* expr, Expr* left, Expr* right);
static Expr* makeCaseList(Expr* caseListElement);
static Expr* makeCaseListElement(Expr* when, Expr* then);
static Expr* caseListAppend(Expr* caseList, Expr* caseListElement);
static Expr* makeCase(Expr* expr, Expr* when, Expr* elseExpr);
static Expr* makeLiteral(int64_t val);
static Expr* makeLiteral(double val);
static Expr* makeLiteral(char* val);
static Expr* makeLiteral(bool val);
static Expr* makeNullLiteral();
static Expr* makeDateLiteral(char* val);
static Expr* makeIntervalLiteral(int64_t duration, DatetimeField unit);
static Expr* makeColumnRef(char* name);
static Expr* makeColumnRef(char* table, char* name);
static Expr* makeStar(void);
static Expr* makeStar(char* table);
static Expr* makeFunctionRef(char* func_name, std::vector<Expr*>* exprList, bool distinct, WindowDescription* window);
static Expr* makeArray(std::vector<Expr*>* exprList);
static Expr* makeArrayIndex(Expr* expr, int64_t index);
static Expr* makeParameter(int id);
static Expr* makeSelect(SelectStatement* select);
static Expr* makeExists(SelectStatement* select);
static Expr* makeInOperator(Expr* expr, std::vector<Expr*>* exprList);
static Expr* makeInOperator(Expr* expr, SelectStatement* select);
static Expr* makeExtract(DatetimeField datetimeField1, Expr* expr);
static Expr* makeCast(Expr* expr, ColumnType columnType);
};
// 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
// http://www.ex-parrot.com/~chris/random/initialise.html
// Unused
#define ALLOC_EXPR(var, type) \
Expr* var; \
do { \
Expr zero = {type}; \
var = (Expr*)malloc(sizeof *var); \
*var = zero; \
} while (0);
#undef ALLOC_EXPR
} // namespace hsql
#endif

View File

@@ -0,0 +1,28 @@
#ifndef SQLPARSER_IMPORT_STATEMENT_H
#define SQLPARSER_IMPORT_STATEMENT_H
#include "SQLStatement.h"
namespace hsql {
enum ImportType {
kImportCSV,
kImportTbl, // Hyrise file format
kImportBinary,
kImportAuto
};
// Represents SQL Import statements.
struct SQLParser_API ImportStatement : SQLStatement {
ImportStatement(ImportType type);
~ImportStatement() override;
ImportType type;
char* filePath;
char* schema;
char* tableName;
Expr* whereClause;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,26 @@
#ifndef SQLPARSER_INSERT_STATEMENT_H
#define SQLPARSER_INSERT_STATEMENT_H
#include "SQLStatement.h"
#include "SelectStatement.h"
namespace hsql {
enum InsertType { kInsertValues, kInsertSelect };
// Represents SQL Insert statements.
// Example: "INSERT INTO students VALUES ('Max', 1112233, 'Musterhausen', 2.3)"
struct SQLParser_API InsertStatement : SQLStatement {
InsertStatement(InsertType type);
~InsertStatement() override;
InsertType type;
char* schema;
char* tableName;
std::vector<char*>* columns;
std::vector<Expr*>* values;
SelectStatement* select;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,12 @@
#include "PrepareStatement.h"
namespace hsql {
// PrepareStatement
PrepareStatement::PrepareStatement() : SQLStatement(kStmtPrepare), name(nullptr), query(nullptr) {}
PrepareStatement::~PrepareStatement() {
free(name);
free(query);
}
} // namespace hsql

View File

@@ -0,0 +1,22 @@
#ifndef SQLPARSER_PREPARE_STATEMENT_H
#define SQLPARSER_PREPARE_STATEMENT_H
#include "SQLStatement.h"
namespace hsql {
// Represents SQL Prepare statements.
// Example: PREPARE test FROM 'SELECT * FROM test WHERE a = ?;'
struct SQLParser_API PrepareStatement : SQLStatement {
PrepareStatement();
~PrepareStatement() override;
char* name;
// The query that is supposed to be prepared.
char* query;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,24 @@
#include "SQLStatement.h"
namespace hsql {
// SQLStatement
SQLStatement::SQLStatement(StatementType type) : hints(nullptr), type_(type) {}
SQLStatement::~SQLStatement() {
if (hints) {
for (Expr* hint : *hints) {
delete hint;
}
}
delete hints;
}
StatementType SQLStatement::type() const { return type_; }
bool SQLStatement::isType(StatementType type) const { return (type_ == type); }
bool SQLStatement::is(StatementType type) const { return isType(type); }
} // namespace hsql

View File

@@ -0,0 +1,51 @@
#ifndef SQLPARSER_SQLSTATEMENT_H
#define SQLPARSER_SQLSTATEMENT_H
#include <vector>
#include "sqlparser_win.h"
#include "Expr.h"
namespace hsql {
enum StatementType {
kStmtError, // unused
kStmtSelect,
kStmtImport,
kStmtInsert,
kStmtUpdate,
kStmtDelete,
kStmtCreate,
kStmtDrop,
kStmtPrepare,
kStmtExecute,
kStmtExport,
kStmtRename,
kStmtAlter,
kStmtShow,
kStmtTransaction
};
// Base struct for every SQL statement
struct SQLParser_API SQLStatement {
SQLStatement(StatementType type);
virtual ~SQLStatement();
StatementType type() const;
bool isType(StatementType type) const;
// Shorthand for isType(type).
bool is(StatementType type) const;
// Length of the string in the SQL query string
size_t stringLength;
std::vector<Expr*>* hints;
private:
StatementType type_;
};
} // namespace hsql
#endif // SQLPARSER_SQLSTATEMENT_H

View File

@@ -0,0 +1,113 @@
#ifndef SQLPARSER_SELECT_STATEMENT_H
#define SQLPARSER_SELECT_STATEMENT_H
#include "Expr.h"
#include "SQLStatement.h"
#include "Table.h"
namespace hsql {
enum OrderType { kOrderAsc, kOrderDesc };
enum SetType { kSetUnion, kSetIntersect, kSetExcept };
enum RowLockMode { ForUpdate, ForNoKeyUpdate, ForShare, ForKeyShare };
enum RowLockWaitPolicy { NoWait, SkipLocked, None };
// Description of the order by clause within a select statement.
struct SQLParser_API OrderDescription {
OrderDescription(OrderType type, Expr* expr);
virtual ~OrderDescription();
OrderType type;
Expr* expr;
};
// Description of the limit clause within a select statement.
struct SQLParser_API LimitDescription {
LimitDescription(Expr* limit, Expr* offset);
virtual ~LimitDescription();
Expr* limit;
Expr* offset;
};
// Description of the group-by clause within a select statement.
struct SQLParser_API GroupByDescription {
GroupByDescription();
virtual ~GroupByDescription();
std::vector<Expr*>* columns;
Expr* having;
};
struct SQLParser_API WithDescription {
~WithDescription();
char* alias;
SelectStatement* select;
};
struct SQLParser_API SetOperation {
SetOperation();
virtual ~SetOperation();
SetType setType;
bool isAll;
SelectStatement* nestedSelectStatement;
std::vector<OrderDescription*>* resultOrder;
LimitDescription* resultLimit;
};
struct SQLParser_API LockingClause {
RowLockMode rowLockMode;
RowLockWaitPolicy rowLockWaitPolicy;
std::vector<char*>* tables;
};
// Representation of a full SQL select statement.
struct SQLParser_API SelectStatement : SQLStatement {
SelectStatement();
~SelectStatement() override;
TableRef* fromTable;
bool selectDistinct;
std::vector<Expr*>* selectList;
Expr* whereClause;
GroupByDescription* groupBy;
// Note that a SetOperation is always connected to a
// different SelectStatement. This statement can itself
// have SetOperation connections to other SelectStatements.
// To evaluate the operations in the correct order:
// Iterate over the setOperations vector:
// 1. Fully evaluate the nestedSelectStatement within the SetOperation
// 2. Connect the original statement with the
// evaluated nestedSelectStatement
// 3. Apply the resultOrder and the resultLimit
// 4. The result now functions as the the original statement
// for the next iteration
//
// Example:
//
// (SELECT * FROM students INTERSECT SELECT * FROM students_2) UNION SELECT * FROM students_3 ORDER BY grade ASC;
//
// 1. We evaluate `Select * FROM students`
// 2. Then we iterate over the setOperations vector
// 3. We evalute the nestedSelectStatement of the first entry, which is: `SELECT * FROM students_2`
// 4. We connect the result of 1. with the results of 3. using the setType, which is INTERSECT
// 5. We continue the iteration of the setOperations vector
// 6. We evaluate the new nestedSelectStatement which is: `SELECT * FROM students_3`
// 7. We apply a Union-Operation to connect the results of 4. and 6.
// 8. Finally, we apply the resultOrder of the last SetOperation (ORDER BY grade ASC)
std::vector<SetOperation*>* setOperations;
std::vector<OrderDescription*>* order;
std::vector<WithDescription*>* withDescriptions;
LimitDescription* limit;
std::vector<LockingClause*>* lockings;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,23 @@
#ifndef SQLPARSER_SHOW_STATEMENT_H
#define SQLPARSER_SHOW_STATEMENT_H
#include "SQLStatement.h"
// Note: Implementations of constructors and destructors can be found in statements.cpp.
namespace hsql {
enum ShowType { kShowColumns, kShowTables };
// Represents SQL SHOW statements.
// Example "SHOW TABLES;"
struct SQLParser_API ShowStatement : SQLStatement {
ShowStatement(ShowType type);
~ShowStatement() override;
ShowType type;
char* schema;
char* name;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,68 @@
#ifndef SQLPARSER_TABLEREF_H
#define SQLPARSER_TABLEREF_H
#include <stdio.h>
#include <vector>
#include "Expr.h"
namespace hsql {
struct SelectStatement;
struct JoinDefinition;
struct TableRef;
// Possible table reference types.
enum TableRefType { kTableName, kTableSelect, kTableJoin, kTableCrossProduct };
struct SQLParser_API TableName {
char* schema;
char* name;
};
struct SQLParser_API Alias {
Alias(char* name, std::vector<char*>* columns = nullptr);
~Alias();
char* name;
std::vector<char*>* columns;
};
// Holds reference to tables. Can be either table names or a select statement.
struct SQLParser_API TableRef {
TableRef(TableRefType type);
virtual ~TableRef();
TableRefType type;
char* schema;
char* name;
Alias* alias;
SelectStatement* select;
std::vector<TableRef*>* list;
JoinDefinition* join;
// Returns true if a schema is set.
bool hasSchema() const;
// Returns the alias, if it is set. Otherwise the name.
const char* getName() const;
};
// Possible types of joins.
enum JoinType { kJoinInner, kJoinFull, kJoinLeft, kJoinRight, kJoinCross, kJoinNatural };
// Definition of a join construct.
struct SQLParser_API JoinDefinition {
JoinDefinition();
virtual ~JoinDefinition();
TableRef* left;
TableRef* right;
Expr* condition;
JoinType type;
};
} // namespace hsql
#endif

View File

@@ -0,0 +1,21 @@
#ifndef HYRISE_TRANSACTIONSTATEMENT_H
#define HYRISE_TRANSACTIONSTATEMENT_H
#include "SQLStatement.h"
namespace hsql {
// Represents SQL Transaction statements.
// Example: BEGIN TRANSACTION;
enum TransactionCommand { kBeginTransaction, kCommitTransaction, kRollbackTransaction };
struct SQLParser_API TransactionStatement : SQLStatement {
TransactionStatement(TransactionCommand command);
~TransactionStatement() override;
TransactionCommand command;
};
} // namespace hsql
#endif

View File

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

View File

@@ -0,0 +1,393 @@
#include "statements.h"
#include "AlterStatement.h"
namespace hsql {
// KeyConstraints
TableConstraint::TableConstraint(ConstraintType type, std::vector<char*>* columnNames)
: type(type), columnNames(columnNames) {}
TableConstraint::~TableConstraint() {
for (char* def : *columnNames) {
free(def);
}
delete columnNames;
}
// ColumnDefinition
ColumnDefinition::ColumnDefinition(char* name, ColumnType type, std::unordered_set<ConstraintType>* column_constraints)
: column_constraints(column_constraints), name(name), type(type), nullable(true) {}
ColumnDefinition::~ColumnDefinition() {
free(name);
delete column_constraints;
}
ColumnType::ColumnType(DataType data_type, int64_t length, int64_t precision, int64_t scale)
: data_type(data_type), length(length), precision(precision), scale(scale) {}
bool operator==(const ColumnType& lhs, const ColumnType& rhs) {
if (lhs.data_type != rhs.data_type) return false;
return lhs.length == rhs.length && lhs.precision == rhs.precision && lhs.scale == rhs.scale;
}
bool operator!=(const ColumnType& lhs, const ColumnType& rhs) { return !(lhs == rhs); }
std::ostream& operator<<(std::ostream& stream, const ColumnType& column_type) {
switch (column_type.data_type) {
case DataType::UNKNOWN:
stream << "UNKNOWN";
break;
case DataType::INT:
stream << "INT";
break;
case DataType::BIGINT:
stream << "BIGINT";
break;
case DataType::LONG:
stream << "LONG";
break;
case DataType::FLOAT:
stream << "FLOAT";
break;
case DataType::DOUBLE:
stream << "DOUBLE";
break;
case DataType::REAL:
stream << "REAL";
break;
case DataType::CHAR:
stream << "CHAR(" << column_type.length << ")";
break;
case DataType::VARCHAR:
stream << "VARCHAR(" << column_type.length << ")";
break;
case DataType::DECIMAL:
stream << "DECIMAL";
break;
case DataType::TEXT:
stream << "TEXT";
break;
case DataType::DATETIME:
stream << "DATETIME";
break;
case DataType::DATE:
stream << "DATE";
break;
case DataType::TIME:
stream << "TIME";
break;
case DataType::SMALLINT:
stream << "SMALLINT";
break;
case DataType::BOOLEAN:
stream << "BOOLEAN";
break;
}
return stream;
}
// DeleteStatement
DeleteStatement::DeleteStatement() : SQLStatement(kStmtDelete), schema(nullptr), tableName(nullptr), expr(nullptr) {}
DeleteStatement::~DeleteStatement() {
free(schema);
free(tableName);
delete expr;
}
// DropStatement
DropStatement::DropStatement(DropType type)
: SQLStatement(kStmtDrop), type(type), schema(nullptr), name(nullptr), indexName(nullptr) {}
DropStatement::~DropStatement() {
free(schema);
free(name);
free(indexName);
}
// AlterStatement and supportive classes
AlterAction::AlterAction(ActionType type) : type(type) {}
AlterAction::~AlterAction() = default;
DropColumnAction::DropColumnAction(char* column_name)
: AlterAction(ActionType::DropColumn), columnName(column_name), ifExists(false) {}
DropColumnAction::~DropColumnAction() { free(columnName); }
AlterStatement::AlterStatement(char* name, AlterAction* action)
: SQLStatement(kStmtAlter), schema(nullptr), ifTableExists(false), name(name), action(action) {}
AlterStatement::~AlterStatement() {
free(schema);
free(name);
delete action;
}
// TransactionStatement
TransactionStatement::TransactionStatement(TransactionCommand command)
: SQLStatement(kStmtTransaction), command(command) {}
TransactionStatement::~TransactionStatement() {}
// ExecuteStatement
ExecuteStatement::ExecuteStatement() : SQLStatement(kStmtExecute), name(nullptr), parameters(nullptr) {}
ExecuteStatement::~ExecuteStatement() {
free(name);
if (parameters) {
for (Expr* param : *parameters) {
delete param;
}
delete parameters;
}
}
// ExportStatement
ExportStatement::ExportStatement(ImportType type)
: SQLStatement(kStmtExport), type(type), filePath(nullptr), schema(nullptr), tableName(nullptr), select(nullptr) {}
ExportStatement::~ExportStatement() {
free(filePath);
free(schema);
free(tableName);
delete select;
}
// ImportStatement
ImportStatement::ImportStatement(ImportType type)
: SQLStatement(kStmtImport),
type(type),
filePath(nullptr),
schema(nullptr),
tableName(nullptr),
whereClause(nullptr) {}
ImportStatement::~ImportStatement() {
free(filePath);
free(schema);
free(tableName);
delete whereClause;
}
// InsertStatement
InsertStatement::InsertStatement(InsertType type)
: SQLStatement(kStmtInsert),
type(type),
schema(nullptr),
tableName(nullptr),
columns(nullptr),
values(nullptr),
select(nullptr) {}
InsertStatement::~InsertStatement() {
free(schema);
free(tableName);
delete select;
if (columns) {
for (char* column : *columns) {
free(column);
}
delete columns;
}
if (values) {
for (Expr* expr : *values) {
delete expr;
}
delete values;
}
}
// ShowStatament
ShowStatement::ShowStatement(ShowType type) : SQLStatement(kStmtShow), type(type), schema(nullptr), name(nullptr) {}
ShowStatement::~ShowStatement() {
free(schema);
free(name);
}
// SelectStatement.h
// OrderDescription
OrderDescription::OrderDescription(OrderType type, Expr* expr) : type(type), expr(expr) {}
OrderDescription::~OrderDescription() { delete expr; }
// LimitDescription
LimitDescription::LimitDescription(Expr* limit, Expr* offset) : limit(limit), offset(offset) {}
LimitDescription::~LimitDescription() {
delete limit;
delete offset;
}
// GroypByDescription
GroupByDescription::GroupByDescription() : columns(nullptr), having(nullptr) {}
GroupByDescription::~GroupByDescription() {
delete having;
if (columns) {
for (Expr* expr : *columns) {
delete expr;
}
delete columns;
}
}
WithDescription::~WithDescription() {
free(alias);
delete select;
}
// SelectStatement
SelectStatement::SelectStatement()
: SQLStatement(kStmtSelect),
fromTable(nullptr),
selectDistinct(false),
selectList(nullptr),
whereClause(nullptr),
groupBy(nullptr),
setOperations(nullptr),
order(nullptr),
withDescriptions(nullptr),
limit(nullptr),
lockings(nullptr) {}
SelectStatement::~SelectStatement() {
delete fromTable;
delete whereClause;
delete groupBy;
delete limit;
// Delete each element in the select list.
if (selectList) {
for (Expr* expr : *selectList) {
delete expr;
}
delete selectList;
}
if (order) {
for (OrderDescription* desc : *order) {
delete desc;
}
delete order;
}
if (withDescriptions) {
for (WithDescription* desc : *withDescriptions) {
delete desc;
}
delete withDescriptions;
}
if (setOperations) {
for (SetOperation* setOperation : *setOperations) {
delete setOperation;
}
delete setOperations;
}
if (lockings) {
for (LockingClause* lockingClause : *lockings) {
if (lockingClause->tables) {
for (char* dtable : *lockingClause->tables) {
free(dtable);
}
delete lockingClause->tables;
}
delete lockingClause;
}
delete lockings;
}
}
// UpdateStatement
UpdateStatement::UpdateStatement() : SQLStatement(kStmtUpdate), table(nullptr), updates(nullptr), where(nullptr) {}
UpdateStatement::~UpdateStatement() {
delete table;
delete where;
if (updates) {
for (UpdateClause* update : *updates) {
free(update->column);
delete update->value;
delete update;
}
delete updates;
}
}
// Alias
Alias::Alias(char* name, std::vector<char*>* columns) : name(name), columns(columns) {}
Alias::~Alias() {
free(name);
if (columns) {
for (char* column : *columns) {
free(column);
}
delete columns;
}
}
// TableRef
TableRef::TableRef(TableRefType type)
: type(type), schema(nullptr), name(nullptr), alias(nullptr), select(nullptr), list(nullptr), join(nullptr) {}
TableRef::~TableRef() {
free(schema);
free(name);
delete select;
delete join;
delete alias;
if (list) {
for (TableRef* table : *list) {
delete table;
}
delete list;
}
}
bool TableRef::hasSchema() const { return schema != nullptr; }
const char* TableRef::getName() const {
if (alias)
return alias->name;
else
return name;
}
// JoinDefinition
JoinDefinition::JoinDefinition() : left(nullptr), right(nullptr), condition(nullptr), type(kJoinInner) {}
JoinDefinition::~JoinDefinition() {
delete left;
delete right;
delete condition;
}
SetOperation::SetOperation() : nestedSelectStatement(nullptr), resultOrder(nullptr), resultLimit(nullptr) {}
SetOperation::~SetOperation() {
delete nestedSelectStatement;
delete resultLimit;
if (resultOrder) {
for (OrderDescription* desc : *resultOrder) {
delete desc;
}
delete resultOrder;
}
}
} // namespace hsql

View File

@@ -0,0 +1,18 @@
#ifndef SQLPARSER_STATEMENTS_H
#define SQLPARSER_STATEMENTS_H
#include "AlterStatement.h"
#include "CreateStatement.h"
#include "DeleteStatement.h"
#include "DropStatement.h"
#include "ExecuteStatement.h"
#include "ExportStatement.h"
#include "ImportStatement.h"
#include "InsertStatement.h"
#include "PrepareStatement.h"
#include "SelectStatement.h"
#include "ShowStatement.h"
#include "TransactionStatement.h"
#include "UpdateStatement.h"
#endif // SQLPARSER_STATEMENTS_H

View File

@@ -0,0 +1,43 @@
#ifndef SQLPARSER_SQLPARSER_WIN_H
#define SQLPARSER_SQLPARSER_WIN_H
#if (__cplusplus >= 201703L)
#if __has_include("Poco/Data/Data.h")
#include "Poco/Data/Data.h"
#endif
#endif
#ifdef Data_API
#define SQLParser_API Data_API
#if defined(Data_EXPORTS) && !defined(SQLParser_EXPORTS)
#define SQLParser_EXPORTS
#endif
#else
#if defined(_DLL) || defined(_USRDLL)
#if defined(SQLParser_EXPORTS)
#define SQLParser_API __declspec(dllexport)
#else
#define SQLParser_API __declspec(dllimport)
#endif
#endif
#endif
#if defined(_WIN32)
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#endif
#if !defined(SQLParser_API)
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define SQLParser_API __attribute__ ((visibility ("default")))
#else
#define SQLParser_API
#endif
#endif
#endif // SQLPARSER_SQLPARSER_WIN_H

View File

@@ -0,0 +1,497 @@
#include "sqlhelper.h"
#include <iostream>
#include <map>
#include <sstream>
#include <string>
namespace hsql {
void printOperatorExpression(Expr* expr, uintmax_t num_indent);
void printAlias(Alias* alias, uintmax_t num_indent);
std::ostream& operator<<(std::ostream& os, const OperatorType& op);
std::ostream& operator<<(std::ostream& os, const DatetimeField& datetime);
std::ostream& operator<<(std::ostream& os, const FrameBound& frame_bound);
std::string indent(uintmax_t num_indent) { return std::string(num_indent, '\t'); }
void inprint(int64_t val, uintmax_t num_indent) { std::cout << indent(num_indent).c_str() << val << " " << std::endl; }
void inprint(double val, uintmax_t num_indent) { std::cout << indent(num_indent).c_str() << val << std::endl; }
void inprint(const char* val, uintmax_t num_indent) { std::cout << indent(num_indent).c_str() << val << std::endl; }
void inprint(const char* val, const char* val2, uintmax_t num_indent) {
std::cout << indent(num_indent).c_str() << val << "->" << val2 << std::endl;
}
void inprintC(char val, uintmax_t num_indent) { std::cout << indent(num_indent).c_str() << val << std::endl; }
void inprint(const OperatorType& op, uintmax_t num_indent) { std::cout << indent(num_indent) << op << std::endl; }
void inprint(const ColumnType& colType, uintmax_t num_indent) {
std::cout << indent(num_indent) << colType << std::endl;
}
void inprint(const DatetimeField& colType, uintmax_t num_indent) {
std::cout << indent(num_indent) << colType << std::endl;
}
void printTableRefInfo(TableRef* table, uintmax_t num_indent) {
switch (table->type) {
case kTableName:
inprint(table->name, num_indent);
if (table->schema) {
inprint("Schema", num_indent + 1);
inprint(table->schema, num_indent + 2);
}
break;
case kTableSelect:
printSelectStatementInfo(table->select, num_indent);
break;
case kTableJoin:
inprint("Join Table", num_indent);
inprint("Left", num_indent + 1);
printTableRefInfo(table->join->left, num_indent + 2);
inprint("Right", num_indent + 1);
printTableRefInfo(table->join->right, num_indent + 2);
inprint("Join Condition", num_indent + 1);
printExpression(table->join->condition, num_indent + 2);
break;
case kTableCrossProduct:
for (TableRef* tbl : *table->list) printTableRefInfo(tbl, num_indent);
break;
}
if (table->alias) {
printAlias(table->alias, num_indent);
}
}
void printAlias(Alias* alias, uintmax_t num_indent) {
inprint("Alias", num_indent + 1);
inprint(alias->name, num_indent + 2);
if (alias->columns) {
for (char* column : *(alias->columns)) {
inprint(column, num_indent + 3);
}
}
}
void printOperatorExpression(Expr* expr, uintmax_t num_indent) {
if (expr == nullptr) {
inprint("null", num_indent);
return;
}
inprint(expr->opType, num_indent);
printExpression(expr->expr, num_indent + 1);
if (expr->expr2) {
printExpression(expr->expr2, num_indent + 1);
} else if (expr->exprList) {
for (Expr* e : *expr->exprList) printExpression(e, num_indent + 1);
}
}
void printExpression(Expr* expr, uintmax_t num_indent) {
if (!expr) return;
switch (expr->type) {
case kExprStar:
inprint("*", num_indent);
break;
case kExprColumnRef:
inprint(expr->name, num_indent);
if (expr->table) {
inprint("Table:", num_indent + 1);
inprint(expr->table, num_indent + 2);
}
break;
// case kExprTableColumnRef: inprint(expr->table, expr->name, num_indent); break;
case kExprLiteralFloat:
inprint(expr->fval, num_indent);
break;
case kExprLiteralInt:
inprint(expr->ival, num_indent);
break;
case kExprLiteralString:
inprint(expr->name, num_indent);
break;
case kExprLiteralDate:
inprint(expr->name, num_indent);
break;
case kExprLiteralNull:
inprint("NULL", num_indent);
break;
case kExprLiteralInterval:
inprint("INTERVAL", num_indent);
inprint(expr->ival, num_indent + 1);
inprint(expr->datetimeField, num_indent + 1);
break;
case kExprFunctionRef:
inprint(expr->name, num_indent);
for (Expr* e : *expr->exprList) {
printExpression(e, num_indent + 1);
}
if (expr->windowDescription) {
printWindowDescription(expr->windowDescription, num_indent + 1);
}
break;
case kExprExtract:
inprint("EXTRACT", num_indent);
inprint(expr->datetimeField, num_indent + 1);
printExpression(expr->expr, num_indent + 1);
break;
case kExprCast:
inprint("CAST", num_indent);
inprint(expr->columnType, num_indent + 1);
printExpression(expr->expr, num_indent + 1);
break;
case kExprOperator:
printOperatorExpression(expr, num_indent);
break;
case kExprSelect:
printSelectStatementInfo(expr->select, num_indent);
break;
case kExprParameter:
inprint(expr->ival, num_indent);
break;
case kExprArray:
for (Expr* e : *expr->exprList) {
printExpression(e, num_indent + 1);
}
break;
case kExprArrayIndex:
printExpression(expr->expr, num_indent + 1);
inprint(expr->ival, num_indent);
break;
default:
std::cerr << "Unrecognized expression type " << expr->type << std::endl;
return;
}
if (expr->alias) {
inprint("Alias", num_indent + 1);
inprint(expr->alias, num_indent + 2);
}
}
void printOrderBy(const std::vector<OrderDescription*>* expr, uintmax_t num_indent) {
if (!expr) return;
for (const auto& order_description : *expr) {
printExpression(order_description->expr, num_indent);
if (order_description->type == kOrderAsc) {
inprint("ascending", num_indent);
} else {
inprint("descending", num_indent);
}
}
}
void printWindowDescription(WindowDescription* window_description, uintmax_t num_indent) {
inprint("OVER", num_indent);
if (window_description->partitionList) {
inprint("PARTITION BY", num_indent + 1);
for (const auto e : *window_description->partitionList) {
printExpression(e, num_indent + 2);
}
}
if (window_description->orderList) {
inprint("ORDER BY", num_indent + 1);
printOrderBy(window_description->orderList, num_indent + 2);
}
std::stringstream stream;
switch (window_description->frameDescription->type) {
case kRows:
stream << "ROWS";
break;
case kRange:
stream << "RANGE";
break;
case kGroups:
stream << "GROUPS";
break;
}
stream << " BETWEEN " << *window_description->frameDescription->start << " AND "
<< *window_description->frameDescription->end;
inprint(stream.str().c_str(), num_indent + 1);
}
void printSelectStatementInfo(const SelectStatement* stmt, uintmax_t num_indent) {
inprint("SelectStatement", num_indent);
inprint("Fields:", num_indent + 1);
for (Expr* expr : *stmt->selectList) printExpression(expr, num_indent + 2);
if (stmt->fromTable) {
inprint("Sources:", num_indent + 1);
printTableRefInfo(stmt->fromTable, num_indent + 2);
}
if (stmt->whereClause) {
inprint("Search Conditions:", num_indent + 1);
printExpression(stmt->whereClause, num_indent + 2);
}
if (stmt->groupBy) {
inprint("GroupBy:", num_indent + 1);
for (Expr* expr : *stmt->groupBy->columns) printExpression(expr, num_indent + 2);
if (stmt->groupBy->having) {
inprint("Having:", num_indent + 1);
printExpression(stmt->groupBy->having, num_indent + 2);
}
}
if (stmt->lockings) {
inprint("Lock Info:", num_indent + 1);
for (LockingClause* lockingClause : *stmt->lockings) {
inprint("Type", num_indent + 2);
if (lockingClause->rowLockMode == RowLockMode::ForUpdate) {
inprint("FOR UPDATE", num_indent + 3);
} else if (lockingClause->rowLockMode == RowLockMode::ForNoKeyUpdate) {
inprint("FOR NO KEY UPDATE", num_indent + 3);
} else if (lockingClause->rowLockMode == RowLockMode::ForShare) {
inprint("FOR SHARE", num_indent + 3);
} else if (lockingClause->rowLockMode == RowLockMode::ForKeyShare) {
inprint("FOR KEY SHARE", num_indent + 3);
}
if (lockingClause->tables) {
inprint("Target tables:", num_indent + 2);
for (char* dtable : *lockingClause->tables) {
inprint(dtable, num_indent + 3);
}
}
if (lockingClause->rowLockWaitPolicy != RowLockWaitPolicy::None) {
inprint("Waiting policy: ", num_indent + 2);
if (lockingClause->rowLockWaitPolicy == RowLockWaitPolicy::NoWait)
inprint("NOWAIT", num_indent + 3);
else
inprint("SKIP LOCKED", num_indent + 3);
}
}
}
if (stmt->setOperations) {
for (SetOperation* setOperation : *stmt->setOperations) {
switch (setOperation->setType) {
case SetType::kSetIntersect:
inprint("Intersect:", num_indent + 1);
break;
case SetType::kSetUnion:
inprint("Union:", num_indent + 1);
break;
case SetType::kSetExcept:
inprint("Except:", num_indent + 1);
break;
}
printSelectStatementInfo(setOperation->nestedSelectStatement, num_indent + 2);
if (setOperation->resultOrder) {
inprint("SetResultOrderBy:", num_indent + 1);
printOrderBy(setOperation->resultOrder, num_indent + 2);
}
if (setOperation->resultLimit) {
if (setOperation->resultLimit->limit) {
inprint("SetResultLimit:", num_indent + 1);
printExpression(setOperation->resultLimit->limit, num_indent + 2);
}
if (setOperation->resultLimit->offset) {
inprint("SetResultOffset:", num_indent + 1);
printExpression(setOperation->resultLimit->offset, num_indent + 2);
}
}
}
}
if (stmt->order) {
inprint("OrderBy:", num_indent + 1);
printOrderBy(stmt->order, num_indent + 2);
}
if (stmt->limit && stmt->limit->limit) {
inprint("Limit:", num_indent + 1);
printExpression(stmt->limit->limit, num_indent + 2);
}
if (stmt->limit && stmt->limit->offset) {
inprint("Offset:", num_indent + 1);
printExpression(stmt->limit->offset, num_indent + 2);
}
}
void printImportStatementInfo(const ImportStatement* stmt, uintmax_t num_indent) {
inprint("ImportStatement", num_indent);
inprint(stmt->filePath, num_indent + 1);
switch (stmt->type) {
case ImportType::kImportCSV:
inprint("CSV", num_indent + 1);
break;
case ImportType::kImportTbl:
inprint("TBL", num_indent + 1);
break;
case ImportType::kImportBinary:
inprint("BINARY", num_indent + 1);
break;
case ImportType::kImportAuto:
inprint("AUTO", num_indent + 1);
break;
}
inprint(stmt->tableName, num_indent + 1);
if (stmt->whereClause) {
inprint("WHERE:", num_indent + 1);
printExpression(stmt->whereClause, num_indent + 2);
}
}
void printExportStatementInfo(const ExportStatement* stmt, uintmax_t num_indent) {
inprint("ExportStatement", num_indent);
inprint(stmt->filePath, num_indent + 1);
switch (stmt->type) {
case ImportType::kImportCSV:
inprint("CSV", num_indent + 1);
break;
case ImportType::kImportTbl:
inprint("TBL", num_indent + 1);
break;
case ImportType::kImportBinary:
inprint("BINARY", num_indent + 1);
break;
case ImportType::kImportAuto:
inprint("AUTO", num_indent + 1);
break;
}
if (stmt->tableName) {
inprint(stmt->tableName, num_indent + 1);
} else {
printSelectStatementInfo(stmt->select, num_indent + 1);
}
}
void printCreateStatementInfo(const CreateStatement* stmt, uintmax_t num_indent) {
inprint("CreateStatement", num_indent);
inprint(stmt->tableName, num_indent + 1);
if (stmt->filePath) inprint(stmt->filePath, num_indent + 1);
}
void printInsertStatementInfo(const InsertStatement* stmt, uintmax_t num_indent) {
inprint("InsertStatement", num_indent);
inprint(stmt->tableName, num_indent + 1);
if (stmt->columns) {
inprint("Columns", num_indent + 1);
for (char* col_name : *stmt->columns) {
inprint(col_name, num_indent + 2);
}
}
switch (stmt->type) {
case kInsertValues:
inprint("Values", num_indent + 1);
for (Expr* expr : *stmt->values) {
printExpression(expr, num_indent + 2);
}
break;
case kInsertSelect:
printSelectStatementInfo(stmt->select, num_indent + 1);
break;
}
}
void printTransactionStatementInfo(const TransactionStatement* stmt, uintmax_t num_indent) {
inprint("TransactionStatement", num_indent);
switch (stmt->command) {
case kBeginTransaction:
inprint("BEGIN", num_indent + 1);
break;
case kCommitTransaction:
inprint("COMMIT", num_indent + 1);
break;
case kRollbackTransaction:
inprint("ROLLBACK", num_indent + 1);
break;
}
}
void printStatementInfo(const SQLStatement* stmt) {
switch (stmt->type()) {
case kStmtSelect:
printSelectStatementInfo((const SelectStatement*)stmt, 0);
break;
case kStmtInsert:
printInsertStatementInfo((const InsertStatement*)stmt, 0);
break;
case kStmtCreate:
printCreateStatementInfo((const CreateStatement*)stmt, 0);
break;
case kStmtImport:
printImportStatementInfo((const ImportStatement*)stmt, 0);
break;
case kStmtExport:
printExportStatementInfo((const ExportStatement*)stmt, 0);
break;
case kStmtTransaction:
printTransactionStatementInfo((const TransactionStatement*)stmt, 0);
break;
default:
break;
}
}
std::ostream& operator<<(std::ostream& os, const OperatorType& op) {
static const std::map<const OperatorType, const std::string> operatorToToken = {
{kOpNone, "None"}, {kOpBetween, "BETWEEN"},
{kOpCase, "CASE"}, {kOpCaseListElement, "CASE LIST ELEMENT"},
{kOpPlus, "+"}, {kOpMinus, "-"},
{kOpAsterisk, "*"}, {kOpSlash, "/"},
{kOpPercentage, "%"}, {kOpCaret, "^"},
{kOpEquals, "="}, {kOpNotEquals, "!="},
{kOpLess, "<"}, {kOpLessEq, "<="},
{kOpGreater, ">"}, {kOpGreaterEq, ">="},
{kOpLike, "LIKE"}, {kOpNotLike, "NOT LIKE"},
{kOpILike, "ILIKE"}, {kOpAnd, "AND"},
{kOpOr, "OR"}, {kOpIn, "IN"},
{kOpConcat, "CONCAT"}, {kOpNot, "NOT"},
{kOpUnaryMinus, "-"}, {kOpIsNull, "IS NULL"},
{kOpExists, "EXISTS"}};
const auto found = operatorToToken.find(op);
if (found == operatorToToken.cend()) {
return os << static_cast<uint64_t>(op);
} else {
return os << (*found).second;
}
}
std::ostream& operator<<(std::ostream& os, const DatetimeField& datetime) {
static const std::map<const DatetimeField, const std::string> operatorToToken = {
{kDatetimeNone, "None"}, {kDatetimeSecond, "SECOND"}, {kDatetimeMinute, "MINUTE"}, {kDatetimeHour, "HOUR"},
{kDatetimeDay, "DAY"}, {kDatetimeMonth, "MONTH"}, {kDatetimeYear, "YEAR"}};
const auto found = operatorToToken.find(datetime);
if (found == operatorToToken.cend()) {
return os << static_cast<uint64_t>(datetime);
} else {
return os << (*found).second;
}
}
std::ostream& operator<<(std::ostream& os, const FrameBound& frame_bound) {
if (frame_bound.type == kCurrentRow) {
os << "CURRENT ROW";
return os;
}
if (frame_bound.unbounded) {
os << "UNBOUNDED";
} else {
os << frame_bound.offset;
}
os << " ";
if (frame_bound.type == kPreceding) {
os << "PRECEDING";
} else {
os << "FOLLOWING";
}
return os;
}
} // namespace hsql

View File

@@ -0,0 +1,41 @@
#ifndef SQLPARSER_SQLHELPER_H
#define SQLPARSER_SQLHELPER_H
#include "../sqlparser_win.h"
#include "../sql/statements.h"
namespace hsql {
// Prints a summary of the given SQLStatement.
void SQLParser_API printStatementInfo(const SQLStatement* stmt);
// Prints a summary of the given SelectStatement with the given indentation.
void SQLParser_API printSelectStatementInfo(const SelectStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given ImportStatement with the given indentation.
void SQLParser_API printImportStatementInfo(const ImportStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given CopyStatement with the given indentation.
void SQLParser_API printExportStatementInfo(const ExportStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given InsertStatement with the given indentation.
void SQLParser_API printInsertStatementInfo(const InsertStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given CreateStatement with the given indentation.
void SQLParser_API printCreateStatementInfo(const CreateStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given TransactionStatement with the given indentation.
void SQLParser_API printTransactionStatementInfo(const TransactionStatement* stmt, uintmax_t num_indent);
// Prints a summary of the given Expression with the given indentation.
void SQLParser_API printExpression(Expr* expr, uintmax_t num_indent);
// Prints an ORDER BY clause
void SQLParser_API printOrderBy(const std::vector<OrderDescription*>* expr, uintmax_t num_indent);
// Prints WindowDescription.
void SQLParser_API printWindowDescription(WindowDescription* window_description, uintmax_t num_indent);
} // namespace hsql
#endif