/* Copyright (C) 2003 MySQL AB 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ODBC_CODEGEN_Code_base_hpp #define ODBC_CODEGEN_Code_base_hpp #include <set> #include <list> #include <vector> #include <common/common.hpp> #include <common/CodeTree.hpp> #include <common/DescArea.hpp> class Ctx; class ConnArea; class StmtArea; class DescArea; class DictCatalog; class DictSchema; class ResultArea; class ResultSet; class SpecRow; class Ndb; class NdbSchemaCon; class NdbConnection; class NdbOperation; class NdbScanFilter; class Plan_root; class Plan_table; class Plan_column; class Plan_expr; class Plan_expr_param; class Plan_pred; class Plan_dml_row; class Plan_dml_column; class Plan_ddl_column; class Plan_ddl_constr; class Plan_idx_column; class Exec_root; class Exec_base; class Exec_query; class Exec_expr; class Exec_expr_row; class Exec_expr_param; /** * @class Plan_base * @brief Base class for plan trees */ class Plan_base : public PlanTree { public: Plan_base(Plan_root* root); virtual ~Plan_base() = 0; // get references to StmtArea via Plan_root StmtArea& stmtArea() const; DescArea& descArea(DescUsage u) const; ConnArea& connArea() const; // catalogs DictCatalog& dictCatalog() const; DictSchema& dictSchema() const; // ndb Ndb* ndbObject() const; NdbSchemaCon* ndbSchemaCon() const; NdbConnection* ndbConnection() const; // containers for Plan classes typedef std::vector<Plan_table*> TableVector; typedef std::vector<Plan_column*> ColumnVector; typedef std::vector<Plan_dml_column*> DmlColumnVector; typedef std::vector<Plan_ddl_column*> DdlColumnVector; typedef std::vector<Plan_ddl_constr*> DdlConstrVector; typedef std::vector<Plan_idx_column*> IdxColumnVector; typedef std::vector<Plan_expr*> ExprVector; typedef std::list<Plan_expr*> ExprList; typedef std::vector<ExprList> ExprListVector; typedef std::list<Plan_pred*> PredList; typedef std::set<Plan_table*> TableSet; typedef std::vector<Plan_expr_param*> ParamVector; // control area on the stack XXX needs to be designed struct Ctl { Ctl(Ctl* up); Ctl* m_up; // up the stack // analyze TableVector m_tableList; // resolve column names bool m_topand; // in top-level where clause bool m_extra; // anything but single pk=expr bool m_aggrok; // aggregate allowed bool m_aggrin; // within aggregate args bool m_const; // only constants in set clause PredList m_topcomp; // top level comparisons Plan_dml_row *m_dmlRow; // row type to convert to Plan_table* m_topTable; // top level table for interpreted progs bool m_having; // in having-predicate // codegen Exec_root* m_execRoot; // root of Exec tree const Exec_query* m_execQuery; // pass to column }; // semantic analysis and optimization virtual Plan_base* analyze(Ctx& ctx, Ctl& ctl) = 0; // generate "executable" code virtual Exec_base* codegen(Ctx& ctx, Ctl& ctl) = 0; // misc virtual void print(Ctx& ctx) = 0; protected: Plan_root* m_root; void printList(Ctx& ctx, Plan_base* a[], unsigned n); }; inline Plan_base::Plan_base(Plan_root* root) : m_root(root) { ctx_assert(m_root != 0); } inline Plan_base::Ctl::Ctl(Ctl* up) : m_up(up), m_tableList(1), // 1-based m_topand(false), m_extra(false), m_aggrok(false), m_aggrin(false), m_dmlRow(0), m_topTable(0), m_having(false), m_execRoot(0), m_execQuery(0) { } /** * @class Exec_base * @brief Base class for exec trees */ class Exec_base : public ExecTree { public: class Code : public ExecTree::Code { public: virtual ~Code() = 0; }; class Data : public ExecTree::Data { public: virtual ~Data() = 0; }; Exec_base(Exec_root* root); virtual ~Exec_base() = 0; // get references to StmtArea via Exec_root virtual StmtArea& stmtArea() const; DescArea& descArea(DescUsage u) const; ConnArea& connArea() const; // catalogs DictSchema& dictSchema() const; // ndb Ndb* ndbObject() const; NdbSchemaCon* ndbSchemaCon() const; NdbConnection* ndbConnection() const; // containers for Exec classes typedef std::vector<Exec_expr*> ExprVector; typedef std::vector<Exec_expr_param*> ParamVector; // control area on the stack struct Ctl { Ctl(Ctl* up); Ctl* m_up; // up the stack const Exec_query* m_query; // pass Data ExprVector m_exprList; // pass Data NdbOperation* m_scanOp; // scan operation bool m_postEval; // for rownum unsigned m_groupIndex; // for group by bool m_groupInit; // first in group Exec_expr_row* m_sortRow; // from sort to group by NdbScanFilter* m_scanFilter; // scan filter }; // allocate and deallocate Data instances virtual void alloc(Ctx& ctx, Ctl& ctl) = 0; virtual void close(Ctx& ctx) = 0; // set Code and Data void setCode(const Code& code); void setData(Data& data); // misc virtual void print(Ctx& ctx) = 0; protected: const Code* m_code; Data* m_data; Exec_root* m_root; void printList(Ctx& ctx, Exec_base* a[], unsigned n); }; inline Exec_base::Exec_base(Exec_root* root) : m_code(0), m_data(0), m_root(root) { ctx_assert(m_root != 0); } inline void Exec_base::setCode(const Code& code) { ctx_assert(m_code == 0); m_code = &code; } inline void Exec_base::setData(Data& data) { ctx_assert(m_data == 0); m_data = &data; } inline Exec_base::Ctl::Ctl(Ctl* up) : m_up(up), m_scanOp(0), m_postEval(false), m_groupIndex(0), m_groupInit(false), m_sortRow(0), m_scanFilter(0) { } #endif