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

Local temporary tables now support indexes.

上级 cb83b7f3
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>RUNSCRIPT no longer uses a temporary file. <ul><li>Local temporary tables now support indexes. Thanks a lot to Matt Roy!
</li><li>RUNSCRIPT no longer uses a temporary file.
</li><li>New system table INFORMATION_SCHEMA.SESSION_STATE containing the </li><li>New system table INFORMATION_SCHEMA.SESSION_STATE containing the
SQL statements that make up the session state. The list currently contains SQL statements that make up the session state. The list currently contains
variables (SET @..) and local temporary tables (without data). variables (SET @..) and local temporary tables (without data).
......
...@@ -4412,7 +4412,7 @@ public class Parser { ...@@ -4412,7 +4412,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList()); command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) { if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
command.setIndex(getSchema().findIndex(indexName)); command.setIndex(getSchema().findIndex(session, indexName));
} }
return command; return command;
} else if (database.getMode().indexDefinitionInCreateTable && (readIf("INDEX") || readIf("KEY"))) { } else if (database.getMode().indexDefinitionInCreateTable && (readIf("INDEX") || readIf("KEY"))) {
...@@ -4443,7 +4443,7 @@ public class Parser { ...@@ -4443,7 +4443,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList()); command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) { if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
command.setIndex(getSchema().findIndex(indexName)); command.setIndex(getSchema().findIndex(session, indexName));
} }
} else if (readIf("FOREIGN")) { } else if (readIf("FOREIGN")) {
command = new AlterTableAddConstraint(session, schema); command = new AlterTableAddConstraint(session, schema);
...@@ -4453,7 +4453,7 @@ public class Parser { ...@@ -4453,7 +4453,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList()); command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) { if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
command.setIndex(schema.findIndex(indexName)); command.setIndex(schema.findIndex(session, indexName));
} }
read("REFERENCES"); read("REFERENCES");
parseReferences(command, schema, tableName); parseReferences(command, schema, tableName);
...@@ -4488,7 +4488,7 @@ public class Parser { ...@@ -4488,7 +4488,7 @@ public class Parser {
} }
if (readIf("INDEX")) { if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema(); String indexName = readIdentifierWithSchema();
command.setRefIndex(getSchema().findIndex(indexName)); command.setRefIndex(getSchema().findIndex(session, indexName));
} }
while (readIf("ON")) { while (readIf("ON")) {
if (readIf("DELETE")) { if (readIf("DELETE")) {
......
...@@ -40,7 +40,7 @@ public class AlterIndexRename extends DefineCommand { ...@@ -40,7 +40,7 @@ public class AlterIndexRename extends DefineCommand {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); Database db = session.getDatabase();
Schema schema = oldIndex.getSchema(); Schema schema = oldIndex.getSchema();
if (schema.findIndex(newIndexName) != null || newIndexName.equals(oldIndex.getName())) { if (schema.findIndex(session, newIndexName) != null || newIndexName.equals(oldIndex.getName())) {
throw Message.getSQLException(ErrorCode.INDEX_ALREADY_EXISTS_1, newIndexName); throw Message.getSQLException(ErrorCode.INDEX_ALREADY_EXISTS_1, newIndexName);
} }
session.getUser().checkRight(oldIndex.getTable(), Right.ALL); session.getUser().checkRight(oldIndex.getTable(), Right.ALL);
......
...@@ -130,7 +130,7 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -130,7 +130,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
} }
if (index == null) { if (index == null) {
IndexType indexType = IndexType.createPrimaryKey(table.getPersistent(), primaryKeyHash); IndexType indexType = IndexType.createPrimaryKey(table.getPersistent(), primaryKeyHash);
String indexName = table.getSchema().getUniqueIndexName(table, Constants.PREFIX_PRIMARY_KEY); String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY);
int id = getObjectId(true, false); int id = getObjectId(true, false);
try { try {
index = table.addIndex(session, indexName, id, indexColumns, indexType, Index.EMPTY_HEAD, null); index = table.addIndex(session, indexName, id, indexColumns, indexType, Index.EMPTY_HEAD, null);
...@@ -262,7 +262,7 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -262,7 +262,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
} }
indexType.setBelongsToConstraint(true); indexType.setBelongsToConstraint(true);
String prefix = constraintName == null ? "CONSTRAINT" : constraintName; String prefix = constraintName == null ? "CONSTRAINT" : constraintName;
String indexName = t.getSchema().getUniqueIndexName(t, prefix + "_INDEX_"); String indexName = t.getSchema().getUniqueIndexName(session, t, prefix + "_INDEX_");
try { try {
return t.addIndex(session, indexName, indexId, cols, indexType, Index.EMPTY_HEAD, null); return t.addIndex(session, indexName, indexId, cols, indexType, Index.EMPTY_HEAD, null);
} finally { } finally {
......
...@@ -65,11 +65,11 @@ public class CreateIndex extends SchemaCommand { ...@@ -65,11 +65,11 @@ public class CreateIndex extends SchemaCommand {
} }
int id = getObjectId(true, false); int id = getObjectId(true, false);
if (primaryKey) { if (primaryKey) {
indexName = table.getSchema().getUniqueIndexName(table, Constants.PREFIX_PRIMARY_KEY); indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_PRIMARY_KEY);
} else if (indexName == null) { } else if (indexName == null) {
indexName = table.getSchema().getUniqueIndexName(table, Constants.PREFIX_INDEX); indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_INDEX);
} }
if (getSchema().findIndex(indexName) != null) { if (getSchema().findIndex(session, indexName) != null) {
if (ifNotExists) { if (ifNotExists) {
return 0; return 0;
} }
......
...@@ -42,7 +42,7 @@ public class DropIndex extends SchemaCommand { ...@@ -42,7 +42,7 @@ public class DropIndex extends SchemaCommand {
public int update() throws SQLException { public int update() throws SQLException {
session.commit(true); session.commit(true);
Database db = session.getDatabase(); Database db = session.getDatabase();
Index index = getSchema().findIndex(indexName); Index index = getSchema().findIndex(session, indexName);
if (index == null) { if (index == null) {
if (!ifExists) { if (!ifExists) {
throw Message.getSQLException(ErrorCode.INDEX_NOT_FOUND_1, indexName); throw Message.getSQLException(ErrorCode.INDEX_NOT_FOUND_1, indexName);
......
...@@ -1567,6 +1567,12 @@ public class Database implements DataHandler { ...@@ -1567,6 +1567,12 @@ public class Database implements DataHandler {
session.removeLocalTempTable(table); session.removeLocalTempTable(table);
return; return;
} }
} else if (obj.getType() == DbObject.INDEX) {
Index index = (Index) obj;
if (index.getTable().getTemporary() && !index.getTable().getGlobalTemporary()) {
session.removeLocalTempTableIndex(index);
return;
}
} }
checkWritingAllowed(); checkWritingAllowed();
Comment comment = findComment(obj); Comment comment = findComment(obj);
......
...@@ -20,6 +20,7 @@ import org.h2.command.Prepared; ...@@ -20,6 +20,7 @@ import org.h2.command.Prepared;
import org.h2.command.dml.SetTypes; import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.index.Index;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.log.InDoubtTransaction; import org.h2.log.InDoubtTransaction;
import org.h2.log.LogSystem; import org.h2.log.LogSystem;
...@@ -65,6 +66,7 @@ public class Session implements SessionInterface { ...@@ -65,6 +66,7 @@ public class Session implements SessionInterface {
private HashMap savepoints; private HashMap savepoints;
private Exception stackTrace = new Exception(); private Exception stackTrace = new Exception();
private HashMap localTempTables; private HashMap localTempTables;
private HashMap localTempTableIndexes;
private int throttle; private int throttle;
private long lastThrottle; private long lastThrottle;
private Command currentCommand; private Command currentCommand;
...@@ -157,6 +159,11 @@ public class Session implements SessionInterface { ...@@ -157,6 +159,11 @@ public class Session implements SessionInterface {
return v == null ? ValueNull.INSTANCE : v; return v == null ? ValueNull.INSTANCE : v;
} }
/**
* Get the list of variable names that are set for this session.
*
* @return the list of names
*/
public String[] getVariableNames() { public String[] getVariableNames() {
if (variables == null) { if (variables == null) {
return new String[0]; return new String[0];
...@@ -174,19 +181,17 @@ public class Session implements SessionInterface { ...@@ -174,19 +181,17 @@ public class Session implements SessionInterface {
* @return the table, or null * @return the table, or null
*/ */
public Table findLocalTempTable(String name) { public Table findLocalTempTable(String name) {
Table t = null; if (localTempTables == null) {
if (localTempTables != null) { return null;
t = (Table) localTempTables.get(name);
} }
return t; return (Table) localTempTables.get(name);
} }
public ObjectArray getLocalTempTables() { public ObjectArray getLocalTempTables() {
if (localTempTables == null) { if (localTempTables == null) {
return new ObjectArray(); return new ObjectArray();
} }
ObjectArray list = new ObjectArray(localTempTables.values()); return new ObjectArray(localTempTables.values());
return list;
} }
/** /**
...@@ -217,6 +222,53 @@ public class Session implements SessionInterface { ...@@ -217,6 +222,53 @@ public class Session implements SessionInterface {
table.removeChildrenAndResources(this); table.removeChildrenAndResources(this);
} }
/**
* Get the local temporary index if one exists with that name, or null if
* not.
*
* @param name the table name
* @return the table, or null
*/
public Index findLocalTempTableIndex(String name) {
if (localTempTableIndexes == null) {
return null;
}
return (Index) localTempTableIndexes.get(name);
}
public HashMap getLocalTempTableIndexes() {
if (localTempTableIndexes == null) {
return new HashMap();
}
return localTempTableIndexes;
}
/**
* Add a local temporary index to this session.
*
* @param index the index to add
* @throws SQLException if a index with this name already exists
*/
public void addLocalTempTableIndex(Index index) throws SQLException {
if (localTempTableIndexes == null) {
localTempTableIndexes = new HashMap();
}
if (localTempTableIndexes.get(index.getName()) != null) {
throw Message.getSQLException(ErrorCode.INDEX_ALREADY_EXISTS_1, index.getSQL());
}
localTempTableIndexes.put(index.getName(), index);
}
/**
* Drop and remove the given local temporary index from this session.
*
* @param index the index
*/
public void removeLocalTempTableIndex(Index index) throws SQLException {
localTempTableIndexes.remove(index.getName());
index.removeChildrenAndResources(this);
}
protected void finalize() { protected void finalize() {
if (!SysProperties.runFinalize) { if (!SysProperties.runFinalize) {
return; return;
......
...@@ -224,11 +224,16 @@ public class Schema extends DbObjectBase { ...@@ -224,11 +224,16 @@ public class Schema extends DbObjectBase {
* Try to find an index with this name. This method returns null if * Try to find an index with this name. This method returns null if
* no object with this name exists. * no object with this name exists.
* *
* @param session the session
* @param name the object name * @param name the object name
* @return the object or null * @return the object or null
*/ */
public Index findIndex(String name) { public Index findIndex(Session session, String name) {
return (Index) indexes.get(name); Index index = (Index) indexes.get(name);
if (index == null) {
index = session.findLocalTempTableIndex(name);
}
return index;
} }
/** /**
...@@ -326,8 +331,14 @@ public class Schema extends DbObjectBase { ...@@ -326,8 +331,14 @@ public class Schema extends DbObjectBase {
* @param prefix the index name prefix * @param prefix the index name prefix
* @return the unique name * @return the unique name
*/ */
public String getUniqueIndexName(Table table, String prefix) { public String getUniqueIndexName(Session session, Table table, String prefix) {
return getUniqueName(table, indexes, prefix); HashMap tableIndexes;
if (table.getTemporary() && !table.getGlobalTemporary()) {
tableIndexes = session.getLocalTempTableIndexes();
} else {
tableIndexes = indexes;
}
return getUniqueName(table, tableIndexes, prefix);
} }
/** /**
......
...@@ -219,7 +219,11 @@ public class TableData extends Table implements RecordReader { ...@@ -219,7 +219,11 @@ public class TableData extends Table implements RecordReader {
index.setTemporary(temporary); index.setTemporary(temporary);
if (index.getCreateSQL() != null) { if (index.getCreateSQL() != null) {
index.setComment(indexComment); index.setComment(indexComment);
database.addSchemaObject(session, index); if (temporary && !getGlobalTemporary()) {
session.addLocalTempTableIndex(index);
} else {
database.addSchemaObject(session, index);
}
// Need to update, because maybe the index is rebuilt at startup, // Need to update, because maybe the index is rebuilt at startup,
// and so the head pos may have changed, which needs to be stored now. // and so the head pos may have changed, which needs to be stored now.
// addSchemaObject doesn't update the sys table at startup // addSchemaObject doesn't update the sys table at startup
......
...@@ -43,6 +43,7 @@ public class TestTempTables extends TestBase { ...@@ -43,6 +43,7 @@ public class TestTempTables extends TestBase {
conn2.createStatement().executeUpdate("create local temporary table test(id int)"); conn2.createStatement().executeUpdate("create local temporary table test(id int)");
conn2.createStatement().executeUpdate("create index idx_id on test(id)"); conn2.createStatement().executeUpdate("create index idx_id on test(id)");
conn2.createStatement().executeUpdate("drop index idx_id"); conn2.createStatement().executeUpdate("drop index idx_id");
conn2.createStatement().executeUpdate("drop table test");
conn2.createStatement().executeUpdate("create table test(id int)"); conn2.createStatement().executeUpdate("create table test(id int)");
conn2.createStatement().executeUpdate("create index idx_id on test(id)"); conn2.createStatement().executeUpdate("create index idx_id on test(id)");
conn1.createStatement().executeUpdate("drop table test"); conn1.createStatement().executeUpdate("drop table test");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论