Thread: Re: AUTO_INCREMENT patch

Re: AUTO_INCREMENT patch

From
Rod Taylor
Date:
Moving to -hackers

> I'm working on getting auto-incrementing CMP fields in JBoss 3.2.1 to
> work with PostgreSQL data sources.  There are currently two obstacles
> to this.

Yeah.. JBoss is very annoying in this regard. A temporary solution seems
to be to use BEFORE triggers to force the sequence to be used for the
default value.  You could also do this with an INSTEAD rule (something
like the below):

CREATE OR REPLACE RULE rulename AS ON INSERT TO tablename DO INSTEAD  INSERT INTO tablename            ( id, col1, ...)
   VALUES ( DEFAULT, NEW.col1, ...); 



AUTO_INCREMENT is non-standard (MySQL only?), however the SQL200X
proposals do have support for the more common IDENTITY syntax which can
accomplish the same job as well as many others. (PostgreSQL does NOT
have the general identity implementation yet)

What you're looking for is the ability to force the column to use the
IDENTITY even when the client provides a specific value:

CREATE TABLE test(col integer GENERATED ALWAYS AS IDENTITY);

See sections 10.22, 10.23, 11.3, and 11.4 of the SQL200X working draft
for full details.

ftp://sqlstandards.org/SC32/WG3/Progression_Documents/FCD/4FCD1-02-Foundation-2002-01.pdf

DB2 and MSSql have implementations of the IDENTITY syntax if you want a
reference point.

Re: AUTO_INCREMENT patch

From
des@des.no (Dag-Erling Smørgrav)
Date:
Rod Taylor <rbt@rbt.ca> writes:
> Yeah.. JBoss is very annoying in this regard. A temporary solution seems
> to be to use BEFORE triggers to force the sequence to be used for the
> default value.  You could also do this with an INSTEAD rule (something
> like the below):
>
> CREATE OR REPLACE RULE rulename AS ON INSERT
>   TO tablename
>   DO INSTEAD
>    INSERT INTO tablename
>              ( id, col1, ...)
>       VALUES ( DEFAULT, NEW.col1, ...);

That's a good workaround for 3.2.1.  As regards the upcoming 3.2.2, I
just found out that it has PostgreSQL-specific code to handle this,
though it's an incomplete fix.  To summarize:
- add <entity-command>postgresql-fetch-seq</entity-command> to each  affected entity (or the <defaults> section) in
jbosscmp-jdbc.xml; this resolves the "failed to insert null" problem and also makes  sure JBoss knows the id of the
newlycreated row. 
- apply my auto_increment patch
- replace the bogus auto-increment template in the PostgreSQL and  PostgreSQL 7.2 mappings in standardjbosscmp-jdbc.xml
withthe  following: 
     <auto-increment-template>?1 AUTO_INCREMENT</auto-increment-template>
  the current template (?1) works if you set the corresponding  <cmp-field>'s <sql-type> to SERIAL - but if you define
arelation  that involves that field, the other endpoint will also be defined  as SERIAL!  Obviously that's not a recipe
forsuccess. 

> AUTO_INCREMENT is non-standard (MySQL only?), however the SQL200X
> proposals do have support for the more common IDENTITY syntax which can
> accomplish the same job as well as many others. (PostgreSQL does NOT
> have the general identity implementation yet)

the IDENTITY syntax is very similar to AUTO_INCREMENT, in fact you can
apply s/auto_increment/identity/ to my patch and have a useful subset
of it :) JBoss already knows about IDENTITY, since Hypersonic SQL and
MS SQL both support it.

