The expression is calculated as given in each case. The difference being that a constant constraint is recognized in the query planner (and thus calculated once with the result being saved), whereas a constant expression as a return value is not.
-----Ursprüngliche Nachricht----- Von: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im Auftrag von x Gesendet: Montag, 29. Mai 2017 14:58 An: SQLite mailing list <sqlite-users@mailinglists.sqlite.org> Betreff: Re: [sqlite] Does prepare do arithmetic? Thanks Clemens, that clears that up. I’m still left wondering though why it calculates 2+2 every step in ‘select 2+2 from Tbl;’ but only once in ‘select * from Tbl where Col=2+2;’ I’m writing code that makes certain changes to the SQL before it submits it to sqlite3_prepare. Initially I assumed prepare took care of any arithmetic but now I’m wondering if I my code should do so before submitting to prepare. From: Clemens Ladisch<mailto:clem...@ladisch.de> Sent: 29 May 2017 12:54 To: sqlite-users@mailinglists.sqlite.org<mailto:sqlite-users@mailinglists.sqlite.org> Subject: Re: [sqlite] Does prepare do arithmetic? x wrote: > The explain for > > Select * from Tbl where Col = (select min(OtherCol) from OtherTbl); > > I’m having problems with. EXPLAIN Select * from Tbl where Col = (select min(OtherCol) from OtherTbl); addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 23 0 00 Start at 23 1 OpenRead 0 2 0 2 00 root=2 iDb=0; tbl 2 Rewind 0 22 0 00 3 Column 0 0 1 00 r[1]=tbl.col 4 Once 0 17 0 00 5 Null 0 3 3 00 r[3..3]=NULL; Init subquery result 6 Integer 1 4 0 00 r[4]=1; LIMIT counter 7 Null 0 5 6 00 r[5..6]=NULL 8 OpenRead 1 3 0 1 00 root=3 iDb=0; OtherTbl 9 Rewind 1 14 0 00 10 Column 1 0 7 00 r[7]=OtherTbl.OtherCol 11 CollSeq 0 0 0 (BINARY) 00 12 AggStep0 0 7 5 min(1) 01 accum=r[5] step(r[7]) 13 Next 1 10 0 01 14 AggFinal 5 1 0 min(1) 00 accum=r[5] N=1 15 Copy 5 3 0 00 r[3]=r[5] 16 DecrJumpZero 4 17 0 00 if (--r[4])==0 goto 17 17 Ne 3 21 1 (BINARY) 51 if r[1]!=r[3] goto 21 18 Column 0 0 8 00 r[8]=tbl.col 19 Column 0 1 9 00 r[9]=tbl.y 20 ResultRow 8 2 0 00 output=r[8..9] 21 Next 0 3 0 01 22 Halt 0 0 0 00 23 Transaction 0 0 2 0 01 usesStmtJournal=0 24 Goto 0 1 0 00 There are two nested loops; the outer one scans Tbl, the inner one scans OtherTbl. However, the database has determined that the result of the inner loop does not depend on the current row in the outer loop, so the inner loop is executed only once (the Once opcode in line 4 jumps to line 17 when it is encountered the second time). > I’m even having problems with explain query plan (shown below) for that one. > > Scan table Tbl > Execute scalar subquery 1 > Scan table OtherTbl > > Why would it scan Tbl first? It doesn't; it _begins_ scanning Tbl first. If Tbl does not happen to have any rows, the inner loop would never by executed. With nesting like this, it would be hard to define which (sub)query is executed first. (And then there are queries that use coroutines ...) Regards, Clemens > This communication (including any attachments) is intended for the use of the > intended recipient(s) only and may contain information that is confidential, > privileged or legally protected. Any unauthorized use or dissemination of > this communication is strictly prohibited. If you have received this > communication in error, please immediately notify the sender by return e-mail > message and delete all copies of the original communication. Thank you for > your cooperation. This e-mail contains public information intended for any subscriber of this mailing list and for anybody else who bothers to read it; it will be copied, disclosed and distributed to the public. If you think you are not the intended recipient, please commit suicide immediately. These terms apply also to any e-mails quoted in, referenced from, or answering this e-mail, and supersede any confidentiality notices in those e-mails. Additionally, confidentiality notices in those e-mails will incur legal processing fees of $42 per line; you have agreed to this by reading this confidentiality notice. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users ___________________________________________ Gunter Hick Software Engineer Scientific Games International GmbH FN 157284 a, HG Wien Klitschgasse 2-4, A-1130 Vienna, Austria Tel: +43 1 80100 0 E-Mail: h...@scigames.at This communication (including any attachments) is intended for the use of the intended recipient(s) only and may contain information that is confidential, privileged or legally protected. Any unauthorized use or dissemination of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender by return e-mail message and delete all copies of the original communication. Thank you for your cooperation. _______________________________________________ sqlite-users mailing list sqlite-users@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users