-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull request 449 (associated with issue 446) breaks applications in the field and needs to be revisited #498
Comments
After a thorough investigation, I do not believe any action is required here.
|
From https://www.sqlite.org/autoinc.html :
|
In today's SWG meeting, @KRyden requested more time to review the issue. |
#517 should not be closed until this is completely adjudicated |
Reopening this issue because of feedback we received during open comment.
|
re: 1, The performance is significant on a large enough number of records, and the size overhead is also significant over a larger file. |
The size overhead is not significant, 4096 bytes for the added sqlite_sequence table. K6a was added to allow people to omit the keyword for performance at their own risk
I agree that point 2 appears to be false.
Suggestion for point 4, directly from the documentation:
|
Hi, I'm the technical lead on Keith's team for SQLite. There's some additional information that may explain better what we're getting on about, so let me expand on what's above.
sqlite> create table no_rowid_alias1 (id integer primary key desc);
sqlite> create table no_rowid_alias_autoinc1 (id integer primary key desc autoincrement);
Error: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY
sqlite> create table no_rowid_alias2 (id integer primary key) without rowid;
sqlite> create table no_rowid_alias_autoincrement2 (id integer primary key autoincrement) without rowid;
Error: AUTOINCREMENT not allowed on WITHOUT ROWID tables
sqlite> Notice that neither of the cases where the
sqlite> create table id_not_null (id integer primary key not null);
sqlite> create table id_without_not_null (id integer primary key);
sqlite> pragma table_info(id_not_null);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 1 1
sqlite> pragma table_info(id_without_not_null);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 0 1
sqlite> Notice the difference between the returned value for the Hopefully this clarifies what we've been going on about. |
Regarding to this quirk:
It is not a quirk, it is just bad documentation in the SQLite website. The description of the pragma
In the source code is more clear:
https://github.com/sqlite/sqlite/blob/b5aaee5e31c081b3ba5beeb563419f2d66be2656/src/pragma.c#L1135 The behaviour is as expected, the documentation is not. It should be:
|
Regarding 2, I put language into 1a28a78 indicating that the rowid alias SHALL be present. I'm not sure how to test this for this, though. On 3, we run into a testability issue. If we test for notnull, we would mark GeoPackages that don't set that flag as invalid even though there is no damage done, no risk to interoperability. |
(Oops! Sorry about the reply.) @fjlopez create table pk_is_internal_rowid_alias (id integer primary key);
pragma table_info (pk_is_internal_rowid_alias);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 0 1
insert into pk_is_internal_rowid_alias values (NULL);
select * from pk_is_internal_rowid_alias;
id
----------
1
create table pk_is_internal_rowid_alias_nn (id integer not null primary key);
pragma table_info (pk_is_internal_rowid_alias_nn);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 1 1
insert into pk_is_internal_rowid_alias_nn values (NULL);
select * from pk_is_internal_rowid_alias_nn;
id
----------
1
create table pk_is_not_internal_rowid_alias (id integer primary key desc);
pragma table_info (pk_is_not_internal_rowid_alias);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 0 1
insert into pk_is_not_internal_rowid_alias values (NULL);
select * from pk_is_not_internal_rowid_alias;
id
----------
create table pk_is_not_internal_rowid_alias_nn (id integer not null primary key desc);
pragma table_info (pk_is_not_internal_rowid_alias_nn);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 1 1
insert into pk_is_not_internal_rowid_alias_nn values (NULL);
Error: near line 18: NOT NULL constraint failed: pk_is_not_internal_rowid_alias_nn.id
create table pk_is_not_internal_rowid_alias_wr (id integer primary key) without rowid;
pragma table_info (pk_is_not_internal_rowid_alias_wr);
cid name type notnull dflt_value pk
---------- ---------- ---------- ---------- ---------- ----------
0 id integer 1 1
insert into pk_is_not_internal_rowid_alias_wr values (NULL);
Error: near line 22: NOT NULL constraint failed: pk_is_not_internal_rowid_alias_wr.id
sqlite> It seems a bit inconsistent in places. |
@jyutzler This section of the SQLite documentation gives you some background: https://www.sqlite.org/lang_createtable.html#rowid. I think the following criteria should work:
Both 3. and 4. could be replaced by requiring the string |
@jyutzler BTW, one possible minor issue with dealing with the alternate approach above, is SQLite allows 4 different ways of delimiting identifiers (5 if you count no delimiter): sqlite> select sql from sqlite_master;
sql
-----------------------------------------------------------
CREATE TABLE t1 (id integer primary key)
CREATE TABLE t2 ("id" integer primary key)
CREATE TABLE t3 ([id] integer primary key)
CREATE TABLE t4 (`id` integer primary key)
CREATE TABLE t5 ('id' integer primary key) So you would have to test for any of those. |
I think that a query for the rowid column can also help for the sqlite> create table id_pk(id integer primary key);
sqlite> select rowid from id_pk;
sqlite> create table id_pk_without_rowid(id integer primary key) without rowid;
sqlite> select rowid from id_pk_without_rowid;
Error: no such column: rowid |
|
@fjlopez Unless, of course, they create a column named sqlite> create table gotcha (rowid integer primary key) without rowid;
sqlite> select rowid from gotcha;
sqlite> However, using The pragma approach looks like a good alternative. If I were writing from a C/C++ that is what I would probably use. |
The pragma approach also works in the Xerial JDBC driver and since SQLITE 3.16 it is possible to use pragma functions: sqlite> select * from pragma_table_info('id_pk');
0|id|integer|0||1 |
In light of #446 (comment), is there any further action required in this ticket? |
@jyutzler I do not believe there is any further action required for this ticket. The Pull Request you referenced handles the issues very cleanly. Thanks you! |
Pull request #449's description is vague but is associated with a larger discussion in #446. There are several issues with this pull request - which has already been integrated into the working Geopackage document.
Issue#1 - the pull request removes the AUTOINCREMENT. AUTOINCREMENT is used in fielded software to allow SQLite to manage the unique row ID. The following code already in use in the field will no longer work without AUTOINCREMENT:
CREATE TABLE example1 (
id INTEGER PRIMARY KEY,
tag TEXT NOT NULL,
geom POINT);
And then insert like so:
INSERT INTO example1 (tag,geom)
VALUES (‘Row 1’,ST_GeomFromText(‘POINT (1 1)’,4326));
In this example, ID is autogenerated by SQLite - without this, the application would have to manage the rowid.
Issue#2: AUTOINCREMENT is still referenced in several tables - was the intent to remove it everywhere (which would be bad as discussed above)?
Issue#3: Requirement 150 probably does not meet modular specification requirements:
Requirement 150
A feature table or view SHALL have a column that uniquely identifies the row. For a feature table, the column SHOULD be an integer primary key. If there is no primary key column, the first column SHALL be of type INTEGER and SHALL contain unique values for each row.
The "SHOULD" would prevent Requirement 150 from being a testable requirement, and really doesn't add anything. this needs to be reviewed.
Issue#4: it's not clear that quorum was present for the adoption of this change. The wiki page shows 11 voting members, but only five present - 6 would be needed for quorum (50%, but odd number so +1). https://portal.opengeospatial.org/wiki/GEOPACKAGEswg/06-May-2019 - it's quite possible somebody else was there or came in late and was not logged as present - this is merely an observation.
Bottom line, issue#1 removal of AUTOINCREMENT breaks existing software.
The text was updated successfully, but these errors were encountered: