Ralf Junker wrote:
Even if sqlite3_column_rowid can sometimes not exactly identify a data field, it can still do so reliably with the majority of queries IMHO. It could at least do so much better than any other work-around I can think of. This would finally enable applications to allow users to edit most of their custom queries and views which are not already build into the application.

I agree. This is why your proposal would be very useful, even if there are a few corner cases to watch out for.

Select statement 1:

  SELECT c1, c2, c3 FROM a NATURAL JOIN b;

Results:

  sqlite_column_int(0)         returns 1
  sqlite_column_table_name(0)  returns 'a'
  sqlite_column_origin_name(0) returns 'c1'

----------

Select statement 2:

  SELECT c1, c2, c3 FROM a JOIN b USING(c1);

Results:

  sqlite_column_int(0)  returns 1
  sqlite_column_table_name(0)  returns 'a'
  sqlite_column_origin_name(0) returns 'c1'

Technically SQLite gets both of these results wrong. The value for c1 returned by these select statements are not supposed to be taken from table a. The sqlite_column_table_name should return a null value. The origin name could still be returned, because the column name is still c1.

The SQL standard says that a USING clause provides a list of common column names that must compare equal to implement the join. Only one copy of the common column data is returned in the result, and the common column names (the names that appears in the USING clause) cannot be qualified in the SELECT statement that contains that USING clause. The same thing applies to a NATURAL join, since that is really just a shortcut for a USING clause with all the names that are common between the two tables.

SQLite should generate an error for the qualified c1 names in all the queries below. The c1 value is not from either table, and so qualifying the common name with a table name is illegal.

   SQLite version 3.3.5
   Enter ".help" for instructions
   sqlite> CREATE TABLE a (c1, c2);
   sqlite> INSERT INTO a VALUES (1, 2);
   sqlite>
   sqlite> CREATE TABLE b (c1, c3);
   sqlite> INSERT INTO b VALUES (1, 3);
   sqlite>
   sqlite> SELECT a.c1, c2, c3 FROM a NATURAL JOIN b;
   1|2|3
   sqlite> SELECT b.c1, c2, c3 FROM a NATURAL JOIN b;
   1|2|3
   sqlite> SELECT a.c1, c2, c3 FROM a JOIN b USING(c1);
   1|2|3
   sqlite> SELECT b.c1, c2, c3 FROM a JOIN b USING(c1);
   1|2|3
   sqlite>

This should probably be fixed when your proposal is implemented.

Dennis Cote

Reply via email to