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

Local temporary tables now support indexes.

上级 cb83b7f3
......@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1>
<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
SQL statements that make up the session state. The list currently contains
variables (SET @..) and local temporary tables (without data).
......
......@@ -4412,7 +4412,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
command.setIndex(getSchema().findIndex(indexName));
command.setIndex(getSchema().findIndex(session, indexName));
}
return command;
} else if (database.getMode().indexDefinitionInCreateTable && (readIf("INDEX") || readIf("KEY"))) {
......@@ -4443,7 +4443,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
command.setIndex(getSchema().findIndex(indexName));
command.setIndex(getSchema().findIndex(session, indexName));
}
} else if (readIf("FOREIGN")) {
command = new AlterTableAddConstraint(session, schema);
......@@ -4453,7 +4453,7 @@ public class Parser {
command.setIndexColumns(parseIndexColumnList());
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
command.setIndex(schema.findIndex(indexName));
command.setIndex(schema.findIndex(session, indexName));
}
read("REFERENCES");
parseReferences(command, schema, tableName);
......@@ -4488,7 +4488,7 @@ public class Parser {
}
if (readIf("INDEX")) {
String indexName = readIdentifierWithSchema();
command.setRefIndex(getSchema().findIndex(indexName));
command.setRefIndex(getSchema().findIndex(session, indexName));
}
while (readIf("ON")) {
if (readIf("DELETE")) {
......
......@@ -40,7 +40,7 @@ public class AlterIndexRename extends DefineCommand {
session.commit(true);
Database db = session.getDatabase();
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);
}
session.getUser().checkRight(oldIndex.getTable(), Right.ALL);
......
......@@ -130,7 +130,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
}
if (index == null) {
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);
try {
index = table.addIndex(session, indexName, id, indexColumns, indexType, Index.EMPTY_HEAD, null);
......@@ -262,7 +262,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
}
indexType.setBelongsToConstraint(true);
String prefix = constraintName == null ? "CONSTRAINT" : constraintName;
String indexName = t.getSchema().getUniqueIndexName(t, prefix + "_INDEX_");
String indexName = t.getSchema().getUniqueIndexName(session, t, prefix + "_INDEX_");
try {
return t.addIndex(session, indexName, indexId, cols, indexType, Index.EMPTY_HEAD, null);
} finally {
......
......@@ -65,11 +65,11 @@ public class CreateIndex extends SchemaCommand {
}
int id = getObjectId(true, false);
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) {
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) {
return 0;
}
......
......@@ -42,7 +42,7 @@ public class DropIndex extends SchemaCommand {
public int update() throws SQLException {
session.commit(true);
Database db = session.getDatabase();
Index index = getSchema().findIndex(indexName);
Index index = getSchema().findIndex(session, indexName);
if (index == null) {
if (!ifExists) {
throw Message.getSQLException(ErrorCode.INDEX_NOT_FOUND_1, indexName);
......
......@@ -1567,6 +1567,12 @@ public class Database implements DataHandler {
session.removeLocalTempTable(table);
return;
}
} else if (obj.getType() == DbObject.INDEX) {
Index index = (Index) obj;
if (index.getTable().getTemporary() && !index.getTable().getGlobalTemporary()) {
session.removeLocalTempTableIndex(index);
return;
}
}
checkWritingAllowed();
Comment comment = findComment(obj);
......
......@@ -20,6 +20,7 @@ import org.h2.command.Prepared;
import org.h2.command.dml.SetTypes;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.index.Index;
import org.h2.jdbc.JdbcConnection;
import org.h2.log.InDoubtTransaction;
import org.h2.log.LogSystem;
......@@ -65,6 +66,7 @@ public class Session implements SessionInterface {
private HashMap savepoints;
private Exception stackTrace = new Exception();
private HashMap localTempTables;
private HashMap localTempTableIndexes;
private int throttle;
private long lastThrottle;
private Command currentCommand;
......@@ -157,6 +159,11 @@ public class Session implements SessionInterface {
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() {
if (variables == null) {
return new String[0];
......@@ -174,19 +181,17 @@ public class Session implements SessionInterface {
* @return the table, or null
*/
public Table findLocalTempTable(String name) {
Table t = null;
if (localTempTables != null) {
t = (Table) localTempTables.get(name);
if (localTempTables == null) {
return null;
}
return t;
return (Table) localTempTables.get(name);
}
public ObjectArray getLocalTempTables() {
if (localTempTables == null) {
return new ObjectArray();
}
ObjectArray list = new ObjectArray(localTempTables.values());
return list;
return new ObjectArray(localTempTables.values());
}
/**
......@@ -217,6 +222,53 @@ public class Session implements SessionInterface {
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() {
if (!SysProperties.runFinalize) {
return;
......
......@@ -224,11 +224,16 @@ public class Schema extends DbObjectBase {
* Try to find an index with this name. This method returns null if
* no object with this name exists.
*
* @param session the session
* @param name the object name
* @return the object or null
*/
public Index findIndex(String name) {
return (Index) indexes.get(name);
public Index findIndex(Session session, String 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 {
* @param prefix the index name prefix
* @return the unique name
*/
public String getUniqueIndexName(Table table, String prefix) {
return getUniqueName(table, indexes, prefix);
public String getUniqueIndexName(Session session, Table table, String 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 {
index.setTemporary(temporary);
if (index.getCreateSQL() != null) {
index.setComment(indexComment);
if (temporary && !getGlobalTemporary()) {
session.addLocalTempTableIndex(index);
} else {
database.addSchemaObject(session, index);
}
// 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.
// addSchemaObject doesn't update the sys table at startup
......
......@@ -43,6 +43,7 @@ public class TestTempTables extends TestBase {
conn2.createStatement().executeUpdate("create local temporary table test(id int)");
conn2.createStatement().executeUpdate("create index idx_id on test(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 index idx_id on test(id)");
conn1.createStatement().executeUpdate("drop table test");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论