Additionally, SQLite is not honoring the ON CONFLICT IGNORE, even if I add NOT 
NULL ON CONFLICT IGNORE to each of the key fields. Instead, it is always 
generating HaltIfNull operations, i.e. ON CONFLICT ABORT.

33      HaltIfNull     1299  2     2     vals.keyid     01  if r[2]=null halt
34      HaltIfNull     1299  2     3     vals.value     01  if r[3]=null halt
35      HaltIfNull     1299  2     4     vals.period_no  01  if r[4]=null halt
36      HaltIfNull     1299  2     5     vals.sync_offset  01  if r[5]=null halt

If SQLite were to generate "IsNull <register> <endofloop> 0" instead, the rows 
with NULL values would be ignored automatically, removing the need for the 
"WHERE value IS NOT NULL" check.

-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im 
Auftrag von Igor Tandetnik
Gesendet: Dienstag, 26. März 2019 21:34
An: sqlite-users@mailinglists.sqlite.org
Betreff: [EXTERNAL] Re: [sqlite] CASE optimization opportunity (was: filling a 
key/value table)

See if something like this works better:

INSERT INTO logidx(keyid,value,location) SELECT id, val, location from (
   SELECT k.id id,
    (case k.name when 'type' then l.type when 'name' then l.name when 'size' 
then l.size else NULL end) AS val,
    l.location location
   FROM logfile l, logkey k
) WHERE val IS NOT NULL;

Or

WITH RawData AS (
   SELECT k.id id,
    (case k.name when 'type' then l.type when 'name' then l.name when 'size' 
then l.size else NULL end) AS val,
    l.location location
   FROM logfile l, logkey k
)
INSERT INTO logidx(keyid,value,location) SELECT id, val, location from RawData 
WHERE val IS NOT NULL;

Igor Tandetnik

