2762 Thava Alagu 2009-06-19
WL#4900: QFPD: AQT: Implement AQT adaptor for Tables, columns, Indexes
This contains initial draft implementation of AQT interface for database
model objects Tables and Columns.
Brief comments on the checked-in files :
Files being checked into sql/db_model directory :
db_model.h - Main header file for importing db model objects.
(External AQT interface header file)
db_model_impl.h - Internal header file for db model objects.
db_model_impl.cc - Internal implementation for db model objects.
db_iterator.h - Iterators specific to db model objects.
(External AQT interface header file)
db_iterator_impl.h - Internal DB Iterator implementation header.
Files being checked into sql/model_base directory:
model_base.h - Main header file for base model objects.
(External AQT Interface header file)
model_base_impl.h - Internal header for base model objects.
model_base_impl.cc - Internal implementation for base model objects.
added:
sql/db_model/Makefile.am
sql/db_model/db_iterator.h
sql/db_model/db_iterator_impl.h
sql/db_model/db_model.h
sql/db_model/db_model_impl.cc
sql/db_model/db_model_impl.h
sql/model_base/model_base.h
sql/model_base/model_base_impl.cc
sql/model_base/model_base_impl.h
modified:
configure.in
libmysqld/Makefile.am
sql/Makefile.am
sql/model_base/Makefile.am
2761 Timour Katchaounov 2009-06-18
WL#4837 QFPD: Join pushdown to NDB without optimization
Cosmetic changes:
* Renamed files/directories according to recommendations and according to last
WL#4739 Physical restructure of the server.
* Made file names more systematic.
* Adjusted all build-related files.
* Reoredered/reduced include directives.
* Fixed include guards.
New code:
* Initial implementation of the Table refence wrapper class, most importantly
of the Query_select class - the main representation of queries.
(WL#4849 QFPD: Implement the adapter part of the AQT interface)
* Initial implementation of an Expression wrapper class.
(WL#4849 QFPD: Implement the adapter part of the AQT interface)
* Changed error reporting according to the decision that errors
are propagated as return values (more changes needed for walkers and wrappers).
@ configure.in
renamed model_common -> model_base
@ libmysqld/Makefile.am
renamed model_common -> model_base
@ sql/Makefile.am
renamed model_common -> model_base
@ sql/model_base
renamed model_common -> model_base
@ sql/model_base/Makefile.am
removed file prefixes
@ sql/model_base/iterator.h
- renamed model_common -> model_base
- fixed include guards
@ sql/model_base/meta_object.h
- renamed model_common -> model_base
- fixed include guards
@ sql/model_base/meta_types.cc
- renamed model_common -> model_base
- fixed include guards
@ sql/model_base/meta_types.h
- renamed model_common -> model_base
- fixed include guards
@ sql/query_model/Makefile.am
- renamed model_common -> model_base
- added new files
@ sql/query_model/expression.h
Initial version of abstract interface for Expressions.
@ sql/query_model/expression_impl.cc
Initial dummy implementation for Expressions backed by items.
@ sql/query_model/expression_impl.h
Initial dummy implementation for Expressions backed by items.
@ sql/query_model/expression_walker_impl.cc
- fixed error return values
- removed file prefixes
@ sql/query_model/expression_walker_impl.h
- fixed error return values
- removed file prefixes
- renamed model_common -> model_base
@ sql/query_model/table_ref.h
Initial implementation of the abstract interface for Table references.
@ sql/query_model/table_ref_impl.cc
Implementation of Table references backed by complete query execution plans.
@ sql/query_model/table_ref_impl.h
Implementation of Table references backed by complete query execution plans.
@ sql/query_model/table_ref_walker_impl.cc
- removed filename prefixes
- fixed error return values
@ sql/query_model/table_ref_walker_impl.h
- removed filename prefixes
- fixed error return values
- fixed include guards
@ sql/query_model/tree_iterator.cc
- removed filename prefixes
- fixed error return values
@ sql/query_model/tree_iterator.h
- removed filename prefixes
- renamed model_common -> model_base
@ sql/query_model/tree_walker.h
- removed filename prefixes
- renamed model_common -> model_base
@ sql/sql_select.cc
- class renames
- removed importing of whole namespace
@ support-files/build-tags
Fixed the input file list generation to be recursive, so that etgas actually
analyzes all source files.
added:
sql/query_model/expression.h
sql/query_model/expression_impl.cc
sql/query_model/expression_impl.h
sql/query_model/table_ref.h
sql/query_model/table_ref_impl.cc
sql/query_model/table_ref_impl.h
renamed:
sql/model_common/ => sql/model_base/
sql/model_common/mc_iterator.h => sql/model_base/iterator.h
sql/model_common/mc_meta_object.h => sql/model_base/meta_object.h
sql/model_common/mc_meta_types.cc => sql/model_base/meta_types.cc
sql/model_common/mc_meta_types.h => sql/model_base/meta_types.h
sql/query_model/qm_expression_tree_walker_impl.cc => sql/query_model/expression_walker_impl.cc
sql/query_model/qm_expression_tree_walker_impl.h => sql/query_model/expression_walker_impl.h
sql/query_model/qm_table_ref_tree_walker_impl.cc => sql/query_model/table_ref_walker_impl.cc
sql/query_model/qm_table_ref_tree_walker_impl.h => sql/query_model/table_ref_walker_impl.h
sql/query_model/qm_tree_iterator.cc => sql/query_model/tree_iterator.cc
sql/query_model/qm_tree_iterator.h => sql/query_model/tree_iterator.h
sql/query_model/qm_tree_walker.h => sql/query_model/tree_walker.h
modified:
configure.in
libmysqld/Makefile.am
sql/Makefile.am
sql/model_base/Makefile.am
sql/query_model/Makefile.am
sql/sql_select.cc
support-files/build-tags
sql/model_base/iterator.h
sql/model_base/meta_object.h
sql/model_base/meta_types.cc
sql/model_base/meta_types.h
sql/query_model/expression_walker_impl.cc
sql/query_model/expression_walker_impl.h
sql/query_model/table_ref_walker_impl.cc
sql/query_model/table_ref_walker_impl.h
sql/query_model/tree_iterator.cc
sql/query_model/tree_iterator.h
sql/query_model/tree_walker.h
=== modified file 'configure.in'
--- a/configure.in 2009-06-18 13:24:30 +0000
+++ b/configure.in 2009-06-19 08:19:59 +0000
@@ -2982,6 +2982,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl
sql/Makefile sql/share/Makefile sql/backup/Makefile dnl
sql/query_model/Makefile sql/model_base/Makefile dnl
+ sql/db_model/Makefile dnl
sql/sql_builtin.cc sql-common/Makefile libservices/Makefile dnl
dbug/Makefile scripts/Makefile include/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl
=== modified file 'libmysqld/Makefile.am'
--- a/libmysqld/Makefile.am 2009-06-18 13:24:30 +0000
+++ b/libmysqld/Makefile.am 2009-06-19 08:19:59 +0000
@@ -107,6 +107,7 @@ INC_LIB= $(top_builddir)/regex/libregex.
$(top_builddir)/dbug/.libs/libdbug.a \
$(top_builddir)/vio/libvio.a \
$(top_builddir)/sql/query_model/.libs/libquerymodel.a \
+ $(top_builddir)/sql/db_model/.libs/libdbmodel.a \
$(top_builddir)/sql/model_base/.libs/libmodelbase.a \
@NDB_SCI_LIBS@ \
@mysql_plugin_libs@ \
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2009-06-18 13:24:30 +0000
+++ b/sql/Makefile.am 2009-06-19 08:19:59 +0000
@@ -28,7 +28,7 @@ AM_CPPFLAGS = @ZLIB_INCLUDES@ \
-I$(top_srcdir)/sql/db_model \
$(libevent_includes)
WRAPLIBS= @WRAPLIBS@
-SUBDIRS = share backup query_model model_base
+SUBDIRS = share backup model_base db_model query_model
libexec_PROGRAMS = mysqld
EXTRA_PROGRAMS = gen_lex_hash
bin_PROGRAMS = mysql_tzinfo_to_sql
@@ -60,7 +60,7 @@ SUPPORTING_LIBS = $(top_builddir)/vio/li
$(top_builddir)/regex/libregex.a \
$(top_builddir)/strings/libmystringsextra.la \
$(top_builddir)/strings/libmystringslt.la
-mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) backup/libbackup.la libndb.la query_model/libquerymodel.la model_base/libmodelbase.la
+mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) backup/libbackup.la libndb.la query_model/libquerymodel.la db_model/libdbmodel.la model_base/libmodelbase.la
LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
mysqld_LDADD = libndb.la \
@MYSQLD_EXTRA_LDFLAGS@ \
@@ -70,6 +70,7 @@ mysqld_LDADD = libndb.la \
$(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@ \
backup/libbackup.la \
query_model/libquerymodel.la \
+ db_model/libdbmodel.la \
model_base/libmodelbase.la
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
=== added file 'sql/db_model/Makefile.am'
--- a/sql/db_model/Makefile.am 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/Makefile.am 2009-06-19 08:19:59 +0000
@@ -0,0 +1,37 @@
+# Copyright 2009 Sun Microsystems, 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+noinst_LTLIBRARIES = libdbmodel.la
+
+INCLUDES = -I$(top_builddir)/include \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/sql \
+ -I$(top_srcdir)/sql/model_base \
+ -I$(top_srcdir)/sql/db_model \
+ -I$(top_srcdir)/regex
+
+libdbmodel_la_SOURCES = db_model_impl.cc
+
+#noinst_HEADERS = db_iterator.h db_iterator_impl.h db_model.h \
+# db_model_impl.h
+
+DEFS = \
+ -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+ -DLIBDIR="\"$(MYSQLLIBdir)\"" \
+ @DEFS@
+
=== added file 'sql/db_model/db_iterator.h'
--- a/sql/db_model/db_iterator.h 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/db_iterator.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,50 @@
+
+
+/**
+ @file db_iterator.h
+ @brief Abstract interface for database-model specific iterator classes.
+
+ Note: This file includes :
+ model_base.h -- common include file for db/query models
+ which declares basic iterators interface.
+ This file defines:
+ Database model specific iterators.
+
+ Note that it *does not* depend on DB model specific db_model.h
+ to avoid circular dependency.
+
+*/
+
+#ifndef DB_MODEL_DB_ITERATOR_INCLUDED
+#define DB_MODEL_DB_ITERATOR_INCLUDED
+
+/* Import declarations for common objects */
+
+#include "model_base.h"
+
+using namespace model_base;
+
+namespace db_model {
+
+/* Forward declaration of classes */
+class Column;
+class Index;
+class Table_constraint;
+class Foreign_key;
+class Unique_key;
+class Index_column;
+class Trigger;
+
+/* DB model specific type definitions. */
+
+typedef Iterator_type<Column> Iterator_column;
+typedef Iterator_type<Index> Iterator_index;
+typedef Iterator_type<Table_constraint> Iterator_table_constraint;
+typedef Iterator_type<Foreign_key> Iterator_foreign_key;
+typedef Iterator_type<Unique_key> Iterator_unique_key;
+typedef Iterator_type<Index_column> Iterator_index_column;
+typedef Iterator_type<Trigger> Iterator_trigger;
+
+} // End namespace db_model
+
+#endif // DB_MODEL_DB_ITERATOR_INCLUDED
=== added file 'sql/db_model/db_iterator_impl.h'
--- a/sql/db_model/db_iterator_impl.h 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/db_iterator_impl.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,20 @@
+
+
+#ifndef DB_MODEL_DB_ITERATOR_IMPL_INCLUDED
+#define DB_MODEL_DB_ITERATOR_IMPL_INCLUDED
+
+#include "db_iterator.h"
+
+namespace db_model {
+
+/* Exported Classes */
+
+class Iterator_index_impl;
+class Iterator_table_constraint_impl;
+class Iterator_foreign_key_impl;
+class Iterator_unique_key_impl;
+class Iterator_index_column_impl;
+
+} // End namespace model_common
+
+#endif // End DB_MODEL_DB_ITERATOR_IMPL_INCLUDED
=== added file 'sql/db_model/db_model.h'
--- a/sql/db_model/db_model.h 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/db_model.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,480 @@
+
+
+/**
+ @file db_model.h
+ @mainpage Abstract interface for database model objects.
+
+ DB objects model API provides abstract interface for database
+objects such as Table, Column, Index and Database.
+
+Note that the goal of abstract model API is to provide stable interface
+for use by storage engines. Currently exposing internal structures
+such as THD to storage engine results in volatile interfaces often
+breaking the storage engines when the internal server implementation
+changes.
+
+ */
+
+
+#ifndef DB_MODEL_DB_MODEL_INCLUDED
+#define DB_MODEL_DB_MODEL_INCLUDED
+
+#include "model_base.h"
+#include "db_iterator.h"
+
+// Imported class declarations.
+
+namespace query_model {
+ class Query_expression;
+}
+
+using namespace model_base;
+
+namespace db_model {
+
+/* Exported classes */
+
+class Database;
+class Table;
+class Base_table;
+class View_table;
+class Column;
+class Index;
+class Foreign_key;
+class Trigger;
+
+class Table_constraint;
+class Unique_key;
+class Index_column;
+
+typedef Unique_key Primary_key;
+
+/* List of class definitions */
+
+/**
+ @class Database
+ @brief Abstract database class
+
+ This represents MySQL database.
+ Currently it supports only minimal functionality.
+ This may be extended in future.
+
+ */
+class Database : public Meta_object {
+
+ /* Get the list of tables */
+ virtual Iterator_string *table_names()=0;
+ /* Get the list of views */
+ virtual Iterator_string *view_names()=0;
+
+};
+
+/**
+ @class table
+ @brief Abstract Table base class
+ */
+class Table : public Meta_object {
+
+public :
+
+ virtual Database *database()=0; /*< Get database */
+ virtual Iterator_column *columns()=0; /*< Get column list */
+
+ /*
+ Table types:
+
+ UNKNOWN_TABLE : Invalid unknown table type.
+
+ PERSISTENT_TABLE : Persistent, user defined, regular tables.
+ Hierarchy: Table=>Base_table=>Persistent_table
+
+ TEMP_TABLE : Non-persistent, visible only to session.
+ (could be user created temp table or server
+ generated temp table)
+ Hierarchy: Table=>Base_table=>Temp_table
+
+ VIEW_TABLE : Represents view or derived table.
+ Hierarchy: Table=>View_table
+
+ */
+ enum Table_type {
+ UNKNOWN_TABLE, /*< Unknown Table Type */
+ PERSISTENT_TABLE, /*< Persistent Table */
+ TEMP_TABLE, /*< Temp Table */
+ VIEW_TABLE, /*< View Table or View */
+ } ;
+
+ virtual Table_type table_type()=0; /*< Get table type */
+ virtual bool engine(::String *str)=0; /*< Get storage engine name*/
+ virtual bool charset(::String *str)=0;/*< Get charset name */
+ virtual bool collation(::String *str)=0;/*< Get collation name */
+
+ enum Row_format {
+ ROW_FORMAT_NOT_USED=-1, ROW_FORMAT_DEFAULT, ROW_FORMAT_FIXED,
+ ROW_FORMAT_DYNAMIC, ROW_FORMAT_COMPRESSED, ROW_FORMAT_REDUNDANT,
+ ROW_FORMAT_COMPACT, ROW_FORMAT_PAGE };
+
+ virtual Row_format row_format()=0; /*< Get row format. */
+
+};
+
+/**
+ @class Column
+ @brief Abstract column base class.
+ This represents the column of an active table in database.
+ */
+class Column : public Meta_object {
+
+public:
+
+ virtual Table *table()=0; /*< Get associated table */
+ virtual bool is_nullable()=0; /*< Is column nullable? */
+ /* Get default value for this column in String form */
+ virtual bool default_value(::String *def)=0;
+ /* Get column number. First column starts from 1. */
+ virtual int column_number()=0;
+
+ virtual bool is_unique()=0; /*< Is unique column? */
+ virtual bool is_primary()=0; /*< Is primarykey column? */
+ virtual bool is_sequence()=0; /*< Is auto increment col?*/
+
+ /* Get SQL data type. */
+ virtual Datatype *datatype()=0;
+
+ /* Get Charset name. Applies to only char based types */
+ virtual bool charset(::String *str)=0;
+ /* Get collation name. Applies to only char based types */
+ virtual bool collation(::String *str)=0;
+
+};
+
+/**
+ @class Base_table
+ @brief The Base_table represents actual table in the database.
+ This can be a persistent regular table or a temporary table.
+ Note that a view table is not a base table.
+*/
+class Base_table : public Table {
+
+public :
+
+ /* Is this temp table? The temp table is visible only in session. */
+ virtual bool is_temp_table() = 0;
+ virtual Iterator_index *indexes()=0; /*< Get index list */
+ virtual Iterator_trigger *triggers()=0; /*< Get triggers list */
+
+ virtual bool comment(::String *str)=0; /*< Get table comment. */
+ virtual bool tablespace(::String *str)=0; /*< Get tblspace name*/
+
+ /*
+ Get all kinds of constraints for this table:
+ This includes: PrimaryKey, ForeignKey, Unique constraints.
+ */
+ virtual Iterator_table_constraint *constraints()=0;
+
+ virtual Primary_key *primary_key()=0; /*< Get Primary Key. */
+
+ virtual Iterator_foreign_key *foreign_keys()=0; /*< Get Foreign keys */
+
+ /* Get the list of unique constraints. Includes primary key if exists */
+ virtual Iterator_unique_key *unique_constraints()=0;
+
+ /* Get auto-increment starting value. */
+ virtual unsigned long long autoincrement()=0;
+
+ /*
+ Get keyblock size in bytes. It is hint to storage engine.
+ Value 0 indicates use of default.
+ */
+ virtual int key_block_size()=0;
+
+ /* Todo: Get partition info. */
+
+};
+
+
+/**
+ @typedef Temp_table
+ @brief Temp_table is a special class of Base_table.
+
+ Both Temp_table and Persistent_table are special cases of Base_table.
+ They share most of the implementation.
+ These interfaces are aliased to Base_table due to simplicity of
+ the implementation (as against creating new derived classes)
+ Note: Foreign keys in temp table are currently ignored.
+*/
+typedef Base_table Temp_table;
+
+/**
+ @typedef Persistent_table
+ @brief Persistent table is a special case of Base_table.
+
+ Both Persistent_table and Temp_table are special cases of Base_table.
+ They share most of the implementation.
+ These interfaces are aliased to Base_table due to simplicity of
+ the implementation.
+*/
+typedef Base_table Persistent_table;
+
+/**
+ @class View_table
+ @brief This represents view table which has definition in the database.
+*/
+class View_table : public Table {
+public:
+ /* Get query expression */
+ virtual ::query_model::Query_expression *query_expr()=0;
+ virtual int sql(::String *str)=0; /*< Get associated SQL */
+};
+
+
+/*
+ @class Index
+ @brief Abstract class for Index.
+ Note: An index may internally be created due to:
+ 1) "primary key" constraint specification
+ 2) "unique" constraint specification
+ 3) "foriegn key" constraint (if supported by storage engine)
+ 4) explicit index specification
+ Non-unique indexes are always created as part of explicit specification.
+ Explicit specification of index always creates new index and mysql
+ does not attempt to "share" internally generated indexes as part of
+ unique/primary key specification.
+
+ The index name and constraint name are same when the index is created
+ for the constraint (either primary key, unique key or foreign key).
+
+ */
+class Index : public Meta_object {
+
+public:
+
+ virtual Table *table()=0; /*< Get associated table */
+ /* Get all components of (possibly clustered) index */
+ virtual Iterator_index_column *parts()=0;
+ virtual bool is_unique()=0; /*< Is unique index? */
+ virtual bool is_clustered()=0; /*< Is clustered index? */
+ virtual bool is_primary()=0; /*< Is primary key index?*/
+ virtual bool is_system_generated()=0; /*< System generated index?*/
+
+ /*
+ This returns associated source constraint for this index.
+ Note: Single index can atmost be associated with single constraint:
+ This could be primary or unique constraint.
+ Non-unique index is not associated with any constraints
+ and will return NULL.
+ */
+ virtual Table_constraint *index_constraint()=0;
+
+ /*
+ Enum type for index types. These are mutually exclusive:
+ Primary : The index is primary index. The values must be unique.
+ Unique : A unique index which is not the primary.
+ Nonunique: Non-unique regular index. values need not be unique.
+ It is also not fulltext, spatial or foreign key index.
+ Fulltext: Special type non-unique index for fulltext search.
+ Spatial : Special type non-unique index for spatial search.
+ ForeignKey: Special type non-unique index in referencing table
+ created for foreign key constraint.
+ */
+ enum Index_type { INDEX_TYPE_PRIMARY, INDEX_TYPE_UNIQUE,
+ INDEX_TYPE_NONUNIQUE, INDEX_TYPE_FULLTEXT,
+ INDEX_TYPE_SPATIAL,
+ INDEX_TYPE_FOREIGN_KEY};
+
+ virtual Index_type index_type()=0; /*< Get index type. */
+
+ enum Index_algo { INDEX_ALGO_UNDEF=0,
+ INDEX_ALGO_BTREE,
+ INDEX_ALGO_RTREE,
+ INDEX_ALGO_HASH,
+ INDEX_ALGO_FULLTEXT };
+
+ virtual Index_algo index_algo()=0; /*< Get Index Algorithm*/
+ /*
+ Get keyblock size in bytes. It is hint to storage engine.
+ Value 0 indicates use of default.
+ */
+ virtual long key_block_size()=0;
+};
+
+/**
+ @class Index_column
+ @brief This represents a single part of the index (in clustered index)
+ If the clustered index has many components, there is one
+ Index_column instance created for each component.
+ For non-clustered index, there is only one Index_column.
+*/
+class Index_column : public Meta_object {
+
+public :
+
+ virtual Column *column()=0; /* Get associated column */
+ /*
+ Index may be created on leading part of column values.
+ Return value of 0 indicates entire column is used for index.
+ */
+ virtual int partial_length()=0;
+ /*
+ Index column can be ascending or descending.
+ Currently it is always used as ascending in mysql.
+ */
+ virtual bool is_ascending()=0;
+};
+
+/*
+ @class Table_constraint
+ @brief Abstract table constraint clause.
+
+Note: Check SQL Standard 5WD-02-Foundation-2003-09 4.17
+ Integrity Constraints for more description about the constraints.
+
+ Constraint := Table Constraint | Domain Constraint | Assertion
+ Table Constraint := Involves one or more columns in a table
+ Domain constraint := Restricted datatype e.g integer value > 3
+ can be used against any column
+ Assertion := Involves multiple tables
+
+ MySQL currently supports table constraints only.
+
+ MySQL assumes all constraints are non-deferrable and checked immediate.
+ [ SQL standard supports the notion of constraint being either deferrable
+ or not. If deferrable, the current constraint mode can be
+ "deferred" or "immediate". ]
+
+ TableConstraint :- unique | referential(foreign_key) | check
+
+ unique-constraint(column-list) :- defined by: "unique" | "primary key"
+ referential-constraint(referencing-columns) :-
+ specifies referenced-table(referenced-columns);
+ The <referenced-columns> should be of type "unique".
+ The match type (full,partial,simple) defines semantics of match when
+ some columns can be null.
+ The referential triggered action specifies what to do :
+ i.e. ON delete|update restrict|cascade|set-null|no-action
+ referenced table may be same as referencing table.
+
+ check-constraint : constraint applied per row on a given table.
+ currently parsed and ignored by MySQL.
+
+ unique key and primary key must be associated with an index.
+ Foreign key constraint may have an associated index in
+ referencing table if storage engine supports it.
+
+ */
+class Table_constraint : public Meta_object {
+
+public:
+
+ /* Get associated base table. */
+ virtual Base_table *base_table()=0;
+ /*
+ Currently all MySQL constraints are not deferrable.
+ so this always returns false for now.
+ */
+ virtual bool is_deferrable() { return false; }
+
+ /*
+ For mysql, all constraints are not deferrable and
+ always checked immediate. So this always returns false for now.
+ */
+ virtual bool is_initially_deferred() { return false; }
+
+ enum Constraint_type {
+ UNIQUE_KEY_CONSTRAINT,
+ PRIMARY_KEY_CONSTRAINT,
+ FOREIGN_KEY_CONSTRAINT
+ };
+
+ /* Get constraint type : unique | primary_key | foreign_key */
+ virtual Constraint_type constraint_type()=0;
+
+};
+
+/*
+ @class Foreign_key
+ @brief Abstract foreign key referential constraint
+ */
+class Foreign_key : public Table_constraint {
+
+public:
+
+ /* Get associated referencing table. */
+ virtual Base_table *referencing_table()=0;
+
+ /* Get associated referenced table. */
+ virtual Base_table *referenced_table()=0;
+
+ /* Get referencing columns. */
+ virtual Iterator_column *referencing_columns()=0;
+
+ /* Get referenced columns. */
+ virtual Iterator_column *referenced_columns()=0;
+
+ /*
+ @enum Foreign_key_match_type
+ @brief Match type for foreign key referential constraint.
+
+ Match type provides semantics of match when some
+ referencing/referenced columns could be null.
+ */
+ enum Foreign_key_match_type {
+ /*
+ Either all referencing columns are null or non-nulls. Every
+ non-null referencing column must match with a referenced column.
+ */
+ FOREIGN_KEY_MATCH_FULL=1,
+ /* Non-null values of referencing cols must match with referenced.*/
+ FOREIGN_KEY_MATCH_PARTIAL,
+ /* If atleast one referencing column is NULL, no constraint imposed.
+ Otherwise all non-null columns must match.
+ */
+ FOREIGN_KEY_MATCH_SIMPLE
+ };
+ virtual Foreign_key_match_type match_type()=0;
+
+ /*
+ @enum Foreign_key_action_type
+ @brief Referential action types for implementing foreign keys.
+ The action specifies what to do after delete|update of the
+ referenced row. This could be one of:
+ restrict|cascade|set-null|no-action|set-default
+ The no-action is the default action type.
+ */
+ enum Foreign_key_action_type {
+ FOREIGN_KEY_NO_ACTION = 0, /*< No action. */
+ FOREIGN_KEY_RESTRICT = 1, /*< Reject update/delete */
+ FOREIGN_KEY_CASCADE = 2, /*< Cascade update/delete */
+ FOREIGN_KEY_SET_NULL = 3, /*< Set referencing columns as null*/
+ FOREIGN_KEY_SET_DEFAULT = 4 /*< Set referencing cols to def value*/
+ };
+
+ /* Returns action to take when a row in referenced table is deleted. */
+ virtual Foreign_key_action_type on_delete_action()=0;
+
+ /* Returns action to take when a row in referenced table is updated. */
+ virtual Foreign_key_action_type on_update_action()=0;
+
+};
+
+/*
+ @class Unique_key
+ @brief Abstract unique key constraint.
+
+ Note: Primary_key is a special case of Unique_key.
+ However they share most of the implementation.
+ Primary_key is type aliased to Unique_key due to the simplicity of
+ the implementation.
+
+ */
+class Unique_key : public Table_constraint {
+public :
+ virtual Index *unique_index()=0;
+ virtual bool is_primary_key()=0;
+};
+
+
+} // End namespace db_model
+
+#endif // DB_MODEL_DB_MODEL_INCLUDED
+
=== added file 'sql/db_model/db_model_impl.cc'
--- a/sql/db_model/db_model_impl.cc 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/db_model_impl.cc 2009-06-19 08:19:59 +0000
@@ -0,0 +1,389 @@
+
+
+#include "mysql_priv.h"
+
+#include "db_model_impl.h"
+
+using namespace model_base;
+
+namespace db_model {
+
+/* Implementation for methods originally declared in super class Table */
+
+bool Base_table_impl::name(::String *str)
+{
+ if (str == NULL || tshare_ == NULL ) return false;
+ char *name = tshare_->table_name.str;
+ size_t len = tshare_->table_name.length;
+
+ // uint32 dstmaxlen = str->alloced_length();
+ // if (dstmaxlen < len) return false;
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+Iterator_column *Base_table_impl::columns()
+{
+ Iterator_column *col_iter = new Iterator_column_impl(table_, session_);
+ return col_iter;
+}
+
+inline Table::Table_type table_category2type(enum_table_category category)
+{
+ switch (category) {
+ case TABLE_UNKNOWN_CATEGORY:
+ return Table::UNKNOWN_TABLE;
+ case TABLE_CATEGORY_TEMPORARY:
+ return Table::TEMP_TABLE;
+ case TABLE_CATEGORY_USER:
+ return Table::PERSISTENT_TABLE;
+ // case TABLE_CATEGORY_SYSTEM:
+ // case TABLE_CATEGORY_INFORMATION:
+ // case TABLE_CATEGORY_PERFORMANCE:
+ default:
+ return Table::UNKNOWN_TABLE;
+ }
+}
+
+Table::Table_type Base_table_impl::table_type()
+{
+ if (!tshare_) return Table::UNKNOWN_TABLE;
+ return table_category2type(tshare_->table_category);
+}
+
+bool Base_table_impl::engine(::String *str)
+{
+
+ if (str == NULL || tshare_ == NULL ) return false;
+
+ handlerton *hton = tshare_ -> db_type();
+ if (hton == NULL) return false;
+
+ ::LEX_STRING *lname = hton_name(hton);
+ if (lname == NULL) return false;
+ char *engine_name = lname->str;
+ size_t len = lname->length;
+
+ if (engine_name == NULL) return false;
+
+ str->copy(engine_name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+bool Base_table_impl::charset(::String *str)
+{
+ if (str == NULL || tshare_ == NULL ) return false;
+
+ ::CHARSET_INFO *cs = tshare_ -> table_charset;
+ if (cs == NULL) return false;
+
+ const char *name = cs -> csname;
+ if (name == NULL) return false;
+ size_t len = strlen(name);
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+
+}
+
+bool Base_table_impl::collation(::String *str)
+{
+ if (str == NULL || tshare_ == NULL ) return false;
+
+ ::CHARSET_INFO *cs = tshare_ -> table_charset;
+ if (cs == NULL) return false;
+
+ const char *name = cs -> name;
+ if (name == NULL) return false;
+ size_t len = strlen(name);
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+Table::Row_format Base_table_impl::row_format()
+{
+ if (tshare_ == NULL ) return Table::ROW_FORMAT_NOT_USED;
+
+ switch (tshare_->row_type) {
+
+ case ::ROW_TYPE_DEFAULT : return Table::ROW_FORMAT_DEFAULT;
+ case ::ROW_TYPE_FIXED : return Table::ROW_FORMAT_FIXED;
+ case ::ROW_TYPE_DYNAMIC : return Table::ROW_FORMAT_DYNAMIC;
+ case ::ROW_TYPE_COMPRESSED : return Table::ROW_FORMAT_COMPRESSED;
+ case ::ROW_TYPE_REDUNDANT : return Table::ROW_FORMAT_REDUNDANT;
+ case ::ROW_TYPE_COMPACT : return Table::ROW_FORMAT_COMPACT;
+ case ::ROW_TYPE_PAGE : return Table::ROW_FORMAT_PAGE;
+ case ::ROW_TYPE_NOT_USED :
+ default: return Table::ROW_FORMAT_NOT_USED ;
+
+ }
+}
+
+
+/* Implementation for super abstract class Base_table */
+
+bool Base_table_impl::is_temp_table()
+{
+
+/* Temp tables also use TABLE_SHARE but not part of table def cache.
+ Temp tables are visible only in the session and can hide a real table
+ of the same name even if that exists during the session.
+*/
+ if (tshare_ && (tshare_->table_category == TABLE_CATEGORY_TEMPORARY))
+ return true;
+
+ return false;
+
+}
+
+
+// Iterator_index * Base_table_impl::indexes();
+// Iterator_trigger * Base_table_impl::triggers();
+
+bool Base_table_impl::comment(::String *str)
+{
+
+ if (str == NULL || tshare_ == NULL ) return false;
+
+ char *name = tshare_->comment.str;
+ size_t len = tshare_->comment.length;
+
+ if (name == NULL) return false;
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+bool Base_table_impl::tablespace(::String *str)
+{
+
+ if (str == NULL || tshare_ == NULL ) return false;
+
+ char *name = tshare_->tablespace;
+
+ if (name == NULL) return false;
+ size_t len = strlen(name);
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+
+}
+
+/*
+ Get all kinds of constraints for this table:
+ This includes: PrimaryKey, ForeignKey, Unique constraints.
+*/
+// Iterator_table_constraint *constraints() { return NULL; }
+
+// Pkey *primary_key() { return NULL; }
+
+// virtual Iterator_fkey *foreign_keys() { return NULL; }
+
+/* Get the list of unique constraints. Includes pkey if exists */
+// virtual Iterator_ukey *unique_constraints() { return NULL; }
+
+/* Get auto-increment starting value. */
+// virtual unsigned long long autoincrement() { return 0; }
+
+/*
+ Get keyblock size in bytes. It is hint to storage engine.
+ Value 0 indicates use of default.
+*/
+// virtual int key_block_size() { return 0; }
+
+
+// Definition of Column_impl methods originally declared in Column class
+//
+
+
+Column_impl::Column_impl(::Field *p_field, Session_impl *p_session)
+{
+ field_ = p_field;
+ //
+ // Synopsis:
+ // Table *t;
+ // Field ** fld_arr = t->field;
+ // TABLE_SHARE *s = t->s;
+ // Column_impl col(fld_arr[0]);
+ //
+ // Note: The t->s->field[n] is also Field* but don't use this
+ // to construct Column_impl since many functions like
+ // field->sql_type(String&) don't work in that case.
+
+
+ session_ = p_session;
+ a_tab_ = NULL; // Associated Table* instance. todo: use global cache.
+ data_type_ = NULL; // Associated data type. todo: use global cache.
+}
+
+
+bool Column_impl::name(::String *str)
+{
+ if (str == NULL || field_ == NULL ) return false;
+
+ const char *name = field_ -> field_name;
+ if (name == NULL) return false;
+
+ size_t len = strlen(name);
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+
+bool Column_impl::is_nullable()
+{
+ // by default, the column is nullable unless specified otherwise.
+ if (field_ == NULL) return true; // should not happen. Just in case.
+ return field_->maybe_null();
+}
+
+Table * Column_impl::table()
+{
+ if (a_tab_ != NULL) return a_tab_; // Reuse the one if already exists
+
+ if (field_ == NULL) return NULL;
+
+ // We require that the field instance is tied to TABLE instance --
+ // just TABLE_SHARE would not suffice.
+ TABLE *t = field_->table;
+ if (t == NULL) return NULL;
+
+ // Todo: Return Table * from cache with key as TABLE *t
+
+ TABLE_SHARE *s = t->s;
+ if (s == NULL) return NULL;
+
+ switch(table_category2type(s->table_category)){
+ case Table::TEMP_TABLE:
+ case Table::PERSISTENT_TABLE:
+ // To do: Retrieve from cache if exists.
+ // We definitely need caching here.
+ return Base_table_impl::create_base_table_inst(t, session_);
+ // To do: Implement this for other types
+ default:
+ return NULL;
+ }
+}
+
+/* Get column number. First column starts from 1. */
+int Column_impl::column_number()
+{
+ if (field_ == NULL) return -1;
+ return (int)field_->field_index + 1;
+}
+
+/* Get default value for this column in String form */
+bool Column_impl::default_value(::String *def)
+{
+ return false;
+}
+
+/* Is this unique column? */
+bool Column_impl::is_unique()
+{
+ if (field_ == NULL) return false;
+
+ // Auto increment column is always unique.
+ if (field_->unireg_check == ::Field::NEXT_NUMBER ) return true;
+
+ TABLE *table = field_->table;
+
+ if (table == NULL) return false; // should not happen
+
+ TABLE_SHARE *share= table->s;
+ uint flags = field_->flags;
+ KEY *key_info= table->key_info;
+ uint primary_key= share->primary_key;
+
+ for (uint i=0 ; i < share->keys ; i++,key_info++)
+ {
+ // skip clustered indexes
+ if (key_info->key_parts > 1) continue;
+
+ // skip if this index does not correspond to this field.
+ KEY_PART_INFO *key_part= key_info->key_part;
+ if (key_part -> field != field_) continue;
+
+ if (i == primary_key) return true; // primary key is always unique
+
+ if (key_info->flags & HA_NOSAME) return true; // unique key index
+ }
+ return false; // No matching unique index found.
+}
+
+/* Is this primarykey column? */
+bool Column_impl::is_primary ()
+{
+ if (field_ == NULL) return false; // should not happen.
+
+ TABLE *table = field_->table;
+
+ if (table == NULL) return false; // should not happen
+
+ TABLE_SHARE *share= table->s;
+ uint flags = field_->flags;
+ KEY *key_info= table->key_info;
+ uint primary_key= share->primary_key;
+
+ if (primary_key >= MAX_KEY) return false; // There is no primary key.
+
+ key_info += primary_key;
+
+ if (key_info->key_parts > 1) return false; // primary key is clustered
+
+ KEY_PART_INFO *key_part= key_info->key_part;
+ if (key_part -> field != field_) return false;
+
+ return true; // All conditions for primary key satisfied.
+
+}
+
+/* Is this auto increment col? */
+bool Column_impl::is_sequence()
+{
+ if (field_ == NULL) return false; // should not happen.
+
+ if (field_ -> unireg_check == ::Field::NEXT_NUMBER ) return true;
+
+ return false;
+}
+
+
+// Implemenation of Column_impl class
+
+/* Get abstract data type. */
+Datatype *Column_impl::datatype()
+{
+ if (data_type_ != NULL) return data_type_;
+ data_type_ = Datatype_impl::create_datatype_impl_inst(field_, session_);
+ return data_type_;
+}
+
+/* Get Charset name. Applies to only char based types */
+bool Column_impl::charset(::String *str)
+{
+ Datatype *type = datatype();
+ if (type == NULL) return false;
+ return type->charset(str);
+}
+
+/* Get collation name. Applies to only char based types */
+bool Column_impl::collation(::String *str)
+{
+ Datatype *type = datatype();
+ if (type == NULL) return false;
+ return type->charset(str);
+}
+
+
+} // End of namespace db_model
=== added file 'sql/db_model/db_model_impl.h'
--- a/sql/db_model/db_model_impl.h 1970-01-01 00:00:00 +0000
+++ b/sql/db_model/db_model_impl.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,488 @@
+
+
+/** @file db_model_impl.h
+ Implementation classes for AQT database objects.
+
+ DB model objects API provides abstract interface for database
+objects such as Table, Column, Index, Database, etc.
+This file contains declarations for the corresponding implementation classes.
+
+ Last updated: 2009 Jun 01
+
+ */
+
+
+#ifndef DB_MODEL_DB_MODEL_IMPL_INCLUDED
+#define DB_MODEL_DB_MODEL_IMPL_INCLUDED
+
+#include "db_model.h"
+#include "db_iterator_impl.h"
+#include "model_base_impl.h"
+
+namespace query_model {
+ // Imported classes
+ class Query_expression;
+};
+
+using namespace model_base;
+
+namespace db_model {
+
+/* Exported classes */
+
+class Database_impl;
+class Base_table_impl;
+class View_table_impl;
+class Column_impl;
+class Index_impl;
+class Foreign_key_impl;
+class Trigger_impl;
+
+class Table_constraint_impl;
+class Unique_key_impl;
+class Primary_key_impl;
+class Index_column_impl;
+
+/* class definitions */
+
+/**
+ @class Database_impl
+ @brief database implementation class
+ */
+class Database_impl : public Database {
+
+public:
+
+ virtual Iterator_string *table_names() { return NULL; };
+ virtual Iterator_string *view_names() { return NULL; };
+
+ Database_impl(String *p_name, Session_impl *p_session) {
+ dbname_ = p_name;
+ session_ = p_session;
+ };
+
+ // Implementation specific internal access functions
+ inline String *name() { return dbname_; };
+ inline Session_impl *session() { return session_; };
+
+private:
+ String *dbname_;
+ Session_impl *session_;
+};
+
+
+class Base_table_impl : public Base_table {
+
+protected :
+
+ /* Retrieving certain information require the presence of TABLE
+ * instance hence we require the constructor with TABLE * ;
+ * Just TABLE_SHARE* does not suffice.
+ TODO: Revisit and confirm this.
+ */
+
+ Base_table_impl(TABLE *p_table, Session_impl *p_session) {
+ table_ = p_table;
+ session_ = p_session;
+ tshare_ = table_ ? table_->s : NULL;
+ }
+
+public :
+
+ /* Todo: To reuse the instances, use public factory method. */
+
+ static Base_table_impl *create_base_table_inst(TABLE *t,
+ Session_impl *p_session)
+ {
+ // Retrieve from cache, if exists; else ...
+ Base_table_impl *btab = new Base_table_impl(t, p_session);
+ // Put this in the cache using TABLE* as key.
+ return btab;
+ }
+
+ virtual bool name(String *);
+
+ // Abstract Methods inherited from Table class ...
+
+ virtual Database *database() { return NULL; }
+
+ virtual Iterator_column *columns();
+ virtual Table_type table_type();
+
+ virtual bool engine(::String *str);
+ virtual bool charset(::String *str);
+ virtual bool collation(::String *str);
+
+ virtual Row_format row_format();
+
+
+ // Abstract Methods inherited from Base_table
+
+ virtual bool is_temp_table();
+
+ virtual Iterator_index *indexes() { return NULL; }
+ virtual Iterator_trigger *triggers() { return NULL; }
+
+ virtual bool comment(::String *str);
+ virtual bool tablespace(::String *str);
+
+ virtual Iterator_table_constraint *constraints() { return NULL; }
+
+ virtual Primary_key *primary_key() { return NULL; }
+
+ virtual Iterator_foreign_key *foreign_keys() { return NULL; }
+
+ /* Get the list of unique constraints. Includes primary key if exists */
+ virtual Iterator_unique_key *unique_constraints() { return NULL; }
+
+ /* Get auto-increment starting value. */
+ virtual unsigned long long autoincrement() { return 0; }
+
+ /*
+ Get keyblock size in bytes. It is hint to storage engine.
+ Value 0 indicates use of default.
+ */
+ virtual int key_block_size() { return 0; }
+
+ /* Todo: Get partition info. */
+
+
+// Not recommended. Certain functionalities may not be available.
+// Base_table_impl(TABLE_SHARE *s, Session_impl *p_session) {
+// tshare = s;
+// tab = NULL;
+// session = p_session;
+// }
+
+
+
+ // Implementation specific internal access functions
+ inline Session_impl *session() { return session_; }
+ inline TABLE * table_impl() { return table_; }
+
+private:
+ TABLE *table_;
+ Session_impl *session_;
+ TABLE_SHARE *tshare_; // Initialized as table->s; Convenience variable.
+};
+
+class View_table_impl : public View_table {
+public:
+
+ /* Get associated query expression for the view */
+ virtual ::query_model::Query_expression *query_expr() { return NULL; }
+
+ /* Get associated SQL for the view */
+ virtual int sql(String *str) { return NULL; }
+
+ View_table_impl(TABLE *t, Session_impl *p_session){
+ table_ = t;
+ session_ = p_session;
+ }
+
+ // Implementation specific internal access functions
+ inline Session_impl *session() { return session_; }
+ inline TABLE * table_impl() { return table_; }
+
+private:
+ TABLE *table_;
+ Session_impl *session_;
+};
+
+
+/**
+ @class Column_impl
+ @brief AQT Column implementation class.
+ This represents the column of an active table in database.
+ */
+
+class Column_impl : public Column {
+
+protected:
+ Column_impl(Field *p_field, Session_impl *p_session);
+
+public:
+
+ /* Factory method to create Column_impl instances */
+
+ static Column_impl *create_column_impl_inst(Field *fld, Session_impl *ses)
+ {
+ Column_impl *inst;
+ // Todo: Retrieve this from cache if available.
+ inst = new Column_impl(fld, ses);
+ // Put this into the Column_impl::col_impl_cache hash
+ return inst;
+ }
+
+ virtual bool name(String *);
+
+ virtual bool is_nullable(); /*< Is column nullable? */
+ virtual Table *table(); /*< Get associated table */
+
+ /* Get column number. First column starts from 1. */
+ virtual int column_number() ;
+
+ /* Get default value for this column in String form */
+ virtual bool default_value(String *def);
+
+ virtual bool is_unique(); /*< Is unique column? */
+ virtual bool is_primary(); /*< Is primarykey column? */
+ virtual bool is_sequence(); /*< Is auto increment col?*/
+
+ /* Get SQL data type. */
+ virtual Datatype *datatype();
+
+ /* Get Charset name. Applies to only char based types */
+ virtual bool charset(String *str);
+
+ /* Get collation name. Applies to only char based types */
+ virtual bool collation(String *str);
+
+ // Implementation specific internal access functions
+ inline Session_impl *session() { return session_; }
+ inline ::Field *field_impl() { return field_; }
+
+private:
+ ::Field *field_;
+ Session_impl *session_;
+ Table *a_tab_; // Associated abstract table.
+ // Todo: This should also go to query/global cache also.
+ Datatype *data_type_; // Associated abstract data type.
+ // Todo: This should go to query/global cache also.
+ // static HASH col_impl_cache_; // Contains (Field*, Column_impl*) map cache
+};
+
+
+/*
+ @class Index_impl
+ @brief Implementaion class for Index.
+
+ */
+class Index_impl : public Index {
+
+public:
+
+ virtual Table *table() /*< Get associated table */
+ { return NULL; }
+
+ virtual Iterator_index_column *parts() /*< Get index components */
+ { return NULL; }
+
+ virtual bool is_unique() /*< Is unique index? */
+ { return false; }
+ virtual bool is_clustered() /*< Is clustered index? */
+ { return false; }
+ virtual bool is_primary() /*< Is primary key index?*/
+ { return false; }
+ virtual bool is_system_generated() /*< System generated index?*/
+ { return false; }
+
+ /*
+ This returns associated source constraint for this index.
+ Note: Single index can atmost be associated with single constraint:
+ This could be primary or unique constraint.
+ Non-unique index is not associated with any constraints
+ and will return NULL.
+ */
+ virtual Table_constraint *index_constraint() { return NULL; }
+
+ virtual Index::Index_type index_type() /*< Get index type. */
+ { return INDEX_TYPE_NONUNIQUE; }
+
+ virtual Index::Index_algo index_algo() /*< Get Index Algorithm*/
+ { return INDEX_ALGO_UNDEF; }
+
+ /*
+ Get keyblock size in bytes. It is hint to storage engine.
+ Value 0 indicates use of default.
+ */
+ virtual long key_block_size() { return 0; }
+};
+
+/*
+ @class Index_column_impl
+ @brief Implementaion class for Index_column which is part of index.
+
+ */
+class Index_column_impl : public Index_column {
+
+public :
+
+ virtual Column *column() /* Get associated column */
+ { return NULL; }
+
+ /*
+ Index may be created on leading part of column values.
+ Return value of 0 indicates entire column is used for index.
+ */
+ virtual int partial_length() { return 0; }
+
+ /* Currently it is always used as ascending in mysql. */
+ virtual bool is_ascending() { return true; }
+};
+
+/*
+ @class Table_constraint_impl
+ @brief Implementation class for table constraint.
+ */
+class Table_constraint_impl : public Table_constraint {
+
+public:
+
+ /* Get associated base table. */
+ virtual Base_table *base_table() { return NULL; }
+
+ /* Currently all MySQL constraints are not deferrable. */
+ virtual bool is_deferrable() { return false; }
+
+ /* Currently all MySQL constraints are not deferrable and
+ always checked immediate.
+ */
+ virtual bool is_initially_deferred() { return false; }
+
+ /* Get constraint type : unique key | primary_key | foreign_key */
+ virtual Constraint_type constraint_type()
+ {
+ return FOREIGN_KEY_CONSTRAINT; // Temporary implementation
+ }
+
+};
+
+/*
+ @class Foreign_key_impl
+ @brief Foreign key referential constraint implementation class
+ */
+class Foreign_key_impl : public Foreign_key {
+
+public:
+
+ /* Get associated base table. */
+ virtual Base_table *base_table() { return NULL; }
+
+ virtual bool name(String *name) /*<Get constraint name */
+ { return -1; }
+
+ /* Get constraint type : unique | primary_key | foreign_key */
+ virtual Constraint_type constraint_type()
+ {
+ return FOREIGN_KEY_CONSTRAINT;
+ }
+
+ /* Get associated referencing table. */
+ virtual Base_table *referencing_table() { return NULL; }
+
+ /* Get associated referenced table. */
+ virtual Base_table *referenced_table() { return NULL; }
+
+ /* Get referencing columns. */
+ virtual Iterator_column *referencing_columns() { return NULL; }
+
+ /* Get referenced columns. */
+ virtual Iterator_column *referenced_columns() { return NULL; }
+
+ virtual Foreign_key_match_type match_type()
+ { return FOREIGN_KEY_MATCH_FULL; }
+
+ /* Returns action to take when a row in referenced table is deleted. */
+ virtual Foreign_key_action_type on_delete_action()
+ { return FOREIGN_KEY_NO_ACTION; }
+
+ /* Returns action to take when a row in referenced table is updated. */
+ virtual Foreign_key_action_type on_update_action()
+ { return FOREIGN_KEY_NO_ACTION; }
+
+};
+
+/*
+ @class Unique_key_impl
+ @brief AQT Implementation class for unique key constraint
+ */
+class Unique_key_impl : public Unique_key {
+public :
+ virtual Index *unique_index() { return NULL; }
+};
+
+
+// Utility and misc helper classes
+
+/**
+
+ @class Iterator_column_impl
+ @brief This implements an iterator over a set of internal columns.
+
+ The backing store for this iterator is the internal TABLE *.
+ On each iteration, current() returns pointer to abstract class Column.
+ This effectively hides the implementation details of internal type "Field"
+ and provides more stable interface for use.
+*/
+class Iterator_column_impl : public Iterator_column {
+
+public:
+
+ Iterator_column_impl(TABLE *p_table, Session_impl *p_session)
+ {
+
+ table_ = p_table;
+ session_ = p_session;
+
+ tshare_ = table_ ? table_->s : NULL;
+ fields_ = table_ ? table_->field : NULL;
+ total_fields_ = tshare_ ? tshare_->fields : 0;
+
+ cur_col_ = NULL;
+ cur_idx_ = -1;
+ // Points to first element by default.
+ if (total_fields_ > 0) cur_idx_ = 0;
+
+ }
+
+ virtual bool first()
+ {
+ if (cur_idx_ == 0) return true;
+ if (total_fields_ <= 0) return false;
+ cur_idx_ = 0;
+ cur_col_ = NULL;
+ return true;
+ }
+
+ virtual bool next()
+ {
+ if (cur_idx_ < 0) return false;
+ if (++cur_idx_ >= total_fields_) {
+ cur_idx_ = -1;
+ return false;
+ }
+ cur_col_ = NULL;
+ return true;
+ }
+
+ virtual Column *current()
+ {
+ if (cur_col_) return cur_col_; // return the current one if exists
+ if (cur_idx_ < 0 || cur_idx_ >= total_fields_) return NULL;
+ ::Field *cur_field = fields_[cur_idx_];
+ // Todo: Retrive cur_col from cache using cur_field ptr as key.
+ cur_col_ = Column_impl::create_column_impl_inst(cur_field, session_);
+ // cur_col_ = new Column_impl(cur_field, session_);
+ return cur_col_;
+ }
+
+ virtual ~Iterator_column_impl() {}
+ virtual bool size_supported() { return true; }
+ virtual long size() { return (long) total_fields_ ; }
+
+private :
+ TABLE *table_;
+ Session_impl *session_;
+ int cur_idx_; /*< cursor pointing to Field array index. Starts from 0.*/
+ Column_impl *cur_col_; /*< Points to current column wrapper class */
+
+ TABLE_SHARE *tshare_; /*< Convenience variable for table->s */
+ Field **fields_; /*< Convenience variable for table->field */
+ int total_fields_; /*< Convenience variable for tshare->fields */
+};
+
+} // End namespace db_model
+
+#endif // DB_MODEL_DB_MODEL_IMPL_INCLUDED
+
=== modified file 'sql/model_base/Makefile.am'
--- a/sql/model_base/Makefile.am 2009-06-18 13:24:30 +0000
+++ b/sql/model_base/Makefile.am 2009-06-19 08:19:59 +0000
@@ -20,7 +20,7 @@ INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/sql \
-I$(top_srcdir)/regex
-libmodelbase_la_SOURCES = meta_types.cc
+libmodelbase_la_SOURCES = meta_types.cc model_base_impl.cc
#noinst_HEADERS =
=== added file 'sql/model_base/model_base.h'
--- a/sql/model_base/model_base.h 1970-01-01 00:00:00 +0000
+++ b/sql/model_base/model_base.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,204 @@
+
+/**
+ @file model_base.h
+ Abstract interface for common base model objects.
+
+ Base model objects provide abstract interface for common objects.
+
+*/
+
+#ifndef MODEL_BASE_MODEL_BASE_INCLUDED
+#define MODEL_BASE_MODEL_BASE_INCLUDED
+
+
+/* @Todo :
+ Import the definition of Iterator & Meta_object
+ from iterator.h and meta_object.h
+*/
+
+namespace model_base {
+
+/* Imported util functions */
+void *model_alloc(size_t sz);
+void *model_free(void *ptr);
+
+
+/* Exported Classes */
+
+template <typename E> class Iterator_type;
+class Datatype;
+class Iterator_string;
+
+
+/* Definitions */
+
+class Meta_object {
+ // Default implementation indicates name not supported.
+ virtual bool name(String *name) { return true; }
+ // virtual bool alias(String *name)=0; /*< Get alias */
+ /* place holder here. definition imported later. */
+};
+
+
+class Session : public Meta_object {
+ virtual void *mem_alloc(size_t size)=0; /*< Session pool malloc */
+ virtual void mem_free(void *) = 0; /*< Free allocated memory */
+};
+
+/**
+ @typedef Base_field_type
+ @brief This type specifies an enum for all SQL data types.
+
+ This enum defintion was copied from internal mysql_com.h.
+ Todo: some cleanup of obsolete types may be possible.
+*/
+enum Base_field_type { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
+ MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
+ MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
+ MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
+ MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
+ MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
+ MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
+ MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
+ MYSQL_TYPE_BIT,
+ MYSQL_TYPE_NEWDECIMAL=246,
+ MYSQL_TYPE_ENUM=247,
+ MYSQL_TYPE_SET=248,
+ MYSQL_TYPE_TINY_BLOB=249,
+ MYSQL_TYPE_MEDIUM_BLOB=250,
+ MYSQL_TYPE_LONG_BLOB=251,
+ MYSQL_TYPE_BLOB=252,
+ MYSQL_TYPE_VAR_STRING=253,
+ MYSQL_TYPE_STRING=254,
+ MYSQL_TYPE_GEOMETRY=255,
+ MAX_NO_FIELD_TYPES /* Should always be last */
+};
+
+/**
+ @class Datatype
+ @brief Abstract datatype class
+ */
+class Datatype : public Meta_object {
+
+public :
+
+ virtual Base_field_type base_type()=0;
+ /*
+ Todo: Include type specific things here including :
+ - length for bit, INT types, char, binary, blob types
+ - (length, decimals) for float, decimal, "numeric" types
+ - charset, collation info for char, text, enum, set types
+ - value set for enum types
+ - value set for set type
+
+ Todo: Explore if the proper datatype hierarchy is better
+ or this is sufficient.
+ */
+ /* This specifies the length declared in field type declaration.
+ Examples:
+ i integer(11) => length is 11
+ c char(100) => length is 100
+ d decimal(10, 5) => length is 10
+ f float(4, 2) => length is 4
+ n numeric(5, 2) => length is 5
+ */
+ virtual uint32 length() = 0;
+
+ /* Applies to only : decimal, float, numeric types */
+ virtual int decimals() = 0;
+
+ /* Applies to only char, text, enum, set */
+ virtual bool charset(::String *str) = 0;
+
+ /* Applies to only char, text, enum, set */
+ virtual bool collation(::String *str) = 0;
+
+ /* Applies to only enum and set datatypes */
+ virtual Iterator_string *values() = 0;
+};
+
+
+
+/**
+ @class Iterator
+ @brief Base class for iterating over Meta_object's collection
+
+ Synopsis:
+
+ Iterator *iter = new Iterator_xyz_impl((Type_abc*)def);
+
+ Meta_object *obj;
+
+ while (obj = iter->current()){
+ ..... // Do something with obj
+ iter->next();
+ }
+ iter->first();
+*/
+class Iterator
+{
+
+public :
+ virtual bool first() = 0; /*< Move current to first */
+ virtual bool next() = 0; /*< Move current to next */
+ virtual Meta_object *current() = 0; /*< Return current obj */
+ virtual ~Iterator() {} /*< virtual destructor */
+ virtual bool size_supported() { return false; } /*< Is size() supported?*/
+ virtual long size() { return -1; } /*< Return collection size*/
+};
+
+
+/**
+ @class Iterator_type
+ @brief Iterator_type is a simple template for Iterator specialization.
+
+ Iterator is used to iterate over collection of objects of
+ generic type Meta_object. Hence the current() method is defined as:
+
+ Meta_object *current();
+
+ However we also need specific specialization of Iterators,
+ which returns more specific type for strict type checking.
+
+ This trivial template is used just for that.
+
+ i.e. Iterator_type<E> is same as Iterator except that the
+ current() method returns object of type E* instead of Meta_object*
+
+*/
+
+template <typename E> class Iterator_type : public Iterator
+{
+public:
+ virtual E *current() = 0;
+ ~Iterator_type() { }
+};
+
+
+/**
+ Special Iterator types needs to be declared separately.
+ It also supports all the methods in the Iterator,
+ though it is not directly type compatible with "Iterator" class.
+
+ The reason for this is explained below:
+ Consider Iterator_string current() method:
+ String *current();
+ However String is not a subclass of Meta_object.
+ In this case, Iterator_string needs to be declared separately
+ and this is not a direct subclass of Iterator.
+*/
+
+class Iterator_string {
+public:
+ virtual bool first() = 0; /*< Move current to first */
+ virtual bool next() = 0; /*< Move current to next */
+ virtual String *current() = 0; /*< Return current obj */
+ virtual ~Iterator_string() {} /*< virtual destructor */
+ virtual bool size_supported() { return false; } /*< Is size() supported?*/
+ virtual long size() { return -1; } /*< Return collection size*/
+
+};
+
+} // End namespace model_base
+
+#endif // End ifdef MODEL_BASE_MODEL_BASE_INCLUDED
=== added file 'sql/model_base/model_base_impl.cc'
--- a/sql/model_base/model_base_impl.cc 1970-01-01 00:00:00 +0000
+++ b/sql/model_base/model_base_impl.cc 2009-06-19 08:19:59 +0000
@@ -0,0 +1,113 @@
+
+/**
+ @file model_base_impl.cc
+
+ Implementation of the interface for base model objects.
+
+*/
+
+#include "mysql_priv.h"
+#include "model_base_impl.h"
+
+namespace model_base {
+
+// Exported Global Functions
+Base_field_type internal_to_external_type(enum_field_types p_type);
+
+Base_field_type internal_to_external_type(enum_field_types p_type)
+{
+ // Currently internal and external enum types are exactly same.
+ // If this changes, update this function accordingly.
+ Base_field_type type = (Base_field_type) p_type;
+ // Todo: expand this with a switch() case to protect it from
+ // accidental changes in internal types.
+}
+
+
+// Implementation of Datatype_impl class
+
+Base_field_type Datatype_impl::base_type()
+{
+ if (field_ == NULL) return MAX_NO_FIELD_TYPES; // should not happen
+ return internal_to_external_type(field_->real_type()) ;
+}
+
+/*
+ For the Datatype :
+ - (length): applicable for bit, INT types, char, binary, blob types
+ - (length, decimals): applicable for float, decimal, "numeric" types
+ e.g. integer(5), char(100)
+*/
+uint32 Datatype_impl::length()
+{
+ if (field_ == NULL) return 0;
+ return field_->field_length;
+}
+
+/*
+ Decimals applicable to: Float, Decimal, "Numeric" Types
+ e.g. Decimal(10,5), Float(10,3)
+ */
+int Datatype_impl::decimals()
+{
+ if (field_ == NULL) return 0;
+ return field_->decimals();
+
+}
+
+/* charset applies to only char, text, enum, set */
+bool Datatype_impl::charset(::String *str)
+{
+ if (str == NULL) return false;
+
+ if (!field_->has_charset()) return false;
+
+ const char *charset = field_->charset()->csname;
+ if (charset == NULL) return false;
+ size_t len = strlen(charset);
+
+ str->copy(charset, (uint32) len, &my_charset_bin);
+
+ return true;
+
+}
+
+/* Collation applies only to char, text, enum, set types */
+
+bool Datatype_impl::collation(::String *str)
+{
+ if (str == NULL) return false;
+
+ if (!field_->has_charset()) return false;
+
+ const char *collation = field_->charset()->name;
+ if (collation == NULL) return false;
+ size_t len = strlen(collation);
+
+ str->copy(collation, (uint32) len, &my_charset_bin);
+
+ return true;
+
+}
+
+/* values() applies to only enum and set datatypes */
+Iterator_string *Datatype_impl::values()
+{
+
+ TYPELIB *typelib;
+
+ enum_field_types type = field_->real_type();
+
+ if (type == ::MYSQL_TYPE_ENUM || type == ::MYSQL_TYPE_SET) {
+ typelib = ((Field_enum *)field_)->typelib;
+ }
+ else typelib = NULL;
+
+ Iterator_string_typelib *iter_str =
+ new Iterator_string_typelib(typelib, field_->charset());
+ return iter_str;
+}
+
+} // End namespace model_base
+
+
=== added file 'sql/model_base/model_base_impl.h'
--- a/sql/model_base/model_base_impl.h 1970-01-01 00:00:00 +0000
+++ b/sql/model_base/model_base_impl.h 2009-06-19 08:19:59 +0000
@@ -0,0 +1,229 @@
+
+/**
+ @file model_base_impl.h
+ Implementation interface for common base model objects.
+
+*/
+
+#ifndef MODEL_BASE_MODEL_BASE_IMPL_INCLUDED
+#define MODEL_BASE_MODEL_BASE_IMPL_INCLUDED
+
+#include "model_base.h"
+
+namespace model_base {
+
+// Exported Classes
+class Session_impl;
+class Datatype_impl;
+class Iterator_string_typelib;
+
+// Exported Functions
+Base_field_type internal_to_external_type(enum_field_types p_type);
+
+/**
+ @class Session_impl
+ @brief Session implementation class
+ */
+class Session_impl : public Session {
+
+public:
+
+Session_impl(THD *t)
+{
+ thd_ = t;
+ // Initialize thread/session specific hash tables here.
+}
+
+~Session_impl()
+{
+ // Free session specific Hash table resources
+}
+
+virtual bool name(::String *str)
+{
+ if (str == NULL) return false;
+ char name[64];
+ snprintf(name, sizeof(name), "session-%p", this);
+ size_t len = strlen(name);
+
+ // uint32 dstmaxlen = str->alloced_length();
+ // if (dstmaxlen < len) return false;
+
+ str->copy(name, (uint32) len, &my_charset_bin);
+
+ return true;
+}
+
+void *mem_alloc(size_t sz)
+{
+ return (void *) malloc(sz);
+}
+
+void mem_free(void *ptr)
+{
+ // Free the allocated block of memory
+ free(ptr); // For now.
+}
+
+ // Implementation specific access methods.
+
+ inline THD *get_thd() { return thd_; }
+
+private:
+ THD *thd_;
+ // Include thread specific hash tables here.
+
+};
+
+
+/**
+ @class Iterator_string_typelib
+ @brief Implements iterator over set of strings backed by TYPELIB
+*/
+class Iterator_string_typelib : public Iterator_string {
+
+public:
+ Iterator_string_typelib(TYPELIB *p_typelib, CHARSET_INFO *p_charset)
+ {
+ typelib_ = p_typelib;
+ src_charset_ = p_charset;
+ cur_idx_ = -1;
+ // By default, the cursor points to the first element.
+ if (typelib_ && typelib_->count > 0) cur_idx_ = 0;
+ // Set the current pointer to NULL
+ str_ptr_ = NULL;
+ // Initialize temporary string for containing current
+ cur_str_.set(strbuf_, sizeof(strbuf_), &my_charset_bin);
+ }
+
+ virtual bool first()
+ {
+ if (cur_idx_ == 0) return true; // Already at first.
+
+ str_ptr_ = NULL; // Pointer to current is now not valid
+ if (typelib_ && typelib_->count > 0) {
+ cur_idx_ = 0;
+ return true;
+ }
+ cur_idx_ = -1;
+ return false;
+ }
+
+ virtual bool next()
+ {
+ if (typelib_ == NULL || typelib_->count == 0) return false;
+ if ( cur_idx_ < 0) return false;
+ if ( (cur_idx_+1) >= (int) typelib_->count) return false;
+
+ ++ cur_idx_;
+ str_ptr_ = NULL;
+ return true;
+ }
+
+ virtual ::String *current()
+ {
+ if (str_ptr_) return str_ptr_;
+
+ if (typelib_ == NULL || typelib_->count == 0) return NULL;
+ if (cur_idx_ < 0 || cur_idx_ >= (int) typelib_->count) return NULL;
+ str_ptr_ = &cur_str_;
+ // Copy the string from typelib to current string.
+ uint errors = 0;
+ cur_str_.copy(typelib_->type_names[cur_idx_],
+ typelib_->type_lengths[cur_idx_],
+ src_charset_? src_charset_:&my_charset_bin,
+ &my_charset_bin, &errors);
+ if (errors) str_ptr_ = NULL;
+ return str_ptr_;
+ }
+
+ virtual ~Iterator_string_typelib() {}
+ virtual bool size_supported() { return true; }
+ virtual long size()
+ {
+ if (typelib_ == NULL) return 0;
+ return (long) typelib_->count;
+ }
+private:
+ TYPELIB *typelib_;
+ int cur_idx_;
+#define MAX_NAME_LEN 256
+ char strbuf_[MAX_NAME_LEN+1];
+ ::String cur_str_;
+ ::String *str_ptr_;
+ CHARSET_INFO *src_charset_; // charset of the typelib source
+ // Note: Destination charset is always assumed to be &my_charset_bin
+ // If this is not OK, introduce dst_cset as well.
+};
+
+
+// Todo: This should be integrated with Meta_type
+
+class Datatype_impl : public Datatype {
+
+protected:
+
+Datatype_impl(::Field *p_field, Session_impl *p_session)
+{
+ field_ = p_field;
+ session_ = p_session;
+}
+
+public:
+
+/**
+ Factory method to create Datatype_impl instances.
+
+ Todo: Datatype should be reused across Fields by using global cache.
+ This implementation is temporary where there is 1:1 relation
+ between field instance and datatype.
+ create_datatype_impl_inst :
+ Factory method to create Datatype_impl instances.
+*/
+static Datatype_impl *create_datatype_impl_inst(::Field *p_field,
+ Session_impl *p_session)
+{
+
+ Datatype_impl *type;
+ // Get from the cache if available. Else create an instance,
+ // and put this into the cache using Field* as key.
+ type = new Datatype_impl(p_field, p_session);
+ // put type into Datatype_impl::datatype_impl_cache
+ return type;
+}
+
+
+virtual Base_field_type base_type();
+
+/* length is applicable for bit, INT types, char, binary, blob types */
+virtual uint32 length();
+
+/* Decimals applicable to: Float, Decimal, "Numeric" Types */
+virtual int decimals();
+
+/* charset applies to only char, text, enum, set */
+virtual bool charset(::String *str);
+
+/* Collation applies only to char, text, enum, set types */
+virtual bool collation(::String *str);
+
+/* values() applies to only enum and set datatypes */
+virtual Iterator_string *values();
+
+// Implementation specific access methods.
+inline Session_impl *session() { return session_; }
+
+private:
+ Session_impl *session_;
+ ::Field *field_; // This is for temporary implementation.
+ // Include thread specific hash tables here.
+
+ // static HASH data_type_cache; // Contains (Field*, Datatype*) map cache
+
+};
+
+
+
+} // End namespace model_base
+
+#endif // End ifdef MODEL_BASE_MODEL_BASE_IMPL_INCLUDED
Attachment: [text/bzr-bundle] bzr/thavamuni.alagu@sun.com-20090619081959-91j0mubjjeu9q48z.bundle
| Thread |
|---|
| • bzr push into mysql-6.0-wl4838-dbmodel branch (thavamuni.alagu:2761 to 2762)WL#4900 | Thava Alagu | 19 Jun |