提交 b0cab2a4 authored 作者: Thomas Mueller's avatar Thomas Mueller

Added external table engines support.

上级 20e2a017
......@@ -228,7 +228,7 @@ Selectivity 100 means values are unique, 10 means every distinct value appears 1
SET DEFAULT changes the default value of a column.
SET NULL sets a column to allow NULL. The row may not be part of a primary key.
SET NULL sets a column to allow NULL. The row may not be part of a primary key.
Single column indexes on this column are dropped.
SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this column.
......@@ -449,8 +449,8 @@ Creates a new index.
This command commits an open transaction.
Hash indexes are meant for in-memory databases and memory tables (CREATE MEMORY TABLE).
For other tables, or if the index contains multiple columns, the HASH keyword is ignored.
Hash indexes can only test for equality, and do not support range queries (similar to a hash table).
For other tables, or if the index contains multiple columns, the HASH keyword is ignored.
Hash indexes can only test for equality, and do not support range queries (similar to a hash table).
Non-unique keys are supported.
","
CREATE INDEX IDXNAME ON TEST(NAME)
......@@ -525,19 +525,22 @@ CREATE SEQUENCE SEQ_ID
CREATE [ CACHED | MEMORY | TEMP | [ GLOBAL | LOCAL ] TEMPORARY ]
TABLE [ IF NOT EXISTS ]
name { { ( { columnDefinition | constraint } [,...] ) [ AS select ] }
| { AS select } } [ NOT PERSISTENT ]
| { AS select } } [ ENGINE tableEngineName ] [ NOT PERSISTENT ]
","
Creates a new table.
Cached tables (the default) are persistent, and the number of rows is not limited by the main memory.
Cached tables (the default) are persistent, and the number of rows is not limited by the main memory.
Memory tables are persistent, but the index data is kept in main memory,
Memory tables are persistent, but the index data is kept in main memory,
that means memory tables should not get too large.
The ENGINE option is only required when custom table implementations are used.
The table engine class must implement the interface org.h2.api.TableEngine.
Tables with the NOT PERSISTENT modifier are kept fully in memory, and all
rows are lost when the database is closed.
rows are lost when the database is closed.
Temporary tables are not persistent. Temporary tables can be global (accessible by all connections)
Temporary tables are not persistent. Temporary tables can be global (accessible by all connections)
or local (only accessible by the current connection). The default is for temporary tables is global.
This command commits an open transaction.
......
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>Improved MS SQL Server compatibility: support string concatenation using "+".
<ul><li>User defined table implementation can now be used using CREATE TABLE ... ENGINE.
Thanks to Sergi Vladykin for implementing this feature!
</li><li>Improved MS SQL Server compatibility: support string concatenation using "+".
Thanks to Stepan for the patch!
</li><li>When using the multi-threaded mode, running ANALYZE concurrently in multiple
connections could throw an exception.
......
......@@ -219,9 +219,9 @@ For a table defined as <code>CREATE TABLE TEST(X FLOAT)</code> the method
return a <code>java.lang.Float</code>. What's wrong?
</p>
<p>
This is not a bug. According the the JDBC specification, the JDBC data type <code>FLOAT</code>
This is not a bug. According the the JDBC specification, the JDBC data type <code>FLOAT</code>
is equivalent to <code>DOUBLE</code>, and both are mapped to <code>java.lang.Double</code>.
See also
See also
<a href="http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/getstart/mapping.html#1055162">
Mapping SQL and Java Types - 8.3.10 FLOAT</a>.</p>
......
......@@ -368,8 +368,8 @@ encrypted using AES-256 and XTEA encryption algorithms
<h3>Derby and HSQLDB</h3>
<p>
After an unexpected process termination (for example power failure), H2 can usually
recover safely and automatically without any user interaction. For Derby and HSQLDB,
After an unexpected process termination (for example power failure), H2 can usually
recover safely and automatically without any user interaction. For Derby and HSQLDB,
some manual steps are required ('Another instance of Derby may have already booted the database' /
'The database is already in use by another process').
</p>
......@@ -831,7 +831,7 @@ at the same time, however if one thread executes a long running query, the other
need to wait.
</p>
<p>
An application should normally use one connection per thread. This database synchronizes
An application should normally use one connection per thread. This database synchronizes
access to the same connection, but other databases may not do this.
</p>
......
......@@ -476,7 +476,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Optimizer: WHERE X=? AND Y IN(?), it always uses the index on Y. Should be cost based.
</li><li>Support ALTER SCHEMA name RENAME TO newName (rename schema).
</li><li>Make the cache scan resistant (currently a small cache is faster than a large cache for large table scans).
</li><li>Issue 178: Optimizer: index usage when both ascending and descending indexes are available
</li><li>Issue 178: Optimizer: index usage when both ascending and descending indexes are available
</li><li>Issue 179: Related subqueries in HAVING clause
</li></ul>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;
import org.h2.table.RecreatableTable;
import org.h2.command.ddl.CreateTableData;
/**
* Class for creating custom table implementations
*
* @author Sergi Vladykin
*/
public interface TableEngine {
/**
* Create new table
* @param data for table construction
* @return created table
*/
RecreatableTable createTable(CreateTableData data);
}
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.api;
import org.h2.table.TableBase;
import org.h2.command.ddl.CreateTableData;
/**
* A class that implements this interface can create custom table
* implementations.
*
* @author Sergi Vladykin
*/
public interface TableEngine {
/**
* Create new table.
*
* @param data the data to construct the table
* @return the created table
*/
TableBase createTable(CreateTableData data);
}
......@@ -4790,7 +4790,7 @@ public class Parser {
}
if (readIf("ENGINE")) {
command.setTableEngine(readString());
}
}
if (temp) {
if (readIf("ON")) {
read("COMMIT");
......
......@@ -12,7 +12,7 @@ import org.h2.engine.Session;
import org.h2.result.ResultInterface;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.StatementBuilder;
/**
......@@ -37,7 +37,7 @@ public class Analyze extends DefineCommand {
session.getUser().checkAdmin();
// TODO do we need to lock the table?
for (Table table : db.getAllTablesAndViews(false)) {
if (!(table instanceof TableData)) {
if (!(table instanceof RegularTable)) {
continue;
}
StatementBuilder buff = new StatementBuilder("SELECT ");
......
......@@ -263,9 +263,6 @@ public class CreateTable extends SchemaCommand {
this.sortedInsertMode = sortedInsertMode;
}
/**
* @param tableEngine the table engine to set
*/
public void setTableEngine(String tableEngine) {
data.tableEngine = tableEngine;
}
......
......@@ -43,7 +43,7 @@ public class CreateTableData {
public boolean temporary;
/**
* Whether the table global temporary
* Whether the table is global temporary.
*/
public boolean globalTemporary;
......@@ -66,9 +66,9 @@ public class CreateTableData {
* The session.
*/
public Session session;
/**
* Table engine to use
* The table engine to use for creating the table.
*/
public String tableEngine;
......
......@@ -594,8 +594,10 @@ public class Session extends SessionWithState implements SessionFactory {
if (SysProperties.CHECK) {
int lockMode = database.getLockMode();
if (lockMode != Constants.LOCK_MODE_OFF && !database.isMultiVersion()) {
if (locks.indexOf(log.getTable()) < 0 && !Table.TABLE_LINK.equals(log.getTable().getTableType())
&& !Table.EXTERNAL_TABLE_ENGINE.equals(log.getTable().getTableType())) {
String type = log.getTable().getTableType();
if (locks.indexOf(log.getTable()) < 0
&& !Table.TABLE_LINK.equals(type)
&& !Table.EXTERNAL_TABLE_ENGINE.equals(type)) {
DbException.throwInternalError();
}
}
......
......@@ -12,7 +12,7 @@ import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.ValueHashMap;
import org.h2.value.Value;
......@@ -26,10 +26,10 @@ public class HashIndex extends BaseIndex {
*/
protected final int indexColumn;
private final TableData tableData;
private final RegularTable tableData;
private ValueHashMap<Long> rows;
public HashIndex(TableData table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
public HashIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
initBaseIndex(table, id, indexName, columns, indexType);
this.indexColumn = columns[0].column.getColumnId();
this.tableData = table;
......
......@@ -17,7 +17,7 @@ import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -30,11 +30,11 @@ public class MultiVersionIndex implements Index {
private final Index base;
private final TreeIndex delta;
private final TableData table;
private final RegularTable table;
private final Object sync;
private final Column firstColumn;
public MultiVersionIndex(Index base, TableData table) {
public MultiVersionIndex(Index base, RegularTable table) {
this.base = base;
this.table = table;
IndexType deltaIndexType = IndexType.createNonUnique(false);
......
......@@ -10,7 +10,7 @@ import java.util.ArrayList;
import org.h2.engine.Session;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
/**
* Cursor implementation for non-unique hash index
......@@ -21,11 +21,11 @@ public class NonUniqueHashCursor implements Cursor {
private final Session session;
private final ArrayList<Long> positions;
private final TableData tableData;
private final RegularTable tableData;
private int index = -1;
public NonUniqueHashCursor(Session session, TableData tableData, ArrayList<Long> positions) {
public NonUniqueHashCursor(Session session, RegularTable tableData, ArrayList<Long> positions) {
this.session = session;
this.tableData = tableData;
this.positions = positions;
......
......@@ -12,7 +12,7 @@ import org.h2.message.DbException;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.New;
import org.h2.util.ValueHashMap;
import org.h2.value.Value;
......@@ -25,10 +25,10 @@ import org.h2.value.Value;
public class NonUniqueHashIndex extends HashIndex {
private ValueHashMap<ArrayList<Long>> rows;
private TableData tableData;
private RegularTable tableData;
private long rowCount;
public NonUniqueHashIndex(TableData table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
public NonUniqueHashIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
super(table, id, indexName, columns, indexType);
this.tableData = table;
reset();
......
......@@ -18,7 +18,7 @@ import org.h2.store.Page;
import org.h2.store.PageStore;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.MathUtils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -30,11 +30,11 @@ import org.h2.value.ValueNull;
public class PageBtreeIndex extends PageIndex {
private PageStore store;
private TableData tableData;
private RegularTable tableData;
private boolean needRebuild;
private long rowCount;
public PageBtreeIndex(TableData table, int id, String indexName, IndexColumn[] columns,
public PageBtreeIndex(RegularTable table, int id, String indexName, IndexColumn[] columns,
IndexType indexType, boolean create, Session session) {
initBaseIndex(table, id, indexName, columns, indexType);
// int test;
......
......@@ -24,7 +24,7 @@ import org.h2.store.Page;
import org.h2.store.PageStore;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.MathUtils;
import org.h2.util.New;
import org.h2.value.Value;
......@@ -38,7 +38,7 @@ import org.h2.value.ValueNull;
public class PageDataIndex extends PageIndex {
private PageStore store;
private TableData tableData;
private RegularTable tableData;
private long lastKey;
private long rowCount;
private HashSet<Row> delta;
......@@ -48,7 +48,7 @@ public class PageDataIndex extends PageIndex {
private DbException fastDuplicateKeyException;
private int memorySizePerPage;
public PageDataIndex(TableData table, int id, IndexColumn[] columns, IndexType indexType, boolean create, Session session) {
public PageDataIndex(RegularTable table, int id, IndexColumn[] columns, IndexType indexType, boolean create, Session session) {
initBaseIndex(table, id, table.getName() + "_DATA", columns, indexType);
// trace = database.getTrace(Trace.PAGE_STORE + "_di");
......
......@@ -13,7 +13,7 @@ import org.h2.result.SearchRow;
import org.h2.store.PageStore;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
/**
* An index that delegates indexing to the page data index.
......@@ -22,7 +22,7 @@ public class PageDelegateIndex extends PageIndex {
private final PageDataIndex mainIndex;
public PageDelegateIndex(TableData table, int id, String name, IndexType indexType, PageDataIndex mainIndex, boolean create, Session session) {
public PageDelegateIndex(RegularTable table, int id, String name, IndexType indexType, PageDataIndex mainIndex, boolean create, Session session) {
IndexColumn[] cols = IndexColumn.wrap(new Column[] { table.getColumn(mainIndex.getMainIndexColumn())});
this.initBaseIndex(table, id, name, cols, indexType);
this.mainIndex = mainIndex;
......
......@@ -21,7 +21,7 @@ import org.h2.result.SearchRow;
import org.h2.store.LobStorage;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.New;
/**
......@@ -33,13 +33,13 @@ import org.h2.util.New;
public class ScanIndex extends BaseIndex {
private long firstFree = -1;
private ArrayList<Row> rows = New.arrayList();
private TableData tableData;
private RegularTable tableData;
private int rowCountDiff;
private HashMap<Integer, Integer> sessionRowCount;
private HashSet<Row> delta;
private long rowCount;
public ScanIndex(TableData table, int id, IndexColumn[] columns, IndexType indexType) {
public ScanIndex(RegularTable table, int id, IndexColumn[] columns, IndexType indexType) {
initBaseIndex(table, id, table.getName() + "_DATA", columns, indexType);
if (database.isMultiVersion()) {
sessionRowCount = New.hashMap();
......
......@@ -11,14 +11,16 @@ import org.h2.result.Row;
import org.h2.result.SearchRow;
/**
* The cursor with at most one row.
* A cursor with at most one row.
*/
public class SingleRowCursor implements Cursor {
private Row row;
private boolean end;
/**
* @param row - the single row (if null then cursor is empty)
* Create a new cursor.
*
* @param row - the single row (if null then cursor is empty)
*/
public SingleRowCursor(Row row) {
this.row = row;
......
......@@ -12,7 +12,7 @@ import org.h2.message.DbException;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -22,10 +22,10 @@ import org.h2.value.ValueNull;
public class TreeIndex extends BaseIndex {
private TreeNode root;
private TableData tableData;
private RegularTable tableData;
private long rowCount;
public TreeIndex(TableData table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
public TreeIndex(RegularTable table, int id, String indexName, IndexColumn[] columns, IndexType indexType) {
initBaseIndex(table, id, indexName, columns, indexType);
tableData = table;
}
......
......@@ -183,7 +183,7 @@ Creates a new sequence."
CREATE [ CACHED | MEMORY | TEMP | [ GLOBAL | LOCAL ] TEMPORARY ]
TABLE [ IF NOT EXISTS ]
name { { ( { columnDefinition | constraint } [,...] ) [ AS select ] }
| { AS select } } [ NOT PERSISTENT ]
| { AS select } } [ ENGINE tableEngineName ] [ NOT PERSISTENT ]
","
Creates a new table."
"Commands (DDL)","CREATE TRIGGER","
......
......@@ -18,7 +18,7 @@ import org.h2.index.PageBtreeIndex;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -29,7 +29,7 @@ public class ResultTempTable implements ResultExternal {
private static final String COLUMN_NAME = "DATA";
private Session session;
private TableData table;
private RegularTable table;
private SortOrder sort;
private Index index;
private Cursor resultCursor;
......@@ -49,7 +49,7 @@ public class ResultTempTable implements ResultExternal {
data.persistData = true;
data.create = true;
data.session = session;
table = (TableData) schema.createTable(data);
table = (RegularTable) schema.createTable(data);
int indexId = session.getDatabase().allocateObjectId();
IndexColumn indexColumn = new IndexColumn();
indexColumn.column = column;
......
......@@ -23,7 +23,7 @@ import org.h2.index.Index;
import org.h2.message.DbException;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.table.TableLink;
import org.h2.util.New;
import org.h2.util.Utils;
......@@ -498,7 +498,7 @@ public class Schema extends DbObjectBase {
}
return engine.createTable(data);
}
return new TableData(data);
return new RegularTable(data);
}
}
......
......@@ -41,7 +41,7 @@ import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.IndexColumn;
import org.h2.table.Table;
import org.h2.table.TableData;
import org.h2.table.RegularTable;
import org.h2.util.Cache;
import org.h2.util.CacheLRU;
import org.h2.util.CacheObject;
......@@ -174,7 +174,7 @@ public class PageStore implements CacheWriter {
private PageLog log;
private Schema metaSchema;
private TableData metaTable;
private RegularTable metaTable;
private PageDataIndex metaIndex;
private IntIntHashMap metaRootPageId = new IntIntHashMap();
private HashMap<Integer, PageIndex> metaObjects = New.hashMap();
......@@ -1228,7 +1228,7 @@ public class PageStore implements CacheWriter {
data.persistIndexes = true;
data.create = false;
data.session = systemSession;
metaTable = new TableData(data);
metaTable = new RegularTable(data);
metaIndex = (PageDataIndex) metaTable.getScanIndex(
systemSession);
metaObjects.clear();
......@@ -1315,7 +1315,7 @@ public class PageStore implements CacheWriter {
data.persistIndexes = true;
data.create = false;
data.session = session;
TableData table = new TableData(data);
RegularTable table = new RegularTable(data);
CompareMode mode = CompareMode.getInstance(ops[0], Integer.parseInt(ops[1]));
table.setCompareMode(mode);
meta = table.getScanIndex(session);
......@@ -1324,7 +1324,7 @@ public class PageStore implements CacheWriter {
if (p == null) {
throw DbException.get(ErrorCode.FILE_CORRUPTED_1, "Table not found:" + parent + " for " + row + " meta:" + metaObjects);
}
TableData table = (TableData) p.getTable();
RegularTable table = (RegularTable) p.getTable();
Column[] tableCols = table.getColumns();
IndexColumn[] cols = new IndexColumn[columns.length];
for (int i = 0; i < columns.length; i++) {
......
......@@ -47,7 +47,7 @@ import org.h2.value.Value;
* in the database. The actual data is not kept here, instead it is kept in the
* indexes. There is at least one index, the scan index.
*/
public class TableData extends RecreatableTable {
public class RegularTable extends TableBase {
private Index scanIndex;
private long rowCount;
private volatile Session lockExclusive;
......@@ -65,7 +65,7 @@ public class TableData extends RecreatableTable {
*/
private boolean waitForLock;
public TableData(CreateTableData data) {
public RegularTable(CreateTableData data) {
super(data);
if (data.persistData && database.isPersistent()) {
mainIndex = new PageDataIndex(this, data.id, IndexColumn.wrap(getColumns()), IndexType.createScan(data.persistData), data.create, data.session);
......@@ -483,8 +483,8 @@ public class TableData extends RecreatableTable {
buff.append(", ");
}
buff.append(t.toString());
if (t instanceof TableData) {
if (((TableData) t).lockExclusive == s) {
if (t instanceof RegularTable) {
if (((RegularTable) t).lockExclusive == s) {
buff.append(" (exclusive)");
} else {
buff.append(" (shared)");
......@@ -498,7 +498,7 @@ public class TableData extends RecreatableTable {
public ArrayList<Session> checkDeadlock(Session session, Session clash, Set<Session> visited) {
// only one deadlock check at any given time
synchronized (TableData.class) {
synchronized (RegularTable.class) {
if (clash == null) {
// verification is started
clash = session;
......
......@@ -79,7 +79,7 @@ public abstract class Table extends SchemaObjectBase {
* The table type name for external table engines.
*/
public static final String EXTERNAL_TABLE_ENGINE = "EXTERNAL";
/**
* The columns of this table.
*/
......
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.table;
import org.h2.command.ddl.CreateTableData;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
/**
* @author Thomas Mueller
* @author Sergi Vladykin
*/
public abstract class RecreatableTable extends Table {
protected final String tableEngine;
private final boolean globalTemporary;
public RecreatableTable(CreateTableData data) {
super(data.schema, data.id, data.tableName, data.persistIndexes, data.persistData);
this.tableEngine = data.tableEngine;
this.globalTemporary = data.globalTemporary;
setTemporary(data.temporary);
Column[] cols = new Column[data.columns.size()];
data.columns.toArray(cols);
setColumns(cols);
}
@Override
public String getDropSQL() {
return "DROP TABLE IF EXISTS " + getSQL();
}
@Override
public String getCreateSQL() {
StatementBuilder buff = new StatementBuilder("CREATE ");
if (isTemporary()) {
if (isGlobalTemporary()) {
buff.append("GLOBAL ");
} else {
buff.append("LOCAL ");
}
buff.append("TEMPORARY ");
} else if (isPersistIndexes()) {
buff.append("CACHED ");
} else {
buff.append("MEMORY ");
}
buff.append("TABLE ").append(getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
}
buff.append("(\n ");
for (Column column : columns) {
buff.appendExceptFirst(",\n ");
buff.append(column.getCreateSQL());
}
buff.append("\n)");
if (tableEngine != null) {
buff.append("\nENGINE '");
buff.append(tableEngine);
buff.append("'");
}
if (!isPersistIndexes() && !isPersistData()) {
buff.append("\nNOT PERSISTENT");
}
return buff.toString();
}
public boolean isGlobalTemporary() {
return globalTemporary;
}
}
/*
* Copyright 2004-2010 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.table;
import org.h2.command.ddl.CreateTableData;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
/**
* The base class of a regular table, or a user defined table.
*
* @author Thomas Mueller
* @author Sergi Vladykin
*/
public abstract class TableBase extends Table {
/**
* The table engine used (null for regular tables).
*/
protected final String tableEngine;
private final boolean globalTemporary;
public TableBase(CreateTableData data) {
super(data.schema, data.id, data.tableName, data.persistIndexes, data.persistData);
this.tableEngine = data.tableEngine;
this.globalTemporary = data.globalTemporary;
setTemporary(data.temporary);
Column[] cols = new Column[data.columns.size()];
data.columns.toArray(cols);
setColumns(cols);
}
public String getDropSQL() {
return "DROP TABLE IF EXISTS " + getSQL();
}
public String getCreateSQL() {
StatementBuilder buff = new StatementBuilder("CREATE ");
if (isTemporary()) {
if (isGlobalTemporary()) {
buff.append("GLOBAL ");
} else {
buff.append("LOCAL ");
}
buff.append("TEMPORARY ");
} else if (isPersistIndexes()) {
buff.append("CACHED ");
} else {
buff.append("MEMORY ");
}
buff.append("TABLE ").append(getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
}
buff.append("(\n ");
for (Column column : columns) {
buff.appendExceptFirst(",\n ");
buff.append(column.getCreateSQL());
}
buff.append("\n)");
if (tableEngine != null) {
buff.append("\nENGINE '");
buff.append(tableEngine);
buff.append("'");
}
if (!isPersistIndexes() && !isPersistData()) {
buff.append("\nNOT PERSISTENT");
}
return buff.toString();
}
public boolean isGlobalTemporary() {
return globalTemporary;
}
}
......@@ -639,4 +639,4 @@ census genealogy scapegoat gov compacted migrating dies typtypmod latch await
counting dtest fallback infix places formal extern destination stdout memmove
stdio printf jchar sizeof stdlib jbyte jint uint ujlong typedef jdouble stdint
jfloat wchar hotspot jvoid std ujint jlong vars jboolean calloc argc strlen
equivalent synchronizes sullivan surname doe stepan
\ No newline at end of file
equivalent synchronizes sullivan surname doe stepan getstart
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论