(interestingly, JBoss doesn't seem to know that DB/2 also supports it)

> What you're looking for is the ability to force the column to use the
> IDENTITY even when the client provides a specific value:
>
> CREATE TABLE test(col integer GENERATED ALWAYS AS IDENTITY);

as mentioned above, that's no longer a problem with JBoss 3.2.2.

> See sections 10.22, 10.23, 11.3, and 11.4 of the SQL200X working draft
> for full details.
>
> ftp://sqlstandards.org/SC32/WG3/Progression_Documents/FCD/4FCD1-02-Foundation-2002-01.pdf

I believe this is more up to date:

ftp://sqlstandards.org/SC32/WG3/Progression_Documents/FDIS/4FDIS1-02-Foundation-2003.pdf

DES
--
Dag-Erling Smørgrav - des@des.no


Re: AUTO_INCREMENT patch

From
des@des.no (Dag-Erling Smørgrav)
Date:
Rod Taylor <rbt@rbt.ca> writes:
> CREATE OR REPLACE RULE rulename AS ON INSERT
>   TO tablename
>   DO INSTEAD
>    INSERT INTO tablename
>              ( id, col1, ...)
>       VALUES ( DEFAULT, NEW.col1, ...);
>

I now have a patch that adds support for the GENERATED ... AS ...
syntax and implements the "GENERATED BY DEFAULT AS IDENTITY" case.
I'm trying to figure out how to implement the other two cases
("GENERATED ALWAYS AS IDENTITY" and "GENERATED ALWAYS AS ( expr )").
I thought I'd try your trick:

des=# create table test ( id serial, word text );
NOTICE:  CREATE TABLE will create implicit sequence "test_id_seq" for SERIAL column "test.id"
CREATE TABLE
des=# create rule test_id_generate as
des-# on insert to test do instead
des-# insert into test ( id, word ) values ( default, new.word );
CREATE RULE
des=# insert into test ( id, word ) values ( 42, 'hello' );
ERROR:  infinite recursion detected in rules for relation "test"
des=# insert into test ( word ) values ( 'hello' );
ERROR:  infinite recursion detected in rules for relation "test"

any suggestions?

DES
--
Dag-Erling Smørgrav - des@des.no


Re: AUTO_INCREMENT patch

From
Rod Taylor
Date:
> des=# create table test ( id serial, word text );
> NOTICE:  CREATE TABLE will create implicit sequence "test_id_seq" for SERIAL column "test.id"
> CREATE TABLE
> des=# create rule test_id_generate as
> des-# on insert to test do instead
> des-# insert into test ( id, word ) values ( default, new.word );
> CREATE RULE
> des=# insert into test ( id, word ) values ( 42, 'hello' );
> ERROR:  infinite recursion detected in rules for relation "test"
> des=# insert into test ( word ) values ( 'hello' );
> ERROR:  infinite recursion detected in rules for relation "test"

Shoot, sorry, I forgot you will want to do this on a view. In my case I
have actually used 2 different schemas.  The JBoss user(s) have their
default search_path setup with jboss, data.  Updates and deletes are
equally fun.

You may find you prefer a trigger for this instead -- it won't complain
about recursion.

t=# begin;
BEGIN
t=# create schema data
t-#   create table test (id serial, word text);
NOTICE:  CREATE TABLE will create implicit sequence "test_id_seq" for
SERIAL column "test.id"
CREATE SCHEMA
t=#
t=# create schema jboss
t-#   create view test as select * from data.test;
CREATE SCHEMA
t=#
t=# create rule test_id_generate as on insert to jboss.test
t-#   do instead
t-#   insert into data.test (id, word) values (default, new.word);
CREATE RULE
t=#
t=# insert into jboss.test (word) values ('hello');
INSERT 17347 1
t=#
t=# insert into jboss.test (id, word) values (null, 'hello');
INSERT 17348 1
t=#
t=# insert into jboss.test (id, word) values ('22', 'hello');
INSERT 17349 1
t=#
t=#
t=# select * from jboss.test;id | word
----+------- 1 | hello 2 | hello 3 | hello
(3 rows)
t=# select * from data.test;id | word
----+------- 1 | hello 2 | hello 3 | hello
(3 rows)


Re: AUTO_INCREMENT patch

From
"Andrew Dunstan"
Date:
Rod Taylor wrote about using views for identity cols, thus:

t=# create schema jboss
t-#   create view test as select * from data.test;
CREATE SCHEMA
t=#
t=# create rule test_id_generate as on insert to jboss.test
t-#   do instead
t-#   insert into data.test (id, word) values (default, new.word);
CREATE RULE
t=#
t=# insert into jboss.test (word) values ('hello');
INSERT 17347 1

The docs currently state that views are read-only. Is this no longer true?

andrew