Re: JDBC gripe list - Mailing list pgsql-jdbc

From MauMau
Subject Re: JDBC gripe list
Date
Msg-id 82360DA2A81A4F6197F346F445C71B2C@maumau
Whole thread Raw
In response to Re: JDBC gripe list  (Dave Cramer <pg@fastcrypt.com>)
Responses Re: JDBC gripe list
Re: JDBC gripe list
List pgsql-jdbc
Hello,


----- Original Message -----
From: "Dave Cramer" <pg@fastcrypt.com>
> So in general I'm having trouble understanding things where the
> implementation says we can do whatever we want you have a requirement
> ? For example getGeneratedKeys from a batch statement? What is it you
> are looking for ? AFAICT we are implementing the spec here. The fact
> that mysql does something else is irrelevant. Please note this is just
> a talking point since I do believe it is possible for us to return the
> generated keys here.

I think the most common use case is, or possibly the only real use case is,
to get auto-generated primary keys when you insert multiple rows at once
into a table which has a sequence. An example is shown in "14.1.4
PreparedStatement Objects" of JDBC 4.0 specification. The following code is
a slightly modified version of that example to use auto-generated keys.

CODE EXAMPLE 14-2 Creating and executing a batch of prepared statements
(slightly modified)
--------------------------------------------------
String[] cols = {"emp_id"};

// turn off autocommit
con.setAutoCommit(false);

PreparedStatement stmt = con.prepareStatement(
"INSERT INTO employees VALUES (?, ?)", cols);

stmt.setInt(1, 2000);
stmt.setString(2, "Kelly Kaufmann");
stmt.addBatch();

stmt.setInt(1, 3000);
stmt.setString(2, "Bill Barnes");
stmt.addBatch();

// submit the batch for execution
int[] updateCounts = stmt.executeBatch();
--------------------------------------------------


Though the table definition is not shown in the spec, assume the one below:

CREATE TABLE employees (
    emp_id SERIAL PRIMARY KEY,
    salary INT,
    name VARCHAR(20)
);

Then, pstmt.getGeneratedKeys() is expected to return a ResultSet that
contains two rows which consist only of emp_id column. The order of those
two rows should correspond to the order of employee records added in the
batch with addBatch().

My opinion is that the users should explicitly specify the columns they want
to be returned. I don't find it useful to specify
Statement.RETURN_GENERATED_KEYS, because the JDBC spec says that JDBC
drivers decide which columns are returned (i.e. implementation defined
behavior). Please keep this in mind when reading the next.

So which columns should be returned when you pass
Statement.RETURN_GENERATED_KEYS instead of "cols" to
Connection.prepareStatement() in the above example code? What if the table
does not have an auto-generated primary key?

I think it would be reasonable to return "ctid" system column when the user
specifies Statement.RETURN_GENERATED_KEYS, because he/she does not show any
intention about what he/she wants. For example, Oracle returns ROWID in this
case, as described as follows in the manual:

--------------------------------------------------
The getGeneratedKeys() method enables you to retrieve the auto-generated key
fields. The auto-generated keys are returned as a ResultSet object.
If key columns are not explicitly indicated, then Oracle JDBC drivers cannot
identify which columns need to be retrieved. When a column name or column
index array is used, Oracle JDBC drivers can identify which columns contain
auto-generated keys that you want to retrieve. However, when the
Statement.RETURN_GENERATED_KEYS integer flag is used, Oracle JDBC drivers
cannot identify these columns. When the integer flag is used to indicate
that auto-generated keys are to be returned, the ROWID pseudo column is
returned as key. The ROWID can be then fetched from the ResultSet object and
can be used to retrieved other columns.
--------------------------------------------------

What do you think?

Regards
MauMau



pgsql-jdbc by date:

Previous
From: Vitalii Tymchyshyn
Date:
Subject: Re: JDBC gripe list
Next
From: "Kevin Grittner"
Date:
Subject: Re: JDBC gripe list