提交 58a30eba authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Return generated keys only if explicitly requested

上级 6fc3314f
...@@ -149,7 +149,7 @@ public abstract class Command implements CommandInterface { ...@@ -149,7 +149,7 @@ public abstract class Command implements CommandInterface {
@Override @Override
public void stop() { public void stop() {
session.endStatement(); session.endStatement();
session.setCurrentCommand(null); session.setCurrentCommand(null, false);
if (!isTransactional()) { if (!isTransactional()) {
session.commit(true); session.commit(true);
} else if (session.getAutoCommit()) { } else if (session.getAutoCommit()) {
...@@ -193,7 +193,7 @@ public abstract class Command implements CommandInterface { ...@@ -193,7 +193,7 @@ public abstract class Command implements CommandInterface {
} }
} }
synchronized (sync) { synchronized (sync) {
session.setCurrentCommand(this); session.setCurrentCommand(this, false);
try { try {
while (true) { while (true) {
database.checkPowerOff(); database.checkPowerOff();
...@@ -238,7 +238,7 @@ public abstract class Command implements CommandInterface { ...@@ -238,7 +238,7 @@ public abstract class Command implements CommandInterface {
} }
@Override @Override
public int executeUpdate() { public int executeUpdate(Object generatedKeysRequest) {
long start = 0; long start = 0;
Database database = session.getDatabase(); Database database = session.getDatabase();
Object sync = database.isMultiThreaded() ? (Object) session : (Object) database; Object sync = database.isMultiThreaded() ? (Object) session : (Object) database;
...@@ -252,7 +252,7 @@ public abstract class Command implements CommandInterface { ...@@ -252,7 +252,7 @@ public abstract class Command implements CommandInterface {
} }
synchronized (sync) { synchronized (sync) {
Session.Savepoint rollback = session.setSavepoint(); Session.Savepoint rollback = session.setSavepoint();
session.setCurrentCommand(this); session.setCurrentCommand(this, generatedKeysRequest);
try { try {
while (true) { while (true) {
database.checkPowerOff(); database.checkPowerOff();
......
...@@ -510,9 +510,16 @@ public interface CommandInterface { ...@@ -510,9 +510,16 @@ public interface CommandInterface {
/** /**
* Execute the statement * Execute the statement
* *
* @param generatedKeysRequest
* {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*
* @return the update count * @return the update count
*/ */
int executeUpdate(); int executeUpdate(Object generatedKeysRequest);
/** /**
* Stop the command execution, release all locks and resources * Stop the command execution, release all locks and resources
......
...@@ -39,7 +39,7 @@ class CommandList extends Command { ...@@ -39,7 +39,7 @@ class CommandList extends Command {
@Override @Override
public int update() { public int update() {
int updateCount = command.executeUpdate(); int updateCount = command.executeUpdate(false);
executeRemaining(); executeRemaining();
return updateCount; return updateCount;
} }
......
...@@ -194,7 +194,7 @@ public class CommandRemote implements CommandInterface { ...@@ -194,7 +194,7 @@ public class CommandRemote implements CommandInterface {
} }
@Override @Override
public int executeUpdate() { public int executeUpdate(Object generatedKeys) {
checkParameters(); checkParameters();
synchronized (session) { synchronized (session) {
int updateCount = 0; int updateCount = 0;
...@@ -206,6 +206,29 @@ public class CommandRemote implements CommandInterface { ...@@ -206,6 +206,29 @@ public class CommandRemote implements CommandInterface {
session.traceOperation("COMMAND_EXECUTE_UPDATE", id); session.traceOperation("COMMAND_EXECUTE_UPDATE", id);
transfer.writeInt(SessionRemote.COMMAND_EXECUTE_UPDATE).writeInt(id); transfer.writeInt(SessionRemote.COMMAND_EXECUTE_UPDATE).writeInt(id);
sendParameters(transfer); sendParameters(transfer);
if (session.getClientVersion() >= Constants.TCP_PROTOCOL_VERSION_17) {
if (Boolean.FALSE.equals(generatedKeys)) {
transfer.writeInt(0);
} else if (Boolean.TRUE.equals(generatedKeys)) {
transfer.writeInt(1);
} else if (generatedKeys instanceof int[]) {
int[] keys = (int[]) generatedKeys;
transfer.writeInt(2);
transfer.writeInt(keys.length);
for (int key : keys) {
transfer.writeInt(key);
}
} else if (generatedKeys instanceof String[]) {
String[] keys = (String[]) generatedKeys;
transfer.writeInt(3);
transfer.writeInt(keys.length);
for (String key : keys) {
transfer.writeString(key);
}
} else {
transfer.writeInt(0);
}
}
session.done(transfer); session.done(transfer);
updateCount = transfer.readInt(); updateCount = transfer.readInt();
autoCommit = transfer.readBoolean(); autoCommit = transfer.readBoolean();
......
...@@ -148,6 +148,7 @@ public class Insert extends Prepared implements ResultTarget { ...@@ -148,6 +148,7 @@ public class Insert extends Prepared implements ResultTarget {
if (listSize > 0) { if (listSize > 0) {
int columnLen = columns.length; int columnLen = columns.length;
GeneratedKeys generatedKeys = session.getGeneratedKeys(); GeneratedKeys generatedKeys = session.getGeneratedKeys();
generatedKeys.initialize(table);
for (int x = 0; x < listSize; x++) { for (int x = 0; x < listSize; x++) {
session.startStatementWithinTransaction(); session.startStatementWithinTransaction();
generatedKeys.nextRow(); generatedKeys.nextRow();
......
...@@ -90,6 +90,7 @@ public class Merge extends Prepared { ...@@ -90,6 +90,7 @@ public class Merge extends Prepared {
// process values in list // process values in list
count = 0; count = 0;
GeneratedKeys generatedKeys = session.getGeneratedKeys(); GeneratedKeys generatedKeys = session.getGeneratedKeys();
generatedKeys.initialize(targetTable);
for (int x = 0, size = valuesExpressionList.size(); x < size; x++) { for (int x = 0, size = valuesExpressionList.size(); x < size; x++) {
setCurrentRowNumber(x + 1); setCurrentRowNumber(x + 1);
generatedKeys.nextRow(); generatedKeys.nextRow();
......
...@@ -100,6 +100,11 @@ public class Constants { ...@@ -100,6 +100,11 @@ public class Constants {
*/ */
public static final int TCP_PROTOCOL_VERSION_16 = 16; public static final int TCP_PROTOCOL_VERSION_16 = 16;
/**
* The TCP protocol version number 17.
*/
public static final int TCP_PROTOCOL_VERSION_17 = 17;
/** /**
* The major version of this database. * The major version of this database.
*/ */
......
...@@ -203,7 +203,7 @@ public class Engine implements SessionFactory { ...@@ -203,7 +203,7 @@ public class Engine implements SessionFactory {
CommandInterface command = session.prepareCommand( CommandInterface command = session.prepareCommand(
"SET " + Parser.quoteIdentifier(setting) + " " + value, "SET " + Parser.quoteIdentifier(setting) + " " + value,
Integer.MAX_VALUE); Integer.MAX_VALUE);
command.executeUpdate(); command.executeUpdate(false);
} catch (DbException e) { } catch (DbException e) {
if (e.getErrorCode() == ErrorCode.ADMIN_RIGHTS_REQUIRED) { if (e.getErrorCode() == ErrorCode.ADMIN_RIGHTS_REQUIRED) {
session.getTrace().error(e, "admin rights required; user: \"" + session.getTrace().error(e, "admin rights required; user: \"" +
...@@ -221,7 +221,7 @@ public class Engine implements SessionFactory { ...@@ -221,7 +221,7 @@ public class Engine implements SessionFactory {
try { try {
CommandInterface command = session.prepareCommand(init, CommandInterface command = session.prepareCommand(init,
Integer.MAX_VALUE); Integer.MAX_VALUE);
command.executeUpdate(); command.executeUpdate(false);
} catch (DbException e) { } catch (DbException e) {
if (!ignoreUnknownSetting) { if (!ignoreUnknownSetting) {
session.close(); session.close();
......
...@@ -10,7 +10,9 @@ import java.util.Collections; ...@@ -10,7 +10,9 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.h2.message.DbException;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
...@@ -27,18 +29,34 @@ public final class GeneratedKeys { ...@@ -27,18 +29,34 @@ public final class GeneratedKeys {
private final ArrayList<Column> columns = New.arrayList(); private final ArrayList<Column> columns = New.arrayList();
private Object generatedKeysRequest;
private Table table;
public void add(Column column, Value value) { public void add(Column column, Value value) {
if (Boolean.FALSE.equals(generatedKeysRequest)) {
return;
}
row.add(column); row.add(column);
row.add(value.getObject()); row.add(value.getObject());
} }
public void clear() { public void clear(Object generatedKeysRequest) {
this.generatedKeysRequest = generatedKeysRequest;
data.clear(); data.clear();
row.clear(); row.clear();
columns.clear(); columns.clear();
table = null;
}
public void initialize(Table table) {
this.table = table;
} }
public void confirmRow() { public void confirmRow() {
if (Boolean.FALSE.equals(generatedKeysRequest)) {
return;
}
int size = row.size(); int size = row.size();
if (size > 0) { if (size > 0) {
if (size == 2) { if (size == 2) {
...@@ -64,14 +82,56 @@ public final class GeneratedKeys { ...@@ -64,14 +82,56 @@ public final class GeneratedKeys {
public SimpleResultSet getKeys() { public SimpleResultSet getKeys() {
SimpleResultSet rs = new SimpleResultSet(); SimpleResultSet rs = new SimpleResultSet();
for (Column column : columns) { if (Boolean.FALSE.equals(generatedKeysRequest)) {
rs.addColumn(column.getName(), DataType.convertTypeToSQLType(column.getType()), return rs;
MathUtils.convertLongToInt(column.getPrecision()), column.getScale()); }
if (Boolean.TRUE.equals(generatedKeysRequest)) {
for (Column column : columns) {
rs.addColumn(column.getName(), DataType.convertTypeToSQLType(column.getType()),
MathUtils.convertLongToInt(column.getPrecision()), column.getScale());
}
} else if (generatedKeysRequest instanceof int[]) {
if (table != null) {
int[] indices = (int[]) generatedKeysRequest;
Column[] columns = table.getColumns();
int cnt = columns.length;
for (int idx : indices) {
if (idx >= 1 && idx <= cnt) {
Column column = columns[idx - 1];
rs.addColumn(column.getName(), DataType.convertTypeToSQLType(column.getType()),
MathUtils.convertLongToInt(column.getPrecision()), column.getScale());
}
}
} else {
return rs;
}
} else if (generatedKeysRequest instanceof String[]) {
if (table != null) {
String[] names = (String[]) generatedKeysRequest;
for (String name : names) {
try {
Column column = table.getColumn(name);
rs.addColumn(column.getName(), DataType.convertTypeToSQLType(column.getType()),
MathUtils.convertLongToInt(column.getPrecision()), column.getScale());
} catch (DbException e) {
}
}
} else {
return rs;
}
} else {
return rs;
}
if (rs.getColumnCount() == 0) {
return rs;
} }
for (Map<Column, Object> map : data) { for (Map<Column, Object> map : data) {
Object[] row = new Object[columns.size()]; Object[] row = new Object[columns.size()];
for (Map.Entry<Column, Object> entry : map.entrySet()) { for (Map.Entry<Column, Object> entry : map.entrySet()) {
row[columns.indexOf(entry.getKey())] = entry.getValue(); int idx = columns.indexOf(entry.getKey());
if (idx >= 0) {
row[idx] = entry.getValue();
}
} }
rs.addRow(row); rs.addRow(row);
} }
......
...@@ -1245,13 +1245,19 @@ public class Session extends SessionWithState { ...@@ -1245,13 +1245,19 @@ public class Session extends SessionWithState {
* executing the statement. * executing the statement.
* *
* @param command the command * @param command the command
*/ * @param generated keys request
public void setCurrentCommand(Command command) { * {@code false} if generated keys are not needed, {@code true} if
* generated keys should be configured automatically, {@code int[]}
* to specify column indices to return generated keys from, or
* {@code String[]} to specify column names to return generated keys
* from
*/
public void setCurrentCommand(Command command, Object generatedKeysRequest) {
this.currentCommand = command; this.currentCommand = command;
// Preserve generated keys in case of a new query so they can be read with // Preserve generated keys in case of a new query so they can be read with
// CALL GET_GENERATED_KEYS() // CALL GET_GENERATED_KEYS()
if (command != null && !command.isQuery() && generatedKeys != null) { if (command != null && !command.isQuery()) {
generatedKeys.clear(); getGeneratedKeys().clear(generatedKeysRequest);
} }
if (queryTimeout > 0 && command != null) { if (queryTimeout > 0 && command != null) {
currentCommandStart = System.currentTimeMillis(); currentCommandStart = System.currentTimeMillis();
......
...@@ -118,7 +118,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -118,7 +118,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
trans.setSSL(ci.isSSL()); trans.setSSL(ci.isSSL());
trans.init(); trans.init();
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_6); trans.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
trans.writeInt(Constants.TCP_PROTOCOL_VERSION_16); trans.writeInt(Constants.TCP_PROTOCOL_VERSION_17);
trans.writeString(db); trans.writeString(db);
trans.writeString(ci.getOriginalURL()); trans.writeString(ci.getOriginalURL());
trans.writeString(ci.getUserName()); trans.writeString(ci.getUserName());
...@@ -210,7 +210,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -210,7 +210,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
CommandInterface c = prepareCommand( CommandInterface c = prepareCommand(
"SET CLUSTER " + serverList, Integer.MAX_VALUE); "SET CLUSTER " + serverList, Integer.MAX_VALUE);
// this will set autoCommit to false // this will set autoCommit to false
c.executeUpdate(); c.executeUpdate(false);
// so we need to switch it on // so we need to switch it on
autoCommit = true; autoCommit = true;
cluster = true; cluster = true;
...@@ -265,13 +265,13 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -265,13 +265,13 @@ public class SessionRemote extends SessionWithState implements DataHandler {
autoCommitTrue = prepareCommand( autoCommitTrue = prepareCommand(
"SET AUTOCOMMIT TRUE", Integer.MAX_VALUE); "SET AUTOCOMMIT TRUE", Integer.MAX_VALUE);
} }
autoCommitTrue.executeUpdate(); autoCommitTrue.executeUpdate(false);
} else { } else {
if (autoCommitFalse == null) { if (autoCommitFalse == null) {
autoCommitFalse = prepareCommand( autoCommitFalse = prepareCommand(
"SET AUTOCOMMIT FALSE", Integer.MAX_VALUE); "SET AUTOCOMMIT FALSE", Integer.MAX_VALUE);
} }
autoCommitFalse.executeUpdate(); autoCommitFalse.executeUpdate(false);
} }
} }
} }
...@@ -468,7 +468,7 @@ public class SessionRemote extends SessionWithState implements DataHandler { ...@@ -468,7 +468,7 @@ public class SessionRemote extends SessionWithState implements DataHandler {
private void switchOffCluster() { private void switchOffCluster() {
CommandInterface ci = prepareCommand("SET CLUSTER ''", Integer.MAX_VALUE); CommandInterface ci = prepareCommand("SET CLUSTER ''", Integer.MAX_VALUE);
ci.executeUpdate(); ci.executeUpdate(false);
} }
/** /**
......
...@@ -29,7 +29,7 @@ abstract class SessionWithState implements SessionInterface { ...@@ -29,7 +29,7 @@ abstract class SessionWithState implements SessionInterface {
try { try {
for (String sql : sessionState) { for (String sql : sessionState) {
CommandInterface ci = prepareCommand(sql, Integer.MAX_VALUE); CommandInterface ci = prepareCommand(sql, Integer.MAX_VALUE);
ci.executeUpdate(); ci.executeUpdate(false);
} }
} finally { } finally {
sessionStateUpdating = false; sessionStateUpdating = false;
......
...@@ -950,7 +950,8 @@ public class FullText { ...@@ -950,7 +950,8 @@ public class FullText {
useOwnConnection = isMultiThread(conn); useOwnConnection = isMultiThread(conn);
if(!useOwnConnection) { if(!useOwnConnection) {
for (int i = 0; i < SQL.length; i++) { for (int i = 0; i < SQL.length; i++) {
prepStatements[i] = conn.prepareStatement(SQL[i]); prepStatements[i] = conn.prepareStatement(SQL[i],
Statement.RETURN_GENERATED_KEYS);
} }
} }
} }
...@@ -1154,7 +1155,9 @@ public class FullText { ...@@ -1154,7 +1155,9 @@ public class FullText {
} }
private PreparedStatement getStatement(Connection conn, int index) throws SQLException { private PreparedStatement getStatement(Connection conn, int index) throws SQLException {
return useOwnConnection ? conn.prepareStatement(SQL[index]) : prepStatements[index]; return useOwnConnection ?
conn.prepareStatement(SQL[index], Statement.RETURN_GENERATED_KEYS)
: prepStatements[index];
} }
} }
......
...@@ -47,7 +47,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements ...@@ -47,7 +47,7 @@ public class JdbcCallableStatement extends JdbcPreparedStatement implements
JdbcCallableStatement(JdbcConnection conn, String sql, int id, JdbcCallableStatement(JdbcConnection conn, String sql, int id,
int resultSetType, int resultSetConcurrency) { int resultSetType, int resultSetConcurrency) {
super(conn, sql, id, resultSetType, resultSetConcurrency, false); super(conn, sql, id, resultSetType, resultSetConcurrency, false, false);
setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id); setTrace(session.getTrace(), TraceObject.CALLABLE_STATEMENT, id);
} }
......
...@@ -300,7 +300,7 @@ public class JdbcConnection extends TraceObject ...@@ -300,7 +300,7 @@ public class JdbcConnection extends TraceObject
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, return new JdbcPreparedStatement(this, sql, id,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_FORWARD_ONLY,
Constants.DEFAULT_RESULT_SET_CONCURRENCY, false); Constants.DEFAULT_RESULT_SET_CONCURRENCY, false, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -326,7 +326,7 @@ public class JdbcConnection extends TraceObject ...@@ -326,7 +326,7 @@ public class JdbcConnection extends TraceObject
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, return new JdbcPreparedStatement(this, sql, id,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_FORWARD_ONLY,
Constants.DEFAULT_RESULT_SET_CONCURRENCY, true); Constants.DEFAULT_RESULT_SET_CONCURRENCY, true, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -491,7 +491,7 @@ public class JdbcConnection extends TraceObject ...@@ -491,7 +491,7 @@ public class JdbcConnection extends TraceObject
checkClosedForWrite(); checkClosedForWrite();
try { try {
commit = prepareCommand("COMMIT", commit); commit = prepareCommand("COMMIT", commit);
commit.executeUpdate(); commit.executeUpdate(false);
} finally { } finally {
afterWriting(); afterWriting();
} }
...@@ -689,7 +689,7 @@ public class JdbcConnection extends TraceObject ...@@ -689,7 +689,7 @@ public class JdbcConnection extends TraceObject
checkClosed(); checkClosed();
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, resultSetType, return new JdbcPreparedStatement(this, sql, id, resultSetType,
resultSetConcurrency, false); resultSetConcurrency, false, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -744,7 +744,7 @@ public class JdbcConnection extends TraceObject ...@@ -744,7 +744,7 @@ public class JdbcConnection extends TraceObject
setLockMode = prepareCommand("SET LOCK_MODE ?", setLockMode); setLockMode = prepareCommand("SET LOCK_MODE ?", setLockMode);
setLockMode.getParameters().get(0).setValue(ValueInt.get(lockMode), setLockMode.getParameters().get(0).setValue(ValueInt.get(lockMode),
false); false);
setLockMode.executeUpdate(); setLockMode.executeUpdate(false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -761,7 +761,7 @@ public class JdbcConnection extends TraceObject ...@@ -761,7 +761,7 @@ public class JdbcConnection extends TraceObject
setQueryTimeout); setQueryTimeout);
setQueryTimeout.getParameters().get(0) setQueryTimeout.getParameters().get(0)
.setValue(ValueInt.get(seconds * 1000), false); .setValue(ValueInt.get(seconds * 1000), false);
setQueryTimeout.executeUpdate(); setQueryTimeout.executeUpdate(false);
queryTimeoutCache = seconds; queryTimeoutCache = seconds;
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
...@@ -1017,7 +1017,7 @@ public class JdbcConnection extends TraceObject ...@@ -1017,7 +1017,7 @@ public class JdbcConnection extends TraceObject
CommandInterface set = prepareCommand( CommandInterface set = prepareCommand(
"SAVEPOINT " + JdbcSavepoint.getName(null, savepointId), "SAVEPOINT " + JdbcSavepoint.getName(null, savepointId),
Integer.MAX_VALUE); Integer.MAX_VALUE);
set.executeUpdate(); set.executeUpdate(false);
JdbcSavepoint savepoint = new JdbcSavepoint(this, savepointId, null, JdbcSavepoint savepoint = new JdbcSavepoint(this, savepointId, null,
trace, id); trace, id);
savepointId++; savepointId++;
...@@ -1045,7 +1045,7 @@ public class JdbcConnection extends TraceObject ...@@ -1045,7 +1045,7 @@ public class JdbcConnection extends TraceObject
CommandInterface set = prepareCommand( CommandInterface set = prepareCommand(
"SAVEPOINT " + JdbcSavepoint.getName(name, 0), "SAVEPOINT " + JdbcSavepoint.getName(name, 0),
Integer.MAX_VALUE); Integer.MAX_VALUE);
set.executeUpdate(); set.executeUpdate(false);
JdbcSavepoint savepoint = new JdbcSavepoint(this, 0, name, trace, JdbcSavepoint savepoint = new JdbcSavepoint(this, 0, name, trace,
id); id);
return savepoint; return savepoint;
...@@ -1131,7 +1131,7 @@ public class JdbcConnection extends TraceObject ...@@ -1131,7 +1131,7 @@ public class JdbcConnection extends TraceObject
checkClosed(); checkClosed();
sql = translateSQL(sql); sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id, resultSetType, return new JdbcPreparedStatement(this, sql, id, resultSetType,
resultSetConcurrency, false); resultSetConcurrency, false, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1151,11 +1151,19 @@ public class JdbcConnection extends TraceObject ...@@ -1151,11 +1151,19 @@ public class JdbcConnection extends TraceObject
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException { throws SQLException {
try { try {
int id = getNextId(TraceObject.PREPARED_STATEMENT);
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("prepareStatement(" + quote(sql) + ", " debugCodeAssign("PreparedStatement",
+ autoGeneratedKeys + ");"); TraceObject.PREPARED_STATEMENT, id,
"prepareStatement(" + quote(sql) + ", "
+ autoGeneratedKeys + ");");
} }
return prepareStatement(sql); checkClosed();
sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id,
ResultSet.TYPE_FORWARD_ONLY,
Constants.DEFAULT_RESULT_SET_CONCURRENCY, false,
autoGeneratedKeys == Statement.RETURN_GENERATED_KEYS);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1175,11 +1183,18 @@ public class JdbcConnection extends TraceObject ...@@ -1175,11 +1183,18 @@ public class JdbcConnection extends TraceObject
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException { throws SQLException {
try { try {
int id = getNextId(TraceObject.PREPARED_STATEMENT);
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("prepareStatement(" + quote(sql) + ", " debugCodeAssign("PreparedStatement",
+ quoteIntArray(columnIndexes) + ");"); TraceObject.PREPARED_STATEMENT, id,
"prepareStatement(" + quote(sql) + ", "
+ quoteIntArray(columnIndexes) + ");");
} }
return prepareStatement(sql); checkClosed();
sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id,
ResultSet.TYPE_FORWARD_ONLY,
Constants.DEFAULT_RESULT_SET_CONCURRENCY, false, columnIndexes);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1199,11 +1214,18 @@ public class JdbcConnection extends TraceObject ...@@ -1199,11 +1214,18 @@ public class JdbcConnection extends TraceObject
public PreparedStatement prepareStatement(String sql, String[] columnNames) public PreparedStatement prepareStatement(String sql, String[] columnNames)
throws SQLException { throws SQLException {
try { try {
int id = getNextId(TraceObject.PREPARED_STATEMENT);
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("prepareStatement(" + quote(sql) + ", " debugCodeAssign("PreparedStatement",
+ quoteArray(columnNames) + ");"); TraceObject.PREPARED_STATEMENT, id,
"prepareStatement(" + quote(sql) + ", "
+ quoteArray(columnNames) + ");");
} }
return prepareStatement(sql); checkClosed();
sql = translateSQL(sql);
return new JdbcPreparedStatement(this, sql, id,
ResultSet.TYPE_FORWARD_ONLY,
Constants.DEFAULT_RESULT_SET_CONCURRENCY, false, columnNames);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1530,7 +1552,7 @@ public class JdbcConnection extends TraceObject ...@@ -1530,7 +1552,7 @@ public class JdbcConnection extends TraceObject
private void rollbackInternal() { private void rollbackInternal() {
rollback = prepareCommand("ROLLBACK", rollback); rollback = prepareCommand("ROLLBACK", rollback);
rollback.executeUpdate(); rollback.executeUpdate(false);
} }
/** /**
......
...@@ -63,11 +63,13 @@ public class JdbcPreparedStatement extends JdbcStatement implements ...@@ -63,11 +63,13 @@ public class JdbcPreparedStatement extends JdbcStatement implements
private ArrayList<Value[]> batchParameters; private ArrayList<Value[]> batchParameters;
private MergedResultSet batchIdentities; private MergedResultSet batchIdentities;
private HashMap<String, Integer> cachedColumnLabelMap; private HashMap<String, Integer> cachedColumnLabelMap;
private final Object generatedKeysRequest;
JdbcPreparedStatement(JdbcConnection conn, String sql, int id, JdbcPreparedStatement(JdbcConnection conn, String sql, int id,
int resultSetType, int resultSetConcurrency, int resultSetType, int resultSetConcurrency,
boolean closeWithResultSet) { boolean closeWithResultSet, Object generatedKeysRequest) {
super(conn, id, resultSetType, resultSetConcurrency, closeWithResultSet); super(conn, id, resultSetType, resultSetConcurrency, closeWithResultSet);
this.generatedKeysRequest = generatedKeysRequest;
setTrace(session.getTrace(), TraceObject.PREPARED_STATEMENT, id); setTrace(session.getTrace(), TraceObject.PREPARED_STATEMENT, id);
this.sqlStatement = sql; this.sqlStatement = sql;
command = conn.prepareCommand(sql, fetchSize); command = conn.prepareCommand(sql, fetchSize);
...@@ -193,7 +195,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements ...@@ -193,7 +195,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
synchronized (session) { synchronized (session) {
try { try {
setExecutingStatement(command); setExecutingStatement(command);
updateCount = command.executeUpdate(); updateCount = command.executeUpdate(generatedKeysRequest);
} finally { } finally {
setExecutingStatement(null); setExecutingStatement(null);
} }
...@@ -236,7 +238,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements ...@@ -236,7 +238,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements
updatable, cachedColumnLabelMap); updatable, cachedColumnLabelMap);
} else { } else {
returnsResultSet = false; returnsResultSet = false;
updateCount = command.executeUpdate(); updateCount = command.executeUpdate(generatedKeysRequest);
} }
} finally { } finally {
if (!lazy) { if (!lazy) {
......
...@@ -65,7 +65,7 @@ public class JdbcSavepoint extends TraceObject implements Savepoint { ...@@ -65,7 +65,7 @@ public class JdbcSavepoint extends TraceObject implements Savepoint {
checkValid(); checkValid();
conn.prepareCommand( conn.prepareCommand(
"ROLLBACK TO SAVEPOINT " + getName(name, savepointId), "ROLLBACK TO SAVEPOINT " + getName(name, savepointId),
Integer.MAX_VALUE).executeUpdate(); Integer.MAX_VALUE).executeUpdate(false);
} }
private void checkValid() { private void checkValid() {
......
...@@ -120,7 +120,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -120,7 +120,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public int executeUpdate(String sql) throws SQLException { public int executeUpdate(String sql) throws SQLException {
try { try {
debugCodeCall("executeUpdate", sql); debugCodeCall("executeUpdate", sql);
return executeUpdateInternal(sql); return executeUpdateInternal(sql, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -148,13 +148,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -148,13 +148,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public long executeLargeUpdate(String sql) throws SQLException { public long executeLargeUpdate(String sql) throws SQLException {
try { try {
debugCodeCall("executeLargeUpdate", sql); debugCodeCall("executeLargeUpdate", sql);
return executeUpdateInternal(sql); return executeUpdateInternal(sql, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
} }
private int executeUpdateInternal(String sql) throws SQLException { private int executeUpdateInternal(String sql, Object generatedKeysRequest) throws SQLException {
checkClosedForWrite(); checkClosedForWrite();
try { try {
closeOldResultSet(); closeOldResultSet();
...@@ -163,7 +163,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -163,7 +163,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
synchronized (session) { synchronized (session) {
setExecutingStatement(command); setExecutingStatement(command);
try { try {
updateCount = command.executeUpdate(); updateCount = command.executeUpdate(generatedKeysRequest);
} finally { } finally {
setExecutingStatement(null); setExecutingStatement(null);
} }
...@@ -191,13 +191,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -191,13 +191,13 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
public boolean execute(String sql) throws SQLException { public boolean execute(String sql) throws SQLException {
try { try {
debugCodeCall("execute", sql); debugCodeCall("execute", sql);
return executeInternal(sql); return executeInternal(sql, false);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
} }
private boolean executeInternal(String sql) throws SQLException { private boolean executeInternal(String sql, Object generatedKeysRequest) throws SQLException {
int id = getNextId(TraceObject.RESULT_SET); int id = getNextId(TraceObject.RESULT_SET);
checkClosedForWrite(); checkClosedForWrite();
try { try {
...@@ -219,7 +219,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -219,7 +219,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
closedByResultSet, scrollable, updatable); closedByResultSet, scrollable, updatable);
} else { } else {
returnsResultSet = false; returnsResultSet = false;
updateCount = command.executeUpdate(); updateCount = command.executeUpdate(generatedKeysRequest);
} }
} finally { } finally {
if (!lazy) { if (!lazy) {
...@@ -756,7 +756,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -756,7 +756,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
String sql = batchCommands.get(i); String sql = batchCommands.get(i);
try { try {
result[i] = executeUpdateInternal(sql); result[i] = executeUpdateInternal(sql, false);
} catch (Exception re) { } catch (Exception re) {
SQLException e = logAndConvert(re); SQLException e = logAndConvert(re);
if (next == null) { if (next == null) {
...@@ -894,7 +894,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -894,7 +894,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeUpdate("+quote(sql)+", "+autoGeneratedKeys+");"); debugCode("executeUpdate("+quote(sql)+", "+autoGeneratedKeys+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, autoGeneratedKeys == RETURN_GENERATED_KEYS);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -919,7 +919,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -919,7 +919,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeLargeUpdate("+quote(sql)+", "+autoGeneratedKeys+");"); debugCode("executeLargeUpdate("+quote(sql)+", "+autoGeneratedKeys+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, autoGeneratedKeys == RETURN_GENERATED_KEYS);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -944,7 +944,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -944,7 +944,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeUpdate("+quote(sql)+", "+quoteIntArray(columnIndexes)+");"); debugCode("executeUpdate("+quote(sql)+", "+quoteIntArray(columnIndexes)+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, columnIndexes);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -969,7 +969,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -969,7 +969,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeLargeUpdate("+quote(sql)+", "+quoteIntArray(columnIndexes)+");"); debugCode("executeLargeUpdate("+quote(sql)+", "+quoteIntArray(columnIndexes)+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, columnIndexes);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -994,7 +994,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -994,7 +994,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeUpdate("+quote(sql)+", "+quoteArray(columnNames)+");"); debugCode("executeUpdate("+quote(sql)+", "+quoteArray(columnNames)+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, columnNames);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1019,7 +1019,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -1019,7 +1019,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("executeLargeUpdate("+quote(sql)+", "+quoteArray(columnNames)+");"); debugCode("executeLargeUpdate("+quote(sql)+", "+quoteArray(columnNames)+");");
} }
return executeUpdateInternal(sql); return executeUpdateInternal(sql, columnNames);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1044,7 +1044,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -1044,7 +1044,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("execute("+quote(sql)+", "+autoGeneratedKeys+");"); debugCode("execute("+quote(sql)+", "+autoGeneratedKeys+");");
} }
return executeInternal(sql); return executeInternal(sql, autoGeneratedKeys == RETURN_GENERATED_KEYS);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1069,7 +1069,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -1069,7 +1069,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("execute("+quote(sql)+", "+quoteIntArray(columnIndexes)+");"); debugCode("execute("+quote(sql)+", "+quoteIntArray(columnIndexes)+");");
} }
return executeInternal(sql); return executeInternal(sql, columnIndexes);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -1094,7 +1094,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme ...@@ -1094,7 +1094,7 @@ public class JdbcStatement extends TraceObject implements Statement, JdbcStateme
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("execute("+quote(sql)+", "+quoteArray(columnNames)+");"); debugCode("execute("+quote(sql)+", "+quoteArray(columnNames)+");");
} }
return executeInternal(sql); return executeInternal(sql, columnNames);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
......
...@@ -91,12 +91,12 @@ public class TcpServerThread implements Runnable { ...@@ -91,12 +91,12 @@ public class TcpServerThread implements Runnable {
if (maxClientVersion < Constants.TCP_PROTOCOL_VERSION_6) { if (maxClientVersion < Constants.TCP_PROTOCOL_VERSION_6) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2,
"" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_6); "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_6);
} else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_16) { } else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_17) {
throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2,
"" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_16); "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_17);
} }
if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_16) { if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_17) {
clientVersion = Constants.TCP_PROTOCOL_VERSION_16; clientVersion = Constants.TCP_PROTOCOL_VERSION_17;
} else { } else {
clientVersion = maxClientVersion; clientVersion = maxClientVersion;
} }
...@@ -178,7 +178,7 @@ public class TcpServerThread implements Runnable { ...@@ -178,7 +178,7 @@ public class TcpServerThread implements Runnable {
RuntimeException closeError = null; RuntimeException closeError = null;
try { try {
Command rollback = session.prepareLocal("ROLLBACK"); Command rollback = session.prepareLocal("ROLLBACK");
rollback.executeUpdate(); rollback.executeUpdate(false);
} catch (RuntimeException e) { } catch (RuntimeException e) {
closeError = e; closeError = e;
server.traceError(e); server.traceError(e);
...@@ -302,7 +302,7 @@ public class TcpServerThread implements Runnable { ...@@ -302,7 +302,7 @@ public class TcpServerThread implements Runnable {
commit = session.prepareLocal("COMMIT"); commit = session.prepareLocal("COMMIT");
} }
int old = session.getModificationId(); int old = session.getModificationId();
commit.executeUpdate(); commit.executeUpdate(false);
transfer.writeInt(getState(old)).flush(); transfer.writeInt(getState(old)).flush();
break; break;
} }
...@@ -353,10 +353,41 @@ public class TcpServerThread implements Runnable { ...@@ -353,10 +353,41 @@ public class TcpServerThread implements Runnable {
int id = transfer.readInt(); int id = transfer.readInt();
Command command = (Command) cache.getObject(id, false); Command command = (Command) cache.getObject(id, false);
setParameters(command); setParameters(command);
Object generatedKeysRequest;
if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_17) {
int type = transfer.readInt();
switch (type) {
default:
generatedKeysRequest = false;
break;
case 1:
generatedKeysRequest = true;
break;
case 2: {
int len = transfer.readInt();
int[] keys = new int[len];
for (int i = 0; i < len; i++) {
keys[i] = transfer.readInt();
}
generatedKeysRequest = keys;
break;
}
case 3: {
int len = transfer.readInt();
String[] keys = new String[len];
for (int i = 0; i < len; i++) {
keys[i] = transfer.readString();
}
generatedKeysRequest = keys;
}
}
} else {
generatedKeysRequest = true;
}
int old = session.getModificationId(); int old = session.getModificationId();
int updateCount; int updateCount;
synchronized (session) { synchronized (session) {
updateCount = command.executeUpdate(); updateCount = command.executeUpdate(generatedKeysRequest);
} }
int status; int status;
if (session.isClosed()) { if (session.isClosed()) {
......
...@@ -1284,7 +1284,7 @@ public class WebApp { ...@@ -1284,7 +1284,7 @@ public class WebApp {
ResultSet rs; ResultSet rs;
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
boolean metadata = false; boolean metadata = false;
boolean generatedKeys = false; int generatedKeys = Statement.NO_GENERATED_KEYS;
boolean edit = false; boolean edit = false;
boolean list = false; boolean list = false;
if (isBuiltIn(sql, "@autocommit_true")) { if (isBuiltIn(sql, "@autocommit_true")) {
...@@ -1316,7 +1316,7 @@ public class WebApp { ...@@ -1316,7 +1316,7 @@ public class WebApp {
sql = sql.substring("@meta".length()).trim(); sql = sql.substring("@meta".length()).trim();
} }
if (isBuiltIn(sql, "@generated")) { if (isBuiltIn(sql, "@generated")) {
generatedKeys = true; generatedKeys = Statement.RETURN_GENERATED_KEYS;
sql = sql.substring("@generated".length()).trim(); sql = sql.substring("@generated".length()).trim();
} else if (isBuiltIn(sql, "@history")) { } else if (isBuiltIn(sql, "@history")) {
buff.append(getCommandHistoryString()); buff.append(getCommandHistoryString());
...@@ -1385,9 +1385,9 @@ public class WebApp { ...@@ -1385,9 +1385,9 @@ public class WebApp {
int maxrows = getMaxrows(); int maxrows = getMaxrows();
stat.setMaxRows(maxrows); stat.setMaxRows(maxrows);
session.executingStatement = stat; session.executingStatement = stat;
boolean isResultSet = stat.execute(sql); boolean isResultSet = stat.execute(sql, generatedKeys);
session.addCommand(sql); session.addCommand(sql);
if (generatedKeys) { if (generatedKeys == Statement.RETURN_GENERATED_KEYS) {
rs = null; rs = null;
rs = stat.getGeneratedKeys(); rs = stat.getGeneratedKeys();
} else { } else {
......
...@@ -211,7 +211,7 @@ public class FileLock implements Runnable { ...@@ -211,7 +211,7 @@ public class FileLock implements Runnable {
Transfer transfer = new Transfer(null, socket); Transfer transfer = new Transfer(null, socket);
transfer.init(); transfer.init();
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_6); transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_6);
transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_16); transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_17);
transfer.writeString(null); transfer.writeString(null);
transfer.writeString(null); transfer.writeString(null);
transfer.writeString(id); transfer.writeString(id);
......
...@@ -526,7 +526,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -526,7 +526,7 @@ public class TestPreparedStatement extends TestBase {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE TABLE TEST_UUID(id UUID DEFAULT " + stat.execute("CREATE TABLE TEST_UUID(id UUID DEFAULT " +
"random_UUID() PRIMARY KEY)"); "random_UUID() PRIMARY KEY)");
stat.execute("INSERT INTO TEST_UUID() VALUES()"); stat.execute("INSERT INTO TEST_UUID() VALUES()", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stat.getGeneratedKeys(); ResultSet rs = stat.getGeneratedKeys();
rs.next(); rs.next();
byte[] data = rs.getBytes(1); byte[] data = rs.getBytes(1);
...@@ -573,7 +573,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -573,7 +573,7 @@ public class TestPreparedStatement extends TestBase {
stat.execute("create sequence seq start with 1000"); stat.execute("create sequence seq start with 1000");
stat.execute("create trigger test_ins after insert on test call \"" + stat.execute("create trigger test_ins after insert on test call \"" +
SequenceTrigger.class.getName() + "\""); SequenceTrigger.class.getName() + "\"");
stat.execute("insert into test values(null)"); stat.execute("insert into test values(null)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stat.getGeneratedKeys(); ResultSet rs = stat.getGeneratedKeys();
rs.next(); rs.next();
// Generated key // Generated key
...@@ -1275,7 +1275,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -1275,7 +1275,7 @@ public class TestPreparedStatement extends TestBase {
stat.execute("CREATE TABLE TEST(ID INT)"); stat.execute("CREATE TABLE TEST(ID INT)");
PreparedStatement prep; PreparedStatement prep;
prep = conn.prepareStatement( prep = conn.prepareStatement(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"); "INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)", Statement.RETURN_GENERATED_KEYS);
prep.execute(); prep.execute();
ResultSet rs = prep.getGeneratedKeys(); ResultSet rs = prep.getGeneratedKeys();
rs.next(); rs.next();
...@@ -1317,7 +1317,6 @@ public class TestPreparedStatement extends TestBase { ...@@ -1317,7 +1317,6 @@ public class TestPreparedStatement extends TestBase {
prep.execute(); prep.execute();
rs = prep.getGeneratedKeys(); rs = prep.getGeneratedKeys();
rs.next(); rs.next();
assertEquals(5, rs.getInt(1));
assertFalse(rs.next()); assertFalse(rs.next());
stat.execute("DROP TABLE TEST"); stat.execute("DROP TABLE TEST");
...@@ -1369,7 +1368,8 @@ public class TestPreparedStatement extends TestBase { ...@@ -1369,7 +1368,8 @@ public class TestPreparedStatement extends TestBase {
stat.execute("drop sequence seq"); stat.execute("drop sequence seq");
stat.execute("create table test(id bigint auto_increment, value int)"); stat.execute("create table test(id bigint auto_increment, value int)");
stat.execute("insert into test(value) values (1), (2)"); stat.execute("insert into test(value) values (1), (2)",
Statement.RETURN_GENERATED_KEYS);
rs = stat.getGeneratedKeys(); rs = stat.getGeneratedKeys();
rs.next(); rs.next();
assertEquals(1L, rs.getLong(1)); assertEquals(1L, rs.getLong(1));
...@@ -1409,7 +1409,8 @@ public class TestPreparedStatement extends TestBase { ...@@ -1409,7 +1409,8 @@ public class TestPreparedStatement extends TestBase {
assertFalse(u1.equals(u2)); assertFalse(u1.equals(u2));
assertFalse(u2.equals(u3)); assertFalse(u2.equals(u3));
assertFalse(u3.equals(u4)); assertFalse(u3.equals(u4));
prep = conn.prepareStatement("merge into test(id, value) key (id) values (?, ?)"); prep = conn.prepareStatement("merge into test(id, value) key (id) values (?, ?)",
Statement.RETURN_GENERATED_KEYS);
prep.setObject(1, 2); prep.setObject(1, 2);
prep.setInt(2, 10); prep.setInt(2, 10);
prep.execute(); prep.execute();
...@@ -1427,7 +1428,8 @@ public class TestPreparedStatement extends TestBase { ...@@ -1427,7 +1428,8 @@ public class TestPreparedStatement extends TestBase {
stat.execute("create trigger test_insert before insert on test for each row call \"" stat.execute("create trigger test_insert before insert on test for each row call \""
+ TestGeneratedKeysTrigger.class.getName() + TestGeneratedKeysTrigger.class.getName()
+ '"'); + '"');
stat.executeUpdate("insert into test(value) values (10), (20)"); stat.executeUpdate("insert into test(value) values (10), (20)",
Statement.RETURN_GENERATED_KEYS);
rs = stat.getGeneratedKeys(); rs = stat.getGeneratedKeys();
rs.next(); rs.next();
u1 = (UUID) rs.getObject(1); u1 = (UUID) rs.getObject(1);
...@@ -1442,10 +1444,68 @@ public class TestPreparedStatement extends TestBase { ...@@ -1442,10 +1444,68 @@ public class TestPreparedStatement extends TestBase {
stat.execute("drop trigger test_insert"); stat.execute("drop trigger test_insert");
stat.execute("drop table test"); stat.execute("drop table test");
stat.execute("create table test(id bigint auto_increment, value int)");
stat.execute("insert into test(value) values (1)");
assertFalse(stat.getGeneratedKeys().next());
stat.execute("insert into test(value) values (1)", Statement.NO_GENERATED_KEYS);
assertFalse(stat.getGeneratedKeys().next());
stat.execute("insert into test(value) values (1)", Statement.RETURN_GENERATED_KEYS);
rs = stat.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(3, rs.getLong(1));
assertFalse(rs.next());
stat.execute("insert into test(value) values (1)", new int[0]);
assertFalse(stat.getGeneratedKeys().next());
stat.execute("insert into test(value) values (1)", new int[] { 1 });
rs = stat.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(5, rs.getLong(1));
assertFalse(rs.next());
stat.execute("insert into test(value) values (1)", new String[0]);
assertFalse(stat.getGeneratedKeys().next());
stat.execute("insert into test(value) values (1)", new String[] { "ID" });
rs = stat.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(7, rs.getLong(1));
assertFalse(rs.next());
prep = conn.prepareStatement("insert into test(value) values (1)");
prep.execute();
assertFalse(prep.getGeneratedKeys().next());
prep = conn.prepareStatement("insert into test(value) values (1)", Statement.NO_GENERATED_KEYS);
prep.execute();
assertFalse(prep.getGeneratedKeys().next());
prep = conn.prepareStatement("insert into test(value) values (1)", Statement.RETURN_GENERATED_KEYS);
prep.execute();
rs = prep.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(10, rs.getLong(1));
assertFalse(rs.next());
prep = conn.prepareStatement("insert into test(value) values (1)", new int[0]);
prep.execute();
assertFalse(prep.getGeneratedKeys().next());
prep = conn.prepareStatement("insert into test(value) values (1)", new int[] { 1 });
prep.execute();
rs = prep.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(12, rs.getLong(1));
assertFalse(rs.next());
prep = conn.prepareStatement("insert into test(value) values (1)", new String[0]);
prep.execute();
assertFalse(prep.getGeneratedKeys().next());
prep = conn.prepareStatement("insert into test(value) values (1)", new String[] { "ID" });
prep.execute();
rs = prep.getGeneratedKeys();
assertTrue(rs.next());
assertEquals(14, rs.getLong(1));
assertFalse(rs.next());
stat.execute("drop table test");
stat.execute("CREATE SEQUENCE SEQ"); stat.execute("CREATE SEQUENCE SEQ");
stat.execute("CREATE TABLE TEST(ID INT)"); stat.execute("CREATE TABLE TEST(ID INT)");
prep = conn.prepareStatement( prep = conn.prepareStatement(
"INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"); "INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)",
Statement.RETURN_GENERATED_KEYS);
prep.addBatch(); prep.addBatch();
prep.addBatch(); prep.addBatch();
prep.addBatch(); prep.addBatch();
......
...@@ -573,12 +573,14 @@ public class TestResultSet extends TestBase { ...@@ -573,12 +573,14 @@ public class TestResultSet extends TestBase {
ResultSet rs; ResultSet rs;
stat.execute("CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)"); stat.execute("CREATE TABLE TEST(ID IDENTITY NOT NULL, NAME VARCHAR NULL)");
stat.execute("INSERT INTO TEST(NAME) VALUES('Hello')"); stat.execute("INSERT INTO TEST(NAME) VALUES('Hello')",
Statement.RETURN_GENERATED_KEYS);
rs = stat.getGeneratedKeys(); rs = stat.getGeneratedKeys();
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(1, rs.getInt(1)); assertEquals(1, rs.getInt(1));
stat.execute("INSERT INTO TEST(NAME) VALUES('World')"); stat.execute("INSERT INTO TEST(NAME) VALUES('World')",
Statement.RETURN_GENERATED_KEYS);
rs = stat.getGeneratedKeys(); rs = stat.getGeneratedKeys();
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals(2, rs.getInt(1)); assertEquals(2, rs.getInt(1));
......
...@@ -351,16 +351,19 @@ public class TestStatement extends TestBase { ...@@ -351,16 +351,19 @@ public class TestStatement extends TestBase {
stat.execute("create table test1(id identity, x int)"); stat.execute("create table test1(id identity, x int)");
stat.execute("drop table if exists test2"); stat.execute("drop table if exists test2");
stat.execute("create table test2(id identity, x int)"); stat.execute("create table test2(id identity, x int)");
stat.execute("merge into test1(x) key(x) values(5)"); stat.execute("merge into test1(x) key(x) values(5)",
Statement.RETURN_GENERATED_KEYS);
ResultSet keys; ResultSet keys;
keys = stat.getGeneratedKeys(); keys = stat.getGeneratedKeys();
keys.next(); keys.next();
assertEquals(1, keys.getInt(1)); assertEquals(1, keys.getInt(1));
stat.execute("insert into test2(x) values(10), (11), (12)"); stat.execute("insert into test2(x) values(10), (11), (12)");
stat.execute("merge into test1(x) key(x) values(5)"); stat.execute("merge into test1(x) key(x) values(5)",
Statement.RETURN_GENERATED_KEYS);
keys = stat.getGeneratedKeys(); keys = stat.getGeneratedKeys();
assertFalse(keys.next()); assertFalse(keys.next());
stat.execute("merge into test1(x) key(x) values(6)"); stat.execute("merge into test1(x) key(x) values(6)",
Statement.RETURN_GENERATED_KEYS);
keys = stat.getGeneratedKeys(); keys = stat.getGeneratedKeys();
keys.next(); keys.next();
assertEquals(2, keys.getInt(1)); assertEquals(2, keys.getInt(1));
...@@ -371,7 +374,8 @@ public class TestStatement extends TestBase { ...@@ -371,7 +374,8 @@ public class TestStatement extends TestBase {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE SEQUENCE SEQ"); stat.execute("CREATE SEQUENCE SEQ");
stat.execute("CREATE TABLE TEST(ID INT)"); stat.execute("CREATE TABLE TEST(ID INT)");
stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)"); stat.execute("INSERT INTO TEST VALUES(NEXT VALUE FOR SEQ)",
Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stat.getGeneratedKeys(); ResultSet rs = stat.getGeneratedKeys();
rs.next(); rs.next();
assertEquals(1, rs.getInt(1)); assertEquals(1, rs.getInt(1));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论