In Informix, a SERIAL column is a 4-byte signed integer with some auto-increment properties.
If you insert the value 0 into a SERIAL column, or fail to provide a value for the serial column, the next number in ascending order will automatically be assigned for this row. In a programming language such as ESQL/C, you can retrieve the value inserted from the SQLCA record. There are also, I think, functions to retrieve the last serial value inserted. If you insert a value into a SERIAL column, that is the value that will be use. Clearly, if there is a unique constraint on the column (there isn't one automatically, though the DB-Access Schema Editor will add one for you) and you insert a duplicate record, then the insertion will fail. If there is no unique constraint, it will succeed. If the newly inserted value, N, is larger than any previously inserted, then the internal counter will be incremented so that the next row inserted with 0 will be assigned N+1.
The second part of the question asks:
This leads to an answer for the first part of the question:
1 You can get a row where there is a zero in the SERIAL column, but only through a back-door cheat. You have to have the column as a plain INTEGER column when you insert the row; then you alter the table so the column is a SERIAL column. So, as I said, you can't insert a row with zero in the SERIAL column, but you can find a row with zero in the SERIAL column if someone is devious enough.
Demonstration
SQL commands prefixed with a +
and a blank; output from the DBMS without that prefix. Note that this table was created without a unique constraint or primary key on the serial column; this is not what I'd normally do.
+ begin work;
+ create table serial_x(s serial(100) not null);
+ insert into serial_x(s) values(0);
+ insert into serial_x(s) values(0);
+ insert into serial_x(s) values(0);
+ select * from serial_x;
100
101
102
+ delete from serial_x;
+ alter table serial_x modify(s serial(1));
+ insert into serial_x(s) values(0);
+ select * from serial_x;
103
+ alter table serial_x modify(s serial(1000));
+ insert into serial_x(s) values(0);
+ select * from serial_x;
103
1000
+ insert into serial_x values(2147483647);
+ select * from serial_x;
103
1000
2147483647
+ insert into serial_x values(-1);
+ insert into serial_x values(-1);
+ insert into serial_x values(0);
+ select * from serial_x;
103
1000
2147483647
-1
-1
1
+ rollback;
I formally checked that ALTER ... SERIAL(0)
produces the same result as ALTER ... SERIAL(1)
.