On 3/26/2019 10:15 AM, Hick Gunter wrote:
> This works as expected, thanks.
>
> SQLite implements this as a pair of coroutines:
>
> Routine A) does a nested scan of the logfile (outer loop = just read
> the logifle once) and the logkey table (inner loop)
>
> Routine B) does the actual insert(s) into the logidx table
>
> Unfortunately, the necessary check of the generated val causes the CASE 
> expression to be evaluated twice (see bytecode).
>
> Instructions 16 thru 25 implement the CASE, leaving R12 holding the
> computed value Instruction 26 checks that something the evaluates to
> TRUE has been found Instructions 28 thru 37 duplicate the CASE,
> leaving R3 with the re-computed value
>
> The same effect could be achieved by copying R12 into R3 when buildung
> the record, just as R11 is copied to R4
>
> 9     VFilter        0     43    7                   00  iplan=r[7] zplan=''
> 10      VColumn        0     47    11                   00  
> r[11]=vcolumn(47); atx_txlog.period_no
> 11      Lt             13    42    11    (BINARY)       53  if r[11]<r[13] 
> goto 42
> 12      Gt             14    42    11    (BINARY)       53  if r[11]>r[14] 
> goto 42
> 13      Explain        13    0     0     SCAN TABLE keys AS k  00
> 14      Rewind         1     43    0                    00
> 15        Column         1     1     15                   00  r[15]=keys.name
> 16        Ne             17    19    15    (NOCASE)       52  if r[15]!=r[17] 
> goto 19
> 17        VColumn        0     15    12                   00  
> r[12]=vcolumn(15); atx_txlog.event_type
> 18        Goto           0     26    0                    00
> 19        Ne             18    22    15    (NOCASE)       52  if r[15]!=r[18] 
> goto 22
> 20        VColumn        0     28    12                   00  
> r[12]=vcolumn(28); atx_txlog.retailer_loc_id
> 21        Goto           0     26    0                    00
> 22        Ne             19    25    15    (NOCASE)       52  if r[15]!=r[19] 
> goto 25
> 23        VColumn        0     64    12                   00  
> r[12]=vcolumn(64); atx_txlog.ticket_key_string
> 24        Goto           0     26    0                    00
> 25        Null           0     12    0                    00  r[12]=NULL
> 26        IfNot          12    41    1                    00
> 27        Rowid          1     2     0                    00  r[2]=rowid
> 28        Ne             17    31    15    (NOCASE)       52  if r[15]!=r[17] 
> goto 31
> 29        VColumn        0     15    3                    00  
> r[3]=vcolumn(15); atx_txlog.event_type
> 30        Goto           0     38    0                    00
> 31        Ne             18    34    15    (NOCASE)       52  if r[15]!=r[18] 
> goto 34
> 32        VColumn        0     28    3                    00  
> r[3]=vcolumn(28); atx_txlog.retailer_loc_id
> 33        Goto           0     38    0                    00
> 34        Ne             19    37    15    (NOCASE)       52  if r[15]!=r[19] 
> goto 37
> 35        VColumn        0     64    3                    00  
> r[3]=vcolumn(64); atx_txlog.ticket_key_string
> 36        Goto           0     38    0                    00
> 37        Null           0     3     0                    00  r[3]=NULL
> 38        Copy           11    4     0                    00  r[4]=r[11]
> 39        VColumn        0     6     5                    00  
> r[5]=vcolumn(6); atx_txlog.sync_offset
> 40        Yield          6     0     0                    00
> 41      Next           1     15    0                    01
> 42    VNext          0     10    0                    00
>
> -----Ursprüngliche Nachricht-----
> Von: sqlite-users
> [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im Auftrag von
> Igor Tandetnik
> Gesendet: Donnerstag, 21. März 2019 17:29
> An: sqlite-users@mailinglists.sqlite.org
> Betreff: [EXTERNAL] Re: [sqlite] filling a key/value table
>
> On 3/21/2019 12:04 PM, Hick Gunter wrote:
>> I have an external data store that is accessible to sqlite as a virtual 
>> table. The equivalent SQL declaration is similar to:
>>
>> CREATE TABLE logfile (timestamp INTEGER, type INTEGER, name TEXT,
>> size INTEGER, ...);
>>
>> I would like to create an index as a native SQLite table declared like:
>>
>> CREATE TABLE logidx( keyid INTEGER, value BLOB, timestamp INTEGER,
>> primary key (keyid, value, location) ) WITHOUT ROWID;
>>
>> The fields of interest are stored in a config table:
>>
>> CREATE TABLE logkey( ID INTEGER PRIMARY KEY, name TEXT ); INSERT INTO
>> logkey(name) VALUES ('type'),('name'),('size');
>>
>> The naive method of inserting values is thus:
>>
>> INSERT INTO logidx(keyid,value,location) SELECT
>> k.id,l.type,l.location from logkey k, logfile l where k.name =
>> 'type'AND l.type IS NOT NULL; INSERT INTO
>> logidx(keyid,value,location) SELECT k.id,l.name,l.location from
>> logkey k, logfile l where k.name = 'name'AND l.name IS NOT NULL;
>> INSERT INTO logidx(keyid,value,location) SELECT
>> k.id,l.size,l.location from logkey k, logfile l where k.name =
>> 'size'AND l.size IS NOT NULL;
>>
>> This hast he disadvantage of requiring a complete scan of the virtual logidx 
>> table for each kind of entry.
>>
>> Any ideas on how to create all the tuples with only one pass of the logidx 
>> table?
>
> Something like this:
>
> INSERT INTO logidx(keyid,value,location) SELECT k.id,
>     (case k.name when 'type' then l.type when 'name' then l.name when 'size' 
> then l.size else NULL end) AS val,
>     l.location
> FROM logfile l, logkey k WHERE val IS NOT NULL;
>
> --
> Igor Tandetnik
>
>
> _______________________________________________
> 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 | Klitschgasse 2-4, A-1130 Vienna | FN 157284 a, HG Wien, DVR:
> 0430013 | (O) +43 1 80100 - 0
>
> May be privileged. May be confidential. Please delete if not the addressee.
> _______________________________________________
> 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 | 
Klitschgasse 2-4, A-1130 Vienna | FN 157284 a, HG Wien, DVR: 0430013 | (O) +43 
1 80100 - 0

May be privileged. May be confidential. Please delete if not the addressee.
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to