提交 48d406c3 authored 作者: Thomas Mueller's avatar Thomas Mueller

LINKED TABLE: the schema name can now be set.

上级 44403978
...@@ -18,7 +18,10 @@ Change Log ...@@ -18,7 +18,10 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>LINKED TABLE: worked around a bug in Oracle with the CHAR data type. <ul><li>Result sets with just a unique index can now be updated (previously a primary key was required).
</li><li>LINKED TABLE: the schema name can now be set. When multiple tables exist in different schema,
and the schema name is not set, an exception is thrown.
</li><li>LINKED TABLE: worked around a bug in Oracle with the CHAR data type.
</li><li>Faster hash code calculation for large binary arrays. </li><li>Faster hash code calculation for large binary arrays.
</li><li>Faster storage re-use algorithm thanks to Greg Dhuse from cleversafe.com. </li><li>Faster storage re-use algorithm thanks to Greg Dhuse from cleversafe.com.
</li><li>The database supports the SHOW command for better MySQL and PostgreSQL compatibility. </li><li>The database supports the SHOW command for better MySQL and PostgreSQL compatibility.
......
...@@ -4517,7 +4517,12 @@ public class Parser { ...@@ -4517,7 +4517,12 @@ public class Parser {
read(","); read(",");
command.setPassword(readString()); command.setPassword(readString());
read(","); read(",");
command.setOriginalTable(readString()); String originalTable = readString();
if (readIf(",")) {
command.setOriginalSchema(originalTable);
originalTable = readString();
}
command.setOriginalTable(originalTable);
read(")"); read(")");
if (readIf("EMIT")) { if (readIf("EMIT")) {
read("UPDATES"); read("UPDATES");
......
...@@ -22,7 +22,7 @@ import org.h2.table.TableLink; ...@@ -22,7 +22,7 @@ import org.h2.table.TableLink;
public class CreateLinkedTable extends SchemaCommand { public class CreateLinkedTable extends SchemaCommand {
private String tableName; private String tableName;
private String driver, url, user, password, originalTable; private String driver, url, user, password, originalSchema, originalTable;
private boolean ifNotExists; private boolean ifNotExists;
private String comment; private String comment;
private boolean emitUpdates; private boolean emitUpdates;
...@@ -75,7 +75,7 @@ public class CreateLinkedTable extends SchemaCommand { ...@@ -75,7 +75,7 @@ public class CreateLinkedTable extends SchemaCommand {
tableName); tableName);
} }
int id = getObjectId(false, true); int id = getObjectId(false, true);
TableLink table = getSchema().createTableLink(id, tableName, driver, url, user, password, originalTable, emitUpdates, force); TableLink table = getSchema().createTableLink(id, tableName, driver, url, user, password, originalSchema, originalTable, emitUpdates, force);
table.setTemporary(temporary); table.setTemporary(temporary);
table.setGlobalTemporary(globalTemporary); table.setGlobalTemporary(globalTemporary);
table.setComment(comment); table.setComment(comment);
...@@ -112,4 +112,8 @@ public class CreateLinkedTable extends SchemaCommand { ...@@ -112,4 +112,8 @@ public class CreateLinkedTable extends SchemaCommand {
this.readOnly = readOnly; this.readOnly = readOnly;
} }
public void setOriginalSchema(String originalSchema) {
this.originalSchema = originalSchema;
}
} }
...@@ -1197,6 +1197,8 @@ public class ErrorCode { ...@@ -1197,6 +1197,8 @@ public class ErrorCode {
* The error with code <code>90080</code> is thrown when * The error with code <code>90080</code> is thrown when
* trying to rename a object to a different schema, or when trying to * trying to rename a object to a different schema, or when trying to
* create a related object in another schema. * create a related object in another schema.
* For CREATE LINKED TABLE, it is thrown when multiple tables with that
* name exist in different schemas.
* Example: * Example:
* <pre> * <pre>
* CREATE SCHEMA TEST_SCHEMA; * CREATE SCHEMA TEST_SCHEMA;
......
...@@ -404,11 +404,12 @@ CREATE INDEX IDXNAME ON TEST(NAME) ...@@ -404,11 +404,12 @@ CREATE INDEX IDXNAME ON TEST(NAME)
"Commands (DDL)","CREATE LINKED TABLE"," "Commands (DDL)","CREATE LINKED TABLE","
CREATE [[GLOBAL | LOCAL] TEMPORARY] LINKED TABLE [IF NOT EXISTS] CREATE [[GLOBAL | LOCAL] TEMPORARY] LINKED TABLE [IF NOT EXISTS]
name(driverString, urlString, name(driverString, urlString,
userString, passwordString, originalTableString) userString, passwordString, [originalSchemaString,] originalTableString)
[EMIT UPDATES | READONLY] [EMIT UPDATES | READONLY]
"," ","
Creates a table link to an external table. Creates a table link to an external table.
The driver name may be empty if the driver is already loaded. The driver name may be empty if the driver is already loaded.
If the schema name is not set, only one table with that name may exist in the target database.
Usually, for update statements, the old rows are deleted first Usually, for update statements, the old rows are deleted first
and then the new rows inserted. It is possible to emit update and then the new rows inserted. It is possible to emit update
statements (however this is not possible on rollback), however statements (however this is not possible on rollback), however
......
...@@ -466,8 +466,8 @@ public class Schema extends DbObjectBase { ...@@ -466,8 +466,8 @@ public class Schema extends DbObjectBase {
* @return the {@link TableLink} object * @return the {@link TableLink} object
*/ */
public TableLink createTableLink(int id, String tableName, String driver, String url, String user, String password, public TableLink createTableLink(int id, String tableName, String driver, String url, String user, String password,
String originalTable, boolean emitUpdates, boolean force) throws SQLException { String originalSchema, String originalTable, boolean emitUpdates, boolean force) throws SQLException {
return new TableLink(this, id, tableName, driver, url, user, password, originalTable, emitUpdates, force); return new TableLink(this, id, tableName, driver, url, user, password, originalSchema, originalTable, emitUpdates, force);
} }
} }
...@@ -39,7 +39,7 @@ import org.h2.value.DataType; ...@@ -39,7 +39,7 @@ import org.h2.value.DataType;
*/ */
public class TableLink extends Table { public class TableLink extends Table {
private String driver, url, user, password, originalTable, qualifiedTableName; private String driver, url, user, password, originalSchema, originalTable, qualifiedTableName;
private Connection conn; private Connection conn;
private HashMap prepared = new HashMap(); private HashMap prepared = new HashMap();
private final ObjectArray indexes = new ObjectArray(); private final ObjectArray indexes = new ObjectArray();
...@@ -53,12 +53,13 @@ public class TableLink extends Table { ...@@ -53,12 +53,13 @@ public class TableLink extends Table {
private boolean readOnly; private boolean readOnly;
public TableLink(Schema schema, int id, String name, String driver, String url, String user, String password, public TableLink(Schema schema, int id, String name, String driver, String url, String user, String password,
String originalTable, boolean emitUpdates, boolean force) throws SQLException { String originalSchema, String originalTable, boolean emitUpdates, boolean force) throws SQLException {
super(schema, id, name, false); super(schema, id, name, false);
this.driver = driver; this.driver = driver;
this.url = url; this.url = url;
this.user = user; this.user = user;
this.password = password; this.password = password;
this.originalSchema = originalSchema;
this.originalTable = originalTable; this.originalTable = originalTable;
this.emitUpdates = emitUpdates; this.emitUpdates = emitUpdates;
try { try {
...@@ -81,7 +82,12 @@ public class TableLink extends Table { ...@@ -81,7 +82,12 @@ public class TableLink extends Table {
storesLowerCase = meta.storesLowerCaseIdentifiers(); storesLowerCase = meta.storesLowerCaseIdentifiers();
storesMixedCase = meta.storesMixedCaseIdentifiers(); storesMixedCase = meta.storesMixedCaseIdentifiers();
supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers(); supportsMixedCaseIdentifiers = meta.supportsMixedCaseIdentifiers();
ResultSet rs = meta.getColumns(null, null, originalTable, null); ResultSet rs = meta.getTables(null, originalSchema, originalTable, null);
if (rs.next() && rs.next()) {
throw Message.getSQLException(ErrorCode.SCHEMA_NAME_MUST_MATCH, originalTable);
}
rs.close();
rs = meta.getColumns(null, originalSchema, originalTable, null);
int i = 0; int i = 0;
ObjectArray columnList = new ObjectArray(); ObjectArray columnList = new ObjectArray();
HashMap columnMap = new HashMap(); HashMap columnMap = new HashMap();
...@@ -114,6 +120,7 @@ public class TableLink extends Table { ...@@ -114,6 +120,7 @@ public class TableLink extends Table {
columnList.add(col); columnList.add(col);
columnMap.put(n, col); columnMap.put(n, col);
} }
rs.close();
if (originalTable.indexOf('.') < 0 && !StringUtils.isNullOrEmpty(schema)) { if (originalTable.indexOf('.') < 0 && !StringUtils.isNullOrEmpty(schema)) {
qualifiedTableName = schema + "." + originalTable; qualifiedTableName = schema + "." + originalTable;
} else { } else {
...@@ -143,6 +150,7 @@ public class TableLink extends Table { ...@@ -143,6 +150,7 @@ public class TableLink extends Table {
columnMap.put(n, col); columnMap.put(n, col);
} }
} }
rs.close();
} catch (SQLException e) { } catch (SQLException e) {
throw Message.getSQLException(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, new String[] { originalTable + "(" throw Message.getSQLException(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, new String[] { originalTable + "("
+ e.toString() + ")" }, e); + e.toString() + ")" }, e);
...@@ -156,7 +164,7 @@ public class TableLink extends Table { ...@@ -156,7 +164,7 @@ public class TableLink extends Table {
linkedIndex = new LinkedIndex(this, id, IndexColumn.wrap(cols), IndexType.createNonUnique(false)); linkedIndex = new LinkedIndex(this, id, IndexColumn.wrap(cols), IndexType.createNonUnique(false));
indexes.add(linkedIndex); indexes.add(linkedIndex);
try { try {
rs = meta.getPrimaryKeys(null, null, originalTable); rs = meta.getPrimaryKeys(null, originalSchema, originalTable);
} catch (SQLException e) { } catch (SQLException e) {
// Some ODBC bridge drivers don't support it: // Some ODBC bridge drivers don't support it:
// some combinations of "DataDirect SequeLink(R) for JDBC" // some combinations of "DataDirect SequeLink(R) for JDBC"
...@@ -182,9 +190,10 @@ public class TableLink extends Table { ...@@ -182,9 +190,10 @@ public class TableLink extends Table {
list.set(idx - 1, column); list.set(idx - 1, column);
} while (rs.next()); } while (rs.next());
addIndex(list, IndexType.createPrimaryKey(false, false)); addIndex(list, IndexType.createPrimaryKey(false, false));
rs.close();
} }
try { try {
rs = meta.getIndexInfo(null, null, originalTable, false, true); rs = meta.getIndexInfo(null, originalSchema, originalTable, false, true);
} catch (SQLException e) { } catch (SQLException e) {
// Oracle throws an exception if the table is not found or is a // Oracle throws an exception if the table is not found or is a
// SYNONYM // SYNONYM
...@@ -193,7 +202,8 @@ public class TableLink extends Table { ...@@ -193,7 +202,8 @@ public class TableLink extends Table {
String indexName = null; String indexName = null;
list = new ObjectArray(); list = new ObjectArray();
IndexType indexType = null; IndexType indexType = null;
while (rs != null && rs.next()) { if (rs != null) {
while (rs.next()) {
String newIndex = rs.getString("INDEX_NAME"); String newIndex = rs.getString("INDEX_NAME");
if (pkName.equals(newIndex)) { if (pkName.equals(newIndex)) {
continue; continue;
...@@ -213,6 +223,8 @@ public class TableLink extends Table { ...@@ -213,6 +223,8 @@ public class TableLink extends Table {
Column column = (Column) columnMap.get(col); Column column = (Column) columnMap.get(col);
list.add(column); list.add(column);
} }
rs.close();
}
if (indexName != null) { if (indexName != null) {
addIndex(list, indexType); addIndex(list, indexType);
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论