/* Copyright (C) 2014 InfiniDB, 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; version 2 of the License. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*********************************************************************** * $Id: dmlpkg.h 9210 2013-01-21 14:10:42Z rdempsey $ * * ***********************************************************************/ /** @file */ #pragma once #include #include #include #include #include #include #include #include #include "nullstring.h" namespace dmlpackage { class DeleteSqlStatement; class UpdateSqlStatement; class InsertSqlStatement; class SqlStatement; class SqlStatementList; class TableName; class ValuesOrQuery; class QuerySpec; class TableExpression; class WhereClause; class SearchCondition; class ExistanceTestPredicate; class AllOrAnyPredicate; class InPredicate; class NullTestPredicate; class LikePredicate; class BetweenPredicate; class ComparisonPredicate; class Predicate; class FromClause; class SelectFilter; class GroupByClause; class HavingClause; class Escape; class ColumnAssignment; typedef std::vector TableNameList; typedef std::vector ColumnAssignmentList; typedef std::vector ColumnNameList; typedef std::vector ValuesList; typedef std::vector AtomList; typedef std::vector QueryBuffer; typedef std::vector ColValuesList; typedef std::vector ColNameList; typedef std::map TableValuesMap; typedef std::bitset<4096> NullValuesBitset; std::ostream& operator<<(std::ostream& os, const SqlStatementList& ct); std::ostream& operator<<(std::ostream& os, const SqlStatement& stmt); /** @brief Predicate types */ enum PREDICATE_TYPE { COMPARE_PREDICATE, BETWEEN_PREDICATE, LIKE_PREDICATE, NULLTEST_PREDICATE, IN_PREDICATE, ALLORANY_PREDICATE, EXIST_PREDICATE, INVALID_PREDICATE }; /** @brief DML Statement types */ enum DML_TYPE { DML_INSERT, DML_UPDATE, DML_DELETE, DML_COMMAND, DML_INVALID_TYPE }; /** @brief SqlStatement represents a toplevel * syntactic element such as a insert, update or delete SQL * statement. * * SqlStatements are containers for the various structures * manufactured by the parsing process for a single SQL * statement. */ class SqlStatement { public: /** @brief ctor */ SqlStatement(); /** @brief dtor */ virtual ~SqlStatement(); /** @brief dump to stdout. */ virtual std::ostream& put(std::ostream& os) const = 0; /** @brief get the query string associated with the * SqlStatement */ virtual std::string getQueryString() const = 0; /** @brief get the statement type */ virtual int getStatementType() const = 0; /** @brief get the schema name from the * TableName data member */ virtual std::string getSchemaName() const; /** @brief get the table name from the * TableName data member */ virtual std::string getTableName() const; TableName* fNamePtr; }; /** @brief Collects SqlStatements so that we can support the * parsing of sqltext containing multiple statements. * * The SqlParser also accepts empty statements (a mixture of * whitespace and semicolons) in which case the result can be a * SqlStatementList of zero items. */ class SqlStatementList { public: /** @brief ctor */ SqlStatementList() = default; /** @brief dtor */ virtual ~SqlStatementList(); /** @brief get the SqlStatement at the given index * * @param i the index */ SqlStatement* operator[](int i) const { return fList[i]; } /** @brief push the supplied SqlStatement pointer onto the list * * @param v a pointer to a SqlStatement */ void push_back(SqlStatement* v); std::vector fList; std::string fSqlText; private: SqlStatementList(const SqlStatementList& x); }; /** @brief The representation of a parsed * INSERT statement * * insert_statement: * INSERT INTO table opt_column_commalist values_or_query_spec */ class InsertSqlStatement : public SqlStatement { public: /** @brief ctor */ InsertSqlStatement(); /** @brief ctor * * @param tableNamePtr pointer to a TableName object * @param valsOrQueryPtr pointer to a ValuesOrQueryObject */ InsertSqlStatement(TableName* tableNamePtr, ValuesOrQuery* valsOrQueryPtr); /** @brief ctor * * @param tableNamePtr pointer to a TableName object * @param columnNamesPtr pointer to ColumnNamesList object * @param valsOrQueryPtr pointer to ValuesOrQueryObject */ InsertSqlStatement(TableName* tableNamePtr, ColumnNameList* columnNamesPtr, ValuesOrQuery* valsOrQueryPtr); /** @brief dtor */ ~InsertSqlStatement() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get a string representation of the query spec */ std::string getQueryString() const override; /** @brief get the statement type - DML_INSERT */ inline int getStatementType() const override { return DML_INSERT; } ValuesOrQuery* fValuesOrQueryPtr; ColumnNameList fColumnList; }; /** @brief The representation of a parsed * UPDATE statement * * update_statement_searched: * UPDATE table SET assignment_commalist opt_where_clause */ class UpdateSqlStatement : public SqlStatement { public: /** @brief ctor */ UpdateSqlStatement(); /** @brief ctor * * @param tableNamePtr pointer to a TableName object * @param colAssignmentPtr pointer to a ColumnAssignmentList object * @param whereClausePtr pointer to a WhereClause object - default 0 */ UpdateSqlStatement(TableName* tableNamePtr, ColumnAssignmentList* colAssignmentListPtr, WhereClause* whereClausePtr = nullptr); /** @brief dtor */ ~UpdateSqlStatement() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the * SET assignment_commalist opt_where_clause * statement */ std::string getQueryString() const override; /** @brief get the statement type - DML_UPDATE */ inline int getStatementType() const override { return DML_UPDATE; } ColumnAssignmentList* fColAssignmentListPtr; WhereClause* fWhereClausePtr; }; /** @brief The representation of a parsed * DELETE statement * * delete_statement_searched: * DELETE FROM table opt_where_clause */ class DeleteSqlStatement : public SqlStatement { public: /** @brief ctor */ DeleteSqlStatement(); /** @brief ctor * * @param tableNamePtr pointer to a TableName object * @param whereClausePtr pointer to a WhereClause object - default = 0 */ explicit DeleteSqlStatement(TableName* tableNamePtr, WhereClause* whereClausePtr = nullptr); /** @brief dtor */ ~DeleteSqlStatement() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the WHERE clause */ std::string getQueryString() const override; /** @brief get the statement type - DML_DELETE */ inline int getStatementType() const override { return DML_DELETE; } WhereClause* fWhereClausePtr; }; /** @brief The representation of a parsed * COMMIT or ROLLBACK statement * * commit_statement: * COMMIT WORK * | COMMIT * * rollback_statement: * ROLLBACK WORK `* | ROLLBACK */ class CommandSqlStatement : public SqlStatement { public: /** @brief ctor * * @param command the COMMIT or ROLLBACK string */ explicit CommandSqlStatement(std::string command); /** @brief get the statement type - DML_COMMAND */ inline int getStatementType() const override { return DML_COMMAND; } /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the COMMIT or ROLLBACK string */ std::string getQueryString() const override; std::string fCommandText; }; /** @brief Stores schema, object names. * */ class TableName { public: /** @brief ctor */ TableName(); /** @brief ctor * * @param name the table name */ explicit TableName(char* name); /** @brief ctor * * @param schema the schema name * @param name the table name */ TableName(char* shema, char* name); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; std::string fName; std::string fSchema; }; /** @brief Stores a column assignment * * assignment: * column '=' scalar_exp * | column '=' NULLX */ class ColumnAssignment { public: explicit ColumnAssignment(std::string column, std::string op = "=", std::string expr = "") : fColumn(std::move(column)) , fOperator(std::move(op)) , fScalarExpression(std::move(expr)) , fFromCol(false) , fFuncScale(0) , fIsNull(false){}; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of * the column assignment */ std::string getColumnAssignmentString() const; std::string fColumn; std::string fOperator; std::string fScalarExpression; bool fFromCol; uint32_t fFuncScale; bool fIsNull; }; /** @brief Stores a value list or a query specification * * values_or_query_spec: * VALUES '(' insert_atom_commalist ')' * | query_spec */ class ValuesOrQuery { public: /** @brief ctor */ ValuesOrQuery(); /** @brief ctor * * @param valuesPtr pointer to a ValuesList object */ explicit ValuesOrQuery(ValuesList* valuesPtr); /** @brief ctor * * @param querySpecPtr pointer to a QuerySpec object */ explicit ValuesOrQuery(QuerySpec* querySpecPtr); /** @brief dtor */ ~ValuesOrQuery(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string reperesentation of * the ValuesList or the QuerySpec */ std::string getQueryString() const; ValuesList fValuesList; QuerySpec* fQuerySpecPtr; }; /** @brief Stores a SELECT filter * * selection: * scalar_exp_commalist * | '*' */ class SelectFilter { public: /** @brief ctor */ SelectFilter(); /** @brief ctor * * @param columnListPtr pointer to a ColumnNameList object */ explicit SelectFilter(ColumnNameList* columnListPtr); /** @brief dtor */ ~SelectFilter(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string represntation of the SELECT statement */ std::string getSelectString() const; ColumnNameList fColumnList; }; /** @brief Stores a FROM clause * * from_clause: * FROM table_ref_commalist */ class FromClause { public: /** @brief ctor */ FromClause(); /** @brief ctor * * @param tableNameList pointer to a TableNameList object */ explicit FromClause(TableNameList* tableNameList); /** @brief dtor */ ~FromClause(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the FROM clause */ std::string getFromClauseString() const; TableNameList* fTableListPtr; }; /** @brief Stores a WHERE clause * * where_clause: * WHERE search_condition */ class WhereClause { public: /** @brief ctor */ WhereClause(); /** @brief dtor */ ~WhereClause(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the WHERE clause */ std::string getWhereClauseString() const; SearchCondition* fSearchConditionPtr; }; /** @brief Stores a GROUP BY clause * * opt_group_by_clause: * empty * | GROUP BY column_ref_commalist */ class GroupByClause { public: /** @brief ctor */ GroupByClause(); /** @brief dtor */ ~GroupByClause(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the GROUP BY clause */ std::string getGroupByClauseString() const; ColumnNameList* fColumnNamesListPtr; }; /** @brief Stores a HAVING clause * * opt_having_clause: * empty * | HAVING search_condition */ class HavingClause { public: /** @brief ctor */ HavingClause(); /** @brief dtor */ ~HavingClause(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the HAVING clause */ std::string getHavingClauseString() const; SearchCondition* fSearchConditionPtr; }; /** @brief Stores an ESCAPE sequence * * * opt_escape: * empty * | ESCAPE atom */ class Escape { public: /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; std::string fEscapeChar; }; /** @brief The base class representaion of a parsed SQL predicate * * predicate: * comparison_predicate * | between_predicate * | like_predicate * | test_for_null * | in_predicate * | all_or_any_predicate * | existence_test */ class Predicate { public: /** @brief ctor */ Predicate(); /** @brief ctor * * @param predicateType the PREDICATE_TYPE */ explicit Predicate(PREDICATE_TYPE predicateType); /** @brief dtor */ virtual ~Predicate(); /** @brief dump to stdout */ virtual std::ostream& put(std::ostream& os) const; /** @param get the string representation of the predicate */ virtual std::string getPredicateString() const; PREDICATE_TYPE fPredicateType; }; /** @brief The representation of a parsed * Comparison Predicate: * * comparison_predicate: * scalar_exp COMPARISON scalar_exp * | scalar_exp COMPARISON subquery */ class ComparisonPredicate : public Predicate { public: /** @brief ctor */ ComparisonPredicate(); /** @brief dtor */ ~ComparisonPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the COMPARISON * predicate */ std::string getPredicateString() const override; std::string fLHScalarExpression; std::string fRHScalarExpression; std::string fOperator; QuerySpec* fSubQuerySpec; }; /** @brief The representation of a parsed * Between Predicate: * * between_predicate: * scalar_exp NOT BETWEEN scalar_exp AND scalar_exp * | scalar_exp BETWEEN scalar_exp AND scalar_exp */ class BetweenPredicate : public Predicate { public: /** @brief ctor */ BetweenPredicate(); /** @brief dtor */ ~BetweenPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the BETWEEN * predicate */ std::string getPredicateString() const override; std::string fLHScalarExpression; std::string fRH1ScalarExpression; std::string fRH2ScalarExpression; std::string fOperator1; std::string fOperator2; }; /** @brief The representation of a parsed * Like Predicate: * * like_predicate: * scalar_exp NOT LIKE atom opt_escape * | scalar_exp LIKE atom opt_escape */ class LikePredicate : public Predicate { public: /** @brief ctor */ LikePredicate(); /** @brief dtor */ ~LikePredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the LIKE * predicate */ std::string getPredicateString() const override; std::string fLHScalarExpression; std::string fAtom; std::string fOperator; Escape* fOptionalEscapePtr; }; /** @brief The representation of a parsed * Null test Predicate: * * test_for_null: * column_ref IS NOT NULLX * | column_ref IS NULLX */ class NullTestPredicate : public Predicate { public: /** @brief ctor */ NullTestPredicate(); /** @brief dtor */ ~NullTestPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the NULL test * predicate */ std::string getPredicateString() const override; std::string fColumnRef; std::string fOperator; }; /** @brief The representation of a parsed * In Predicate: * * in_predicate: * scalar_exp NOT IN '(' subquery ')' * | scalar_exp IN '(' subquery ')' * | scalar_exp NOT IN '(' atom_commalist ')' * | scalar_exp IN '(' atom_commalist ')' */ class InPredicate : public Predicate { public: /** @brief ctor */ InPredicate(); /** @brief dtor */ ~InPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the IN * predicate */ std::string getPredicateString() const override; std::string fScalarExpression; std::string fOperator; AtomList fAtomList; QuerySpec* fSubQuerySpecPtr; }; /** @brief The representation of a parsed * All Or Any Predicate: * * all_or_any_predicate: * scalar_exp COMPARISON any_all_some subquery */ class AllOrAnyPredicate : public Predicate { public: /** @brief ctor */ AllOrAnyPredicate(); /** @brief dtor */ ~AllOrAnyPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the * ALL or ANY predicate */ std::string getPredicateString() const override; std::string fScalarExpression; std::string fOperator; std::string fAnyAllSome; QuerySpec* fSubQuerySpecPtr; }; /** @brief The representation of a parsed * Existance test Predicate: * * existence_test: * EXISTS subquery */ class ExistanceTestPredicate : public Predicate { public: /** @brief ctor */ ExistanceTestPredicate(); /** @brief dtor */ ~ExistanceTestPredicate() override; /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const override; /** @brief get the string representation of the EXISTS * predicate */ std::string getPredicateString() const override; QuerySpec* fSubQuerySpecPtr; }; /** @brief The representation of a parsed * Search Condition: * * search_condition: * | search_condition OR search_condition * | search_condition AND search_condition * | NOT search_condition * | '(' search_condition ')' * | predicate */ class SearchCondition { public: /** @brief ctor */ SearchCondition(); /** @brief dtor */ ~SearchCondition(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the striong representation of the * search condition */ std::string getSearchConditionString() const; Predicate* fPredicatePtr; SearchCondition* fLHSearchConditionPtr; SearchCondition* fRHSearchConditionPtr; std::string fOperator; }; /** @brief The representation of a parsed * Table Expression: * * table_exp: * from_clause * opt_where_clause * opt_group_by_clause * opt_having_clause */ class TableExpression { public: /** @brief ctor */ TableExpression(); /** @brief ctor * * @param fromClausePtr pointer to a FromClause object * @param whereClausePtr pointer to a WhereClause object * @param groupByPtr pointer to a GroupByClause object * @param havingPtr pointer to a HavingClause object */ TableExpression(FromClause* fromClausePtr, WhereClause* whereClausePtr, GroupByClause* groupByPtr, HavingClause* havingPtr); /** @brief dtor */ ~TableExpression(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the * table expression */ std::string getTableExpressionString() const; FromClause* fFromClausePtr; WhereClause* fWhereClausePtr; GroupByClause* fGroupByPtr; HavingClause* fHavingPtr; }; /** @brief The representation of a parsed * Query Specification: * * query_spec: * SELECT opt_all_distinct selection table_exp */ class QuerySpec { public: /** @brief ctor */ QuerySpec(); /** @brief ctor * * @param selectFilter pointer to a SelectFilter object * @param tableExpression pointer to a TableExpression object */ QuerySpec(SelectFilter* selectFilter, TableExpression* tableExpression); /** @brief ctor * * @param selectFilter pointer to a SelectFilter object * @param tableExpression pointer to a TableExpression object * @param allOrDistinct pointer to a ALL or DISTINCT string */ QuerySpec(SelectFilter* selectFilter, TableExpression* tableExpression, char* allOrDistinct); /** @brief dtor */ ~QuerySpec(); /** @brief dump to stdout */ std::ostream& put(std::ostream& os) const; /** @brief get the string representation of the * query specification */ std::string getQueryString() const; SelectFilter* fSelectFilterPtr; TableExpression* fTableExpressionPtr; std::string fOptionAllOrDistinct; }; } // namespace dmlpackage