thank you very much Richard! very interesting to
get some info about these rather internal issues. This
gives us a good background to review some potential
dangerous loops. Your hint with the temp table is extremely
useful.

Best wishes

Marcus Grimm

>
> On Jun 30, 2009, at 2:34 PM, Marcus Grimm wrote:
>>
>> I'm not sure what will happend if you for example
>> delete a table row that would be the next row that
>> sqlite3_step would see, but doing so to me sounds
>> a bad approach anyhow.
>
> The official policy is that if you modify a table (via INSERT, UPDATE,
> or DELETE) in the middle of a SELECT, then what you get from the
> remainder of the SELECT is undefined.
>
> Sometimes, modifying a table has no effect on the remainder of the
> SELECT.  For example, suppose you are running
>
>     SELECT x FROM table1 WHERE y>10 ORDER BY x;
>
> where there is no index on x.  The way SQLite implements this is to
> load all the rows that have y>10 into a temporary table that is sorted
> by x.  Then it starts returning rows of the temporary table one by
> one.  By the time the first row is returned, everything that will ever
> be read from table1 by this query has already been read, so modifying
> table1 at that point will have no effect on subsequent SELECT output.
>
> On the other hand, if you have a query like this:
>
>    SELECT x FROM table1 WHERE y>10;
>
> where there is no index on y, then the query will be implemented as a
> full table scan.  SQLite will read the rows starting at the beginning
> of table1 and working toward the end.  As each row is read, it will be
> tested to see if y>10.  If y>10, then the row is returned.  Otherwise,
> SQLite advances to the next row.  In such a scenario, if you modify
> one of the later rows in the table, the modifications will be seen
> when the scan reaches the corresponding position in the table.
>
> Things can get tricky when you start looking at joins.  Consider:
>
>     SELECT t1.x, t2.y FROM t1 JOIN t2;
>
> This will typically be implemented as a nested loop:
>
>      for each row in t1:
>           for each row in t2:
>                output t1.x, t2.y
>
> If you delete the current row from t1 while there are still more rows
> to go on t2, what output do you get for t1.x on subsequent rows?  The
> answer is "it depends".  Sometimes you will continue to get the
> original value of t1.x.  Other times you will get a NULL.  Whether you
> get the original value of t1.x or NULL might change from one point
> release to the next.
>
> Bottom line:  It is best not to depend on the behavior of a SELECT
> after any row in the table being SELECTed is modified.  SQLite tries
> to do something "sensible".  But sometimes it is not clear what the
> sensible behavior is.  If you need to modify a table as you are
> reading it from a SELECT, consider storing the results of the SELECT
> in a TEMP table, then reading the TEMP table as you modify the
> original table:
>
>       CREATE TEMP TABLE xyz AS SELECT * FROM table1 WHERE....;
>       SELECT * FROM xyz;   -- make changes to table1 as xyz is read
>       DROP TEMP TABLE xyz;
>
>
> D. Richard Hipp
> d...@hwaci.com
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to