提交 56e947ef authored 作者: Thomas Mueller's avatar Thomas Mueller

Linked tables now support default values.

上级 218b14f3
...@@ -96,15 +96,7 @@ public class Update extends Prepared { ...@@ -96,15 +96,7 @@ public class Update extends Prepared {
newValue = oldRow.getValue(i); newValue = oldRow.getValue(i);
} else if (newExpr == ValueExpression.getDefault()) { } else if (newExpr == ValueExpression.getDefault()) {
Column column = table.getColumn(i); Column column = table.getColumn(i);
Expression defaultExpr = column.getDefaultExpression(); newValue = table.getDefaultValue(session, column);
Value v;
if (defaultExpr == null) {
v = column.validateConvertUpdateSequence(session, null);
} else {
v = defaultExpr.getValue(session);
}
int type = column.getType();
newValue = v.convertTo(type);
} else { } else {
Column column = table.getColumn(i); Column column = table.getColumn(i);
newValue = newExpr.getValue(session).convertTo(column.getType()); newValue = newExpr.getValue(session).convertTo(column.getType());
......
...@@ -55,8 +55,10 @@ public class LinkedIndex extends BaseIndex { ...@@ -55,8 +55,10 @@ public class LinkedIndex extends BaseIndex {
buff.append(targetTableName).append(" VALUES("); buff.append(targetTableName).append(" VALUES(");
for (int i = 0; i < row.getColumnCount(); i++) { for (int i = 0; i < row.getColumnCount(); i++) {
Value v = row.getValue(i); Value v = row.getValue(i);
buff.appendExceptFirst(","); buff.appendExceptFirst(", ");
if (isNull(v)) { if (v == null) {
buff.append("DEFAULT");
} else if (isNull(v)) {
buff.append("NULL"); buff.append("NULL");
} else { } else {
buff.append('?'); buff.append('?');
...@@ -221,7 +223,13 @@ public class LinkedIndex extends BaseIndex { ...@@ -221,7 +223,13 @@ public class LinkedIndex extends BaseIndex {
buff.append(targetTableName).append(" SET "); buff.append(targetTableName).append(" SET ");
for (int i = 0; i < newRow.getColumnCount(); i++) { for (int i = 0; i < newRow.getColumnCount(); i++) {
buff.appendExceptFirst(", "); buff.appendExceptFirst(", ");
buff.append(table.getColumn(i).getSQL()).append("=?"); buff.append(table.getColumn(i).getSQL()).append('=');
Value v = newRow.getValue(i);
if (v == null) {
buff.append("DEFAULT");
} else {
buff.append('?');
}
} }
buff.append(" WHERE "); buff.append(" WHERE ");
buff.resetCount(); buff.resetCount();
...@@ -243,8 +251,11 @@ public class LinkedIndex extends BaseIndex { ...@@ -243,8 +251,11 @@ public class LinkedIndex extends BaseIndex {
int j = 1; int j = 1;
PreparedStatement prep = link.getPreparedStatement(sql, false); PreparedStatement prep = link.getPreparedStatement(sql, false);
for (int i = 0; i < newRow.getColumnCount(); i++) { for (int i = 0; i < newRow.getColumnCount(); i++) {
newRow.getValue(i).set(prep, j); Value v = newRow.getValue(i);
j++; if (v != null) {
v.set(prep, j);
j++;
}
} }
for (int i = 0; i < oldRow.getColumnCount(); i++) { for (int i = 0; i < oldRow.getColumnCount(); i++) {
Value v = oldRow.getValue(i); Value v = oldRow.getValue(i);
......
...@@ -62,24 +62,29 @@ public class RowList { ...@@ -62,24 +62,29 @@ public class RowList {
buff.writeInt(r.getStorageId()); buff.writeInt(r.getStorageId());
for (int i = 0; i < r.getColumnCount(); i++) { for (int i = 0; i < r.getColumnCount(); i++) {
Value v = r.getValue(i); Value v = r.getValue(i);
if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) { if (v == null) {
// need to keep a reference to temporary lobs, buff.writeByte((byte) 0);
// otherwise the temp file is deleted } else {
ValueLob lob = (ValueLob) v; buff.writeByte((byte) 1);
if (lob.getSmall() == null && lob.getTableId() == 0) { if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) {
if (lobs == null) { // need to keep a reference to temporary lobs,
lobs = ObjectArray.newInstance(); // otherwise the temp file is deleted
ValueLob lob = (ValueLob) v;
if (lob.getSmall() == null && lob.getTableId() == 0) {
if (lobs == null) {
lobs = ObjectArray.newInstance();
}
// need to create a copy, otherwise,
// if stored multiple times, it may be renamed
// and then not found
lob = lob.copyToTemp();
lobs.add(lob);
v = lob;
} }
// need to create a copy, otherwise,
// if stored multiple times, it may be renamed
// and then not found
lob = lob.copyToTemp();
lobs.add(lob);
v = lob;
} }
buff.checkCapacity(buff.getValueLen(v));
buff.writeValue(v);
} }
buff.checkCapacity(buff.getValueLen(v));
buff.writeValue(v);
} }
} }
...@@ -180,13 +185,18 @@ public class RowList { ...@@ -180,13 +185,18 @@ public class RowList {
int storageId = buff.readInt(); int storageId = buff.readInt();
Value[] values = new Value[columnCount]; Value[] values = new Value[columnCount];
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Value v = buff.readValue(); Value v;
if (v.isLinked()) { if (buff.readByte() == 0) {
ValueLob lob = (ValueLob) v; v = null;
// the table id is 0 if it was linked when writing } else {
// a temporary entry v = buff.readValue();
if (lob.getTableId() == 0) { if (v.isLinked()) {
session.unlinkAtCommit(lob); ValueLob lob = (ValueLob) v;
// the table id is 0 if it was linked when writing
// a temporary entry
if (lob.getTableId() == 0) {
session.unlinkAtCommit(lob);
}
} }
} }
values[i] = v; values[i] = v;
......
...@@ -18,6 +18,7 @@ import org.h2.engine.Constants; ...@@ -18,6 +18,7 @@ import org.h2.engine.Constants;
import org.h2.engine.DbObject; import org.h2.engine.DbObject;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.expression.ExpressionVisitor; import org.h2.expression.ExpressionVisitor;
import org.h2.index.Index; import org.h2.index.Index;
import org.h2.index.IndexType; import org.h2.index.IndexType;
...@@ -936,4 +937,23 @@ public abstract class Table extends SchemaObjectBase { ...@@ -936,4 +937,23 @@ public abstract class Table extends SchemaObjectBase {
return compareMode; return compareMode;
} }
/**
* Get or generate a default value for the given column.
*
* @param session the session
* @param column the column
* @return the value
*/
public Value getDefaultValue(Session session, Column column) throws SQLException {
Expression defaultExpr = column.getDefaultExpression();
Value v;
if (defaultExpr == null) {
v = column.validateConvertUpdateSequence(session, null);
} else {
v = defaultExpr.getValue(session);
}
int type = column.getType();
return v.convertTo(type);
}
} }
...@@ -33,6 +33,7 @@ import org.h2.util.New; ...@@ -33,6 +33,7 @@ import org.h2.util.New;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueDate; import org.h2.value.ValueDate;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
...@@ -542,4 +543,37 @@ public class TableLink extends Table { ...@@ -542,4 +543,37 @@ public class TableLink extends Table {
return false; return false;
} }
/**
* Convert the values if required. Default values are not set (kept as
* null).
*
* @param session the session
* @param row the row
*/
public void validateConvertUpdateSequence(Session session, Row row) throws SQLException {
for (int i = 0; i < columns.length; i++) {
Value value = row.getValue(i);
if (value != null) {
// null means use the default value
Column column = columns[i];
Value v2 = column.validateConvertUpdateSequence(session, value);
if (v2 != value) {
row.setValue(i, v2);
}
}
}
}
/**
* Get or generate a default value for the given column. Default values are
* not set (kept as null).
*
* @param session the session
* @param column the column
* @return the value
*/
public Value getDefaultValue(Session session, Column column) {
return null;
}
} }
...@@ -33,6 +33,7 @@ public class TestLinkedTable extends TestBase { ...@@ -33,6 +33,7 @@ public class TestLinkedTable extends TestBase {
} }
public void test() throws SQLException { public void test() throws SQLException {
testDefaultValues();
testHiddenSQL(); testHiddenSQL();
// testLinkAutoAdd(); // testLinkAutoAdd();
testNestedQueriesToSameTable(); testNestedQueriesToSameTable();
...@@ -50,6 +51,47 @@ public class TestLinkedTable extends TestBase { ...@@ -50,6 +51,47 @@ public class TestLinkedTable extends TestBase {
deleteDb("linkedTable"); deleteDb("linkedTable");
} }
private void testDefaultValues() throws SQLException {
if (config.memory) {
return;
}
deleteDb("linkedTable");
Connection connMain = DriverManager.getConnection("jdbc:h2:mem:linkedTable");
Statement statMain = connMain.createStatement();
statMain.execute("create table test(id identity, name varchar default 'test')");
Connection conn = getConnection("linkedTable");
Statement stat = conn.createStatement();
stat.execute("create linked table test1('', 'jdbc:h2:mem:linkedTable', '', '', 'TEST') emit updates");
stat.execute("create linked table test2('', 'jdbc:h2:mem:linkedTable', '', '', 'TEST')");
stat.execute("insert into test1 values(default, default)");
stat.execute("insert into test2 values(default, default)");
stat.execute("merge into test2 values(3, default)");
stat.execute("update test1 set name=default where id=1");
stat.execute("update test2 set name=default where id=2");
ResultSet rs = statMain.executeQuery("select * from test order by id");
rs.next();
assertEquals(1, rs.getInt(1));
assertEquals("test", rs.getString(2));
rs.next();
assertEquals(2, rs.getInt(1));
assertEquals("test", rs.getString(2));
rs.next();
assertEquals(3, rs.getInt(1));
assertEquals("test", rs.getString(2));
assertFalse(rs.next());
stat.execute("delete from test1 where id=1");
stat.execute("delete from test2 where id=2");
stat.execute("delete from test2 where id=3");
conn.close();
rs = statMain.executeQuery("select * from test order by id");
assertFalse(rs.next());
connMain.close();
}
private void testHiddenSQL() throws SQLException { private void testHiddenSQL() throws SQLException {
if (config.memory || !SysProperties.SHARE_LINKED_CONNECTIONS) { if (config.memory || !SysProperties.SHARE_LINKED_CONNECTIONS) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论