@Override protected final int execute(ExecuteContext ctx, ExecuteListener listener) throws SQLException { if (returning.isEmpty()) { return super.execute(ctx, listener); } else { int result = 1; ResultSet rs; switch (ctx.configuration().dialect()) { // SQLite can select _rowid_ after the insert case SQLITE: { listener.executeStart(ctx); result = ctx.statement().executeUpdate(); listener.executeEnd(ctx); DSLContext create = DSL.using(ctx.connection(), SQLDialect.SQLITE, ctx.configuration().settings()); returned = create .select(returning) .from(getInto()) .where(rowid().equal(rowid().getDataType().convert(create.lastID()))) .fetchInto(getInto()); return result; } // Sybase can select @@identity after the insert // TODO [#832] Fix this. This might be a driver issue. JDBC // Generated keys don't work with jconn3, but they seem to work // with jTDS (which is used for Sybase ASE integration) case CUBRID: case SYBASE: { listener.executeStart(ctx); result = ctx.statement().executeUpdate(); listener.executeEnd(ctx); selectReturning(ctx.configuration(), create(ctx.configuration()).lastID()); return result; } // Some dialects can only retrieve "identity" (AUTO_INCREMENT) values // Additional values have to be fetched explicitly // [#1260] TODO CUBRID supports this, but there's a JDBC bug case ASE: case DERBY: case H2: case INGRES: case MYSQL: case SQLSERVER: { listener.executeStart(ctx); result = ctx.statement().executeUpdate(); listener.executeEnd(ctx); rs = ctx.statement().getGeneratedKeys(); try { List<Object> list = new ArrayList<Object>(); // Some JDBC drivers seem to illegally return null // from getGeneratedKeys() sometimes if (rs != null) { while (rs.next()) { list.add(rs.getObject(1)); } } selectReturning(ctx.configuration(), list.toArray()); return result; } finally { JDBCUtils.safeClose(rs); } } // Firebird and Postgres can execute the INSERT .. RETURNING // clause like a select clause. JDBC support is not implemented // in the Postgres JDBC driver case FIREBIRD: case POSTGRES: { listener.executeStart(ctx); rs = ctx.statement().executeQuery(); listener.executeEnd(ctx); break; } // These dialects have full JDBC support case DB2: case HSQLDB: case ORACLE: default: { listener.executeStart(ctx); result = ctx.statement().executeUpdate(); listener.executeEnd(ctx); rs = ctx.statement().getGeneratedKeys(); break; } } ExecuteContext ctx2 = new DefaultExecuteContext(ctx.configuration()); ExecuteListener listener2 = new ExecuteListeners(ctx2); ctx2.resultSet(rs); returned = new CursorImpl<R>(ctx2, listener2, fieldArray(returning), null, true, false) .fetch() .into(getInto()); return result; } }