/* 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: ddlpkg.h 9210 2013-01-21 14:10:42Z rdempsey $ * * ***********************************************************************/ /** @file * * Class definitions for ddl parser objects. These are the things * manufactured by the bison SQL parser. SqlStatementList is the * toplevel parser result. * * Parser objects are described as structs. These objects never * change state following construction. An accessor/mutator * discipline would amount to clutter. * * The constructor forms here are directly driven by the structure of * the grammar in ddl.y. * */ #pragma once #include #include #include #include #include #include #include "bytestream.h" #include "logicalpartition.h" #define EXPORT namespace ddlpackage { typedef messageqcpp::ByteStream::byte byte; typedef messageqcpp::ByteStream::doublebyte doublebyte; typedef messageqcpp::ByteStream::quadbyte quadbyte; class AlterTable; struct AlterTableAction; struct ColumnDef; struct ColumnDefaultValue; struct ColumnType; struct QualifiedName; struct CreateTableStatement; struct SqlStatementList; struct SqlStatement; struct ColumnConstraintDef; struct TableConstraintDef; struct SchemaObject; struct ReferentialAction; struct TableDef; typedef SqlStatement DDLPkg; typedef std::vector ColumnConstraintList; typedef std::vector SchemaObjectList; typedef std::vector ColumnNameList; typedef std::vector AlterTableActionList; typedef std::vector ColumnDefList; typedef std::map TableOptionMap; typedef std::vector TableElementList; typedef std::vector TableConstraintDefList; std::ostream& operator<<(std::ostream& os, const ColumnType& columnType); std::ostream& operator<<(std::ostream& os, const QualifiedName& constraint); std::ostream& operator<<(std::ostream& os, const TableConstraintDef& constraint); std::ostream& operator<<(std::ostream& os, const ColumnConstraintDef& con); std::ostream& operator<<(std::ostream& os, const ColumnDef& column); EXPORT std::ostream& operator<<(std::ostream& os, const SqlStatementList& ct); EXPORT std::ostream& operator<<(std::ostream& os, const SqlStatement& stmt); std::ostream& operator<<(std::ostream& os, const ColumnDefList& columnList); std::ostream& operator<<(std::ostream& os, const AlterTableAction& columnList); std::ostream& operator<<(std::ostream& os, const ColumnDefaultValue& defaultValue); std::ostream& operator<<(std::ostream& os, const ColumnNameList& columnNames); std::ostream& operator<<(std::ostream& os, const ReferentialAction& ref); std::ostream& operator<<(std::ostream& os, const TableDef& tableDef); /** @brief Verb List * Make sure to keep the enum and string list in-sync */ enum DDL_VERBS { DDL_CREATE, DDL_ALTER, DDL_DROP, DDL_INVALID_VERB }; /** @brief Subject List * Make sure to keep the enum and string list in-sync */ enum DDL_SUBJECTS { DDL_TABLE, DDL_INDEX, DDL_INVALID_SUBJECT }; enum DDL_CONSTRAINT_ATTRIBUTES { DDL_DEFERRABLE, DDL_NON_DEFERRABLE, DDL_INITIALLY_IMMEDIATE, DDL_INITIALLY_DEFERRED, DDL_INVALID_ATTRIBUTE }; const std::string ConstraintAttrStrings[] = {"deferrable", "non-deferrable", "initially-immediate", "initially-deferred", "invalid"}; enum DDL_REFERENTIAL_ACTION { DDL_CASCADE, DDL_SET_NULL, DDL_SET_DEFAULT, DDL_NO_ACTION, DDL_RESTRICT, DDL_INVALID_REFERENTIAL_ACTION }; const std::string ReferentialActionStrings[] = {"cascade", "set_null", "set_default", "no_action", "invalid_action"}; enum DDL_MATCH_TYPE { DDL_FULL, DDL_PARTIAL, DDL_INVALID_MATCH_TYPE }; const std::string MatchTypeStrings[] = {"full", "partial", "invalid_match_type"}; /** @brief Constraint List * Make sure to keep the enum and string list in-sync */ enum DDL_CONSTRAINTS { DDL_PRIMARY_KEY, DDL_FOREIGN_KEY, DDL_CHECK, DDL_UNIQUE, DDL_REFERENCES, DDL_NOT_NULL, DDL_AUTO_INCREMENT, DDL_INVALID_CONSTRAINT }; /** @brief */ const std::string ConstraintString[] = {"primary", "foreign", "check", "unique", "references", "not_null", "auto_increment" ""}; /** @brief Datatype List * Make sure to keep the enum, string, and length list in-sync */ enum DDL_DATATYPES { DDL_BIT, DDL_TINYINT, DDL_CHAR, DDL_SMALLINT, DDL_DECIMAL, DDL_MEDINT, DDL_INT, DDL_FLOAT, DDL_DATE, DDL_BIGINT, DDL_DOUBLE, DDL_DATETIME, DDL_VARCHAR, DDL_VARBINARY, DDL_CLOB, DDL_BLOB, DDL_REAL, DDL_NUMERIC, DDL_NUMBER, DDL_INTEGER, DDL_UNSIGNED_TINYINT, DDL_UNSIGNED_SMALLINT, DDL_UNSIGNED_MEDINT, DDL_UNSIGNED_INT, DDL_UNSIGNED_BIGINT, DDL_UNSIGNED_DECIMAL, DDL_UNSIGNED_FLOAT, DDL_UNSIGNED_DOUBLE, DDL_UNSIGNED_NUMERIC, DDL_TEXT, DDL_TIME, DDL_TIMESTAMP, DDL_INVALID_DATATYPE }; /** @brief Datatype string list */ const std::string DDLDatatypeString[] = {"bit", "tinyint", "char", "smallint", "decimal", "medint", "integer", "float", "date", "bigint", "double", "datetime", "varchar", "varbinary", "clob", "blob", "real", "numeric", "number", "integer", "unsigned-tinyint", "unsigned-smallint", "unsigned-medint", "unsigned-int", "unsigned-bigint", "unsigned-decimal", "unsigned-float", "unsigned-double", "unsigned-numeric", "text", "time", "timestamp", ""}; /** @brief Alter table action string list */ const std::string AlterActionString[] = { "AtaAddColumn", "AtaAddColumns", "AtaDropColumn", "AtaDropColumns", "AtaAddTableConstraint", "AtaSetColumnDefault", "AtaDropColumnDefault", "AtaDropTableConstraint", "AtaRenameTable", "AtaModifyColumnType", "AtaRenameColumn", "AtaTableComment"}; /** @brief Datatype Length list * */ const int DDLDatatypeLength[] = { 1, // BIT 1, // TINYINT 1, // CHAR 2, // SMALLINT 2, // DECIMAL 4, // MEDINT 4, // INT 4, // FLOAT 4, // DATE 8, // BIGINT 8, // DOUBLE 8, // DATETIME 8, // VARCHAR 8, // VARBINAR 8, // CLOB 8, // BLOB 4, // REAL 2, // NUMERIC 4, // NUMBER 4, // INTEGER 1, // UNSIGNED_TINYINT, 2, // UNSIGNED_SMALLINT, 4, // UNSIGNED_MEDINT, 4, // UNSIGNED_INT, 8, // UNSIGNED_BIGINT, 2, // UNSIGNED_DECIMAL, 4, // UNSIGNED_FLOAT, 8, // UNSIGNED_DOUBLE, 2, // UNSIGNED_NUMERIC, 8, // TEXT 8, // TIME 8, // TIMESTAMP -1 // INVALID LENGTH }; enum DDL_SERIAL_TYPE { DDL_TABLE_DEF, DDL_COLUMN_DEF, DDL_COLUMN_CONSTRAINT_DEF, DDL_TABLE_CONSTRAINT_DEF, DDL_SQL_STATEMENT_LIST, DDL_CREATE_TABLE_STATEMENT, DDL_CREATE_INDEX, DDL_ALTER_TABLE_STATEMENT, DDL_ATA_ADD_COLUMN, DDL_ATA_ADD_COLUMNS, DDL_ATA_DROP_COLUMN, DDL_ATA_ADD_TABLE_CONSTRAINT, DDL_ATA_SET_COLUMN_DEFAULT, DDL_ATA_DROP_COLUMN_DEFAULT, DDL_ATA_DROP_TABLE_CONSTRAINT, DDL_ATA_RENAME_TABLE, DDL_ATA_RENAME_COLUMN, DDL_ATA_MODIFY_COLUMN_TYPE, DDL_ATA_TABLE_COMMENT, DDL_COLUMN_TYPE, DDL_COLUMN_DEFAULT_VALUE, DDL_TABLE_UNIQUE_CONSTRAINT_DEF, DDL_TABLE_PRIMARY_CONSTRAINT_DEF, DDL_REF_ACTION, DDL_TABLE_REFERENCES_CONSTRAINT_DEF, DDL_TABLE_CHECK_CONSTRAINT_DEF, DDL_QUALIFIED_NAME, DDL_CONSTRAINT_ATTRIBUTES_DEF, DDL_DROP_INDEX_STATEMENT, DDL_DROP_TABLE_STATEMENT, DDL_ATA_DROP_COLUMNS, DDL_NULL, DDL_INVALID_SERIAL_TYPE, DDL_TRUNC_TABLE_STATEMENT, DDL_MARK_PARTITION_STATEMENT, DDL_RESTORE_PARTITION_STATEMENT, DDL_DROP_PARTITION_STATEMENT, DDL_DEBUG_STATEMENT }; /** @brief An abstract base for TableDef, ColumnDef, ... * * The primary purpose of this class is to provide a unified type * for things that can appear together in syntactic elements. For * example, column definitions and table constraints can appear * together in the table_element_list of a create table statement. * We need a base class so that we can return different concrete * types as the semantic value of bison rules, while having a * single, more abstract type to report to bison as the type of * the semantic value. */ struct SchemaObject { virtual ~SchemaObject() = default; explicit SchemaObject(std::string name) : fName(name) { } SchemaObject() : fName("unnamed") { } std::string fName; }; /** @brief SqlStatement represents a toplevel * syntactic element such as a create table or alter table SQL * statement. * * SqlStatements are containers for the various structures * manufactured by the parsing process for a single SQL * statement. */ struct SqlStatement { /** @brief Deserialize from ByteStream */ virtual int unserialize(messageqcpp::ByteStream& bs) = 0; /** @brief Serialize to ByteStream */ virtual int serialize(messageqcpp::ByteStream& bs) = 0; /** @brief Dump to stdout. */ virtual std::ostream& put(std::ostream& os) const = 0; EXPORT SqlStatement(); EXPORT virtual ~SqlStatement(); /** @brief The session ID assigned to this stmt by the front end (in theory) * * XXXPAT: need to fix this. It should be type execplan::SessionManager::SID, but * that causes a circular dependency in the header files. Should unravel that at * some point. * * Right now this var is initialized from a counter. At some point we need * to serialize/unserialize it from a byte stream. */ uint32_t fSessionID; /** @brief The original sql string */ std::string fSql; /** @brief the default schema (owner that will be used when not specified) */ std::string fOwner; uint32_t fTableWithAutoi; // has autoincrement column? }; /** @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. */ struct SqlStatementList { SqlStatementList() = default; SqlStatement* operator[](int i) const { return fList[i]; } virtual ~SqlStatementList(); /** @brief Add a statement to the underlying container. */ void push_back(SqlStatement* v); std::vector fList; std::string fSqlText; private: SqlStatementList(const SqlStatementList& x); }; /** @brief Stores catalog, schema, object names. * * ddl.y does not yet support catalog. So, expect catalog * qualified names to fail parsing for the moment. */ struct QualifiedName { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs); QualifiedName() = default; EXPORT explicit QualifiedName(const char* name); EXPORT QualifiedName(const char* name, const char* schema); EXPORT QualifiedName(const char* name, const char* schema, const char* catalog); virtual ~QualifiedName() = default; std::string fCatalog; std::string fName; std::string fSchema; }; /** TableDef represents a table definition. */ struct TableDef : public SchemaObject { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs); TableDef() : fQualifiedName(nullptr) { } EXPORT TableDef(QualifiedName* name, TableElementList* elements, TableOptionMap* options); /** @brief TableDef ctor. * ctor */ TableDef(QualifiedName* name, ColumnDefList columns, TableConstraintDefList constraints, int /*tableWithAutoinc*/) : fQualifiedName(name), fColumns(columns), fConstraints(constraints) { } EXPORT ~TableDef() override; QualifiedName* fQualifiedName; ColumnDefList fColumns; TableConstraintDefList fConstraints; TableOptionMap fOptions; }; /** @brief Represents the create table statement * * @note It takes possession of the TableDef given to it. */ struct CreateTableStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ EXPORT CreateTableStatement(); /** @brief You can't have a CreateTableStatement without a table defintion */ EXPORT explicit CreateTableStatement(TableDef* tableDef); EXPORT ~CreateTableStatement() override; /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; std::string schemaName() const { if (!fTableDef || !fTableDef->fQualifiedName) return "UNKNOWN"; return fTableDef->fQualifiedName->fSchema; } TableDef* fTableDef; ///< The table defintion. }; /** * @brief The subforms of alter table are represented as * subclasses of AlterTableAction * * SQL-92 specifies that an alter_table_statement has exactly one * alter_table_action. But many vendors support aggregating * alter_table_actions under one alter_table_statement. We * support that. The subforms of alter table are represented as * subclasses of AlterTableAction, all of which are named * according to the convention AtaFoo, where Ata stands for * AlterTableAction. */ struct AlterTableAction { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs) = 0; /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs) = 0; /** @brief Ctor for deserialization */ AlterTableAction() = default; virtual ~AlterTableAction() = default; /** @brief QualifiedName of the focal table for this statement. */ // QualifiedName *fTableName; /** @brief Dump to stdout. */ EXPORT virtual std::ostream& put(std::ostream& os) const; }; /** @brief Represents alter table add column forms. */ struct AtaAddColumn : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaAddColumn() : fColumnDef(nullptr) { } /** @brief You can't add a column without specifying a column definition. */ explicit AtaAddColumn(ColumnDef* columnDef); ~AtaAddColumn() override; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; /** @brief The focal column definition. */ ColumnDef* fColumnDef; }; /** @brief Represents the table_element_list style of add column which is not part of SQL-92. */ struct AtaAddColumns : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaAddColumns() = default; explicit AtaAddColumns(TableElementList* tableElements); ~AtaAddColumns() override; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ColumnDefList fColumns; }; /** @brief Represents the table_element_list style of drop column which is not part of SQL-92. */ struct AtaDropColumns : public AlterTableAction { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaDropColumns() = default; EXPORT explicit AtaDropColumns(ColumnNameList* tableElements); EXPORT ~AtaDropColumns() override; /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ColumnNameList fColumns; }; /** AtaAddTableConstraint */ struct AtaAddTableConstraint : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaAddTableConstraint() : fTableConstraint(nullptr) { } explicit AtaAddTableConstraint(TableConstraintDef* tableConstraint); ~AtaAddTableConstraint() override; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; TableConstraintDef* fTableConstraint; }; /** @brief alter table drop column. */ struct AtaDropColumn : public AlterTableAction { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaDropColumn() = default; /** @brief Ctor for parser construction */ EXPORT AtaDropColumn(std::string columnName, DDL_REFERENTIAL_ACTION dropBehavior); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~AtaDropColumn() override = default; std::string fColumnName; DDL_REFERENTIAL_ACTION fDropBehavior; }; /** @brief alter table set column default */ struct AtaSetColumnDefault : AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; AtaSetColumnDefault() : fDefaultValue(nullptr) { } /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaSetColumnDefault() override; AtaSetColumnDefault(const char* colName, ColumnDefaultValue* defaultValue); std::string fColumnName; ColumnDefaultValue* fDefaultValue; }; /** @brief alter table drop column default. */ struct AtaDropColumnDefault : AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaDropColumnDefault() = default; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaDropColumnDefault() override = default; /** @brief Ctor for parser construction */ explicit AtaDropColumnDefault(const char* colName); std::string fColumnName; }; /** @brief alter table drop table constraint. */ struct AtaDropTableConstraint : AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaDropTableConstraint() = default; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaDropTableConstraint() override = default; AtaDropTableConstraint(const char* constraintName, DDL_REFERENTIAL_ACTION dropBehavior); std::string fConstraintName; DDL_REFERENTIAL_ACTION fDropBehavior; }; /** alter table rename */ struct AtaRenameTable : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaRenameTable() : fQualifiedName(nullptr) { } explicit AtaRenameTable(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaRenameTable() override; QualifiedName* fQualifiedName; }; /** alter table comment */ struct AtaTableComment : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaTableComment() : fTableComment("") { } explicit AtaTableComment(const char* tableComment); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaTableComment() override; std::string fTableComment; }; /** @brief alter table modify column */ struct AtaModifyColumnType : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaModifyColumnType() : fColumnType(nullptr) { } /** @brief Ctor for parser construction */ AtaModifyColumnType(const char* name, ColumnType* columnType) : fColumnType(columnType), fName(name) { } explicit AtaModifyColumnType(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaModifyColumnType() override; ColumnType* fColumnType; std::string fName; }; /** @brief alter table rename column */ struct AtaRenameColumn : public AlterTableAction { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ AtaRenameColumn() : fNewType(nullptr), fDefaultValue(nullptr) { } AtaRenameColumn(const char* name, const char* newName, ColumnType* newType, const char* comment = nullptr) : fName(name), fNewName(newName), fNewType(newType) { if (comment) fComment = comment; fDefaultValue = nullptr; } AtaRenameColumn(const char* name, const char* newName, ColumnType* newType, ColumnConstraintList* constraint_list, ColumnDefaultValue* defaultValue, const char* comment = nullptr) : fName(name), fNewName(newName), fNewType(newType), fDefaultValue(defaultValue) { if (constraint_list) fConstraints = *constraint_list; // if (defaultValue) //{ // fDefaultValue = defaultValue; //} if (comment) fComment = comment; } explicit AtaRenameColumn(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~AtaRenameColumn() override; std::string fName; ///< current column name std::string fNewName; ///< new column name ColumnType* fNewType; /** @brief Zero or more constraints. */ ColumnConstraintList fConstraints; /** @brief NULL if there was no DEFAULT clause */ ColumnDefaultValue* fDefaultValue; std::string fComment; }; /** @brief Stores the type information for a column. */ struct ColumnType { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs); /** @brief For deserialization. */ ColumnType() : fCharset(nullptr), fCollate(nullptr), fCharsetNum(0), fExplicitLength(false) { } friend std::ostream& operator<<(std::ostream& os, const ColumnType& ac); /** @brief This constructor is used by the parser to construct the ColumnType when a precision/scale clause is encountered. */ EXPORT ColumnType(int prec, int scale); /** @brief Used in cases where we don't need to create an object until we have seen all it's parts. */ EXPORT ColumnType(int type); virtual ~ColumnType() = default; /** @brief Type code from DDL_DATATYPES */ int fType; /** @brief Length of datatype in bytes */ long fLength; /** @brief SQL precision. This is the number of digits in the representation. */ int fPrecision; /** @brief SQL scale. This is is the number of digits to the right of the decimal point. */ int fScale; /** @brief SQL "with timezone" specifier */ bool fWithTimezone; int fCompressiontype; std::string fAutoincrement; uint64_t fNextvalue; /** @brief Column charset (CHAR, VARCHAR and TEXT only) */ const char* fCharset; /** @brief Column collation (CHAR, VARCHAR and TEXT only) */ const char* fCollate; /** @brief Column charset number (CHAR, VARCHAR and TEXT only) */ uint32_t fCharsetNum; /** @brief Is the TEXT column has explicit defined length, ie TEXT(1717) */ bool fExplicitLength; }; /** @brief A column constraint definition. * * Since we aren't supporting references constraint specifications * for columns, it seemed simpler to use a single column * constraint class instead of articulating the varieties among * several classes like we do with table constraints. */ struct ColumnConstraintDef : public SchemaObject { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs); ColumnConstraintDef() = default; /** @brief Constructs as check constraint. */ EXPORT explicit ColumnConstraintDef(const char* check); /** @brief Constructs as other constraint. */ EXPORT explicit ColumnConstraintDef(DDL_CONSTRAINTS type); ~ColumnConstraintDef() override = default; /** @brief Whether deferrable. */ bool fDeferrable; /** @brief Immediate or defferred */ DDL_CONSTRAINT_ATTRIBUTES fCheckTime; /** @brief Distinguish kinds of constraints */ DDL_CONSTRAINTS fConstraintType; /** @brief Stores foo from check(foo) */ std::string fCheck; }; /** @brief Represents a columns default value. */ struct ColumnDefaultValue { /** @brief Deserialize from ByteStream */ virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ virtual int serialize(messageqcpp::ByteStream& bs); ColumnDefaultValue() = default; explicit ColumnDefaultValue(const char* value); virtual ~ColumnDefaultValue() = default; /** @brief Is NULL the default value? */ bool fNull; /** @brief Specified default value as a string. */ std::string fValue; }; /** @brief Represents a column definition. */ struct ColumnDef : public SchemaObject { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs); /** @brief For deserialization. */ ColumnDef() : fType(nullptr) { } EXPORT ~ColumnDef() override; /** @brief Parser ctor. */ EXPORT ColumnDef(const char* name, ColumnType* type, ColumnConstraintList* constraint_list, ColumnDefaultValue* defaultValue, const char* comment = nullptr); /** @brief ColumnDef ctor. * ctor */ ColumnDef(const char* name, ColumnType* type, ColumnConstraintList constraints, ColumnDefaultValue* defaultValue = nullptr, const char* /*comment*/ = nullptr) : SchemaObject(name), fType(type), fConstraints(constraints), fDefaultValue(defaultValue) { } void convertDecimal(); /** @brief Never NULL since all Columns must have a type. */ ColumnType* fType; /** @brief Zero or more constraints. */ ColumnConstraintList fConstraints; /** @brief NULL if there was no DEFAULT clause */ ColumnDefaultValue* fDefaultValue; std::string fComment; }; /** @brief Abstract base for table constraint definitions. */ struct TableConstraintDef : public SchemaObject { /** @brief Return DDL_SERIAL code */ virtual DDL_SERIAL_TYPE getSerialType() = 0; /** @brief Deserialize from ByteStream */ virtual int unserialize(messageqcpp::ByteStream& bs) = 0; /** @brief Serialize to ByteStream */ virtual int serialize(messageqcpp::ByteStream& bs) = 0; TableConstraintDef(); explicit TableConstraintDef(DDL_CONSTRAINTS cType); /** @brief Dump to stdout. */ virtual std::ostream& put(std::ostream& os) const; ~TableConstraintDef() override = default; // std::string fName; DDL_CONSTRAINTS fConstraintType; }; /** @brief Unique table constraint. */ struct TableUniqueConstraintDef : public TableConstraintDef { /** @brief Return DDL_SERIAL code */ DDL_SERIAL_TYPE getSerialType() override { return DDL_TABLE_UNIQUE_CONSTRAINT_DEF; } /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; TableUniqueConstraintDef() : TableConstraintDef(DDL_UNIQUE) { } explicit TableUniqueConstraintDef(ColumnNameList* columns); ~TableUniqueConstraintDef() override = default; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ColumnNameList fColumnNameList; }; /** @brief Primary key table constraint. */ struct TablePrimaryKeyConstraintDef : public TableConstraintDef { /** @brief Return DDL_SERIAL code */ DDL_SERIAL_TYPE getSerialType() override { return DDL_TABLE_PRIMARY_CONSTRAINT_DEF; } /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; TablePrimaryKeyConstraintDef() : TableConstraintDef(DDL_PRIMARY_KEY) { } EXPORT explicit TablePrimaryKeyConstraintDef(ColumnNameList* columns); ~TablePrimaryKeyConstraintDef() override = default; /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ColumnNameList fColumnNameList; }; /** @brief ReferentialAction specifies what to do about table relationships when elements are updated and deleted. */ struct ReferentialAction { virtual ~ReferentialAction() = default; /** @brief Deserialize from ByteStream */ virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ virtual int serialize(messageqcpp::ByteStream& bs); DDL_REFERENTIAL_ACTION fOnUpdate; DDL_REFERENTIAL_ACTION fOnDelete; }; /** @brief TableReferencesConstraintDef represents a foreign key constraint. */ struct TableReferencesConstraintDef : public TableConstraintDef { /** @brief Return DDL_SERIAL code */ DDL_SERIAL_TYPE getSerialType() override { return DDL_TABLE_REFERENCES_CONSTRAINT_DEF; } /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; TableReferencesConstraintDef() : TableConstraintDef(DDL_REFERENCES), fTableName(nullptr), fRefAction(nullptr) { } TableReferencesConstraintDef(ColumnNameList* columns, QualifiedName* fTableName, ColumnNameList* foreignColumns, DDL_MATCH_TYPE matchType, ReferentialAction* refAction); ~TableReferencesConstraintDef() override; /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ColumnNameList fColumns; QualifiedName* fTableName; ColumnNameList fForeignColumns; DDL_MATCH_TYPE fMatchType; ReferentialAction* fRefAction; }; /** @brief Table check constraint. */ struct TableCheckConstraintDef : public TableConstraintDef { /** @brief Return DDL_SERIAL code */ DDL_SERIAL_TYPE getSerialType() override { return DDL_TABLE_CHECK_CONSTRAINT_DEF; } /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; TableCheckConstraintDef() : TableConstraintDef(DDL_CHECK) { } explicit TableCheckConstraintDef(const char* check); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~TableCheckConstraintDef() override = default; std::string fCheck; }; /** @brief Represents the alter table command. * * All forms of alter_table_statements are represented as * subclasses of this. */ struct AlterTableStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; AlterTableStatement() : fTableName(nullptr) { } EXPORT AlterTableStatement(QualifiedName* qName, AlterTableActionList* ataList); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; /** @brief Delete members. */ EXPORT ~AlterTableStatement() override; std::string schemaName() const { if (!fTableName) return "UNKNOWN"; return fTableName->fSchema; } long getTimeZone() const { return fTimeZone; } void setTimeZone(long timeZone) { fTimeZone = timeZone; } QualifiedName* fTableName; AlterTableActionList fActions; private: long fTimeZone; public: }; /** @brief This is used during parsing when constraint attributes are recognized. This is always before the parent column def is recognized. That's why we need a separate structure during parsing. When the column def is recognized, we'll just copy these into the Column structure. */ struct ConstraintAttributes { /** @brief Deserialize from ByteStream */ virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ virtual int serialize(messageqcpp::ByteStream& bs); ConstraintAttributes() = default; ConstraintAttributes(DDL_CONSTRAINT_ATTRIBUTES checkTime, bool deferrable) : fCheckTime(checkTime), fDeferrable(deferrable) { } virtual ~ConstraintAttributes() = default; DDL_CONSTRAINT_ATTRIBUTES fCheckTime; bool fDeferrable; }; /** @brief CreateIndex represents the CreateIndex operation. * * @note This currently takes ownership of the objects assigned to * fIndexName & fTableName. */ struct CreateIndexStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; CreateIndexStatement(); CreateIndexStatement(QualifiedName* qualifiedName1, QualifiedName* qualifiedName2, ColumnNameList* columnNames, bool unique); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~CreateIndexStatement() override; QualifiedName* fIndexName; QualifiedName* fTableName; ColumnNameList fColumnNames; bool fUnique; }; /** @brief DropIndexStatement represents the drop index operation. */ struct DropIndexStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ int serialize(messageqcpp::ByteStream& bs) override; DropIndexStatement() : fIndexName(nullptr) { } explicit DropIndexStatement(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ std::ostream& put(std::ostream& os) const override; ~DropIndexStatement() override; QualifiedName* fIndexName; }; /** @brief DropTableStatement represents the drop table operation */ struct DropTableStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; DropTableStatement() : fTableName(nullptr) { } EXPORT DropTableStatement(QualifiedName* qualifiedName, bool cascade, bool ifExists = false); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~DropTableStatement() override { delete fTableName; } std::string schemaName() const { if (!fTableName) return "UNKNOWN"; return fTableName->fSchema; } QualifiedName* fTableName; bool fCascade = false; bool fIfExists = false; }; /** @brief DebugStatement */ struct DebugDDLStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT virtual int unserialize(messageqcpp::ByteStream& bs); /** @brief Serialize to ByteStream */ EXPORT virtual int serialize(messageqcpp::ByteStream& bs); DebugDDLStatement(uint32_t debugLevel); EXPORT DebugDDLStatement(); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const; virtual ~DebugDDLStatement() { } uint32_t fDebugLevel; }; /** @brief TruncTableStatement represents the drop table operation */ struct TruncTableStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; TruncTableStatement() : fTableName(nullptr) { } EXPORT explicit TruncTableStatement(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~TruncTableStatement() override { delete fTableName; } std::string schemaName() const { if (!fTableName) return "UNKNOWN"; return fTableName->fSchema; } QualifiedName* fTableName; }; /** @brief Represents the mark partition out of service statement * */ struct MarkPartitionStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ MarkPartitionStatement() : fTableName(nullptr) { } /** @brief You can't have a CreateTableStatement without a table defintion */ EXPORT explicit MarkPartitionStatement(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~MarkPartitionStatement() override { delete fTableName; } QualifiedName* fTableName; ///< The table defintion std::set fPartitions; // partition numbers }; /** @brief Represents the mark partition out of service statement * */ struct RestorePartitionStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ RestorePartitionStatement() : fTableName(nullptr) { } EXPORT explicit RestorePartitionStatement(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~RestorePartitionStatement() override { delete fTableName; } QualifiedName* fTableName; ///< The table name. std::set fPartitions; // partition numbers }; /** @brief Represents the mark partition out of service statement * */ struct DropPartitionStatement : public SqlStatement { /** @brief Deserialize from ByteStream */ EXPORT int unserialize(messageqcpp::ByteStream& bs) override; /** @brief Serialize to ByteStream */ EXPORT int serialize(messageqcpp::ByteStream& bs) override; /** @brief Ctor for deserialization */ DropPartitionStatement() : fTableName(nullptr) { } EXPORT explicit DropPartitionStatement(QualifiedName* qualifiedName); /** @brief Dump to stdout. */ EXPORT std::ostream& put(std::ostream& os) const override; ~DropPartitionStatement() override { delete fTableName; } QualifiedName* fTableName; ///< The table name. std::set fPartitions; // partition numbers }; } // namespace ddlpackage #undef EXPORT