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