Possible User Defined Function (UDF) Bug?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Possible User Defined Function (UDF) Bug?

nomad
[ version: sqlite-snapshot-201711181730.tar.gz embedded in Perl's
DBD::SQLite module. ]

I have a user-defined function used as follows:

    CREATE TRIGGER
        after_insert_x
    AFTER INSERT ON
        x
    FOR EACH ROW
    BEGIN

        INSERT INTO
            y(id)
        VALUES(
            udf()
        );

    END;

What I am seeing is that for a row inserted into table y the udf() is
called *twice*. This behaviour only seems to occur with the
INSERT/VALUES combination. If I change the trigger contents to be the
following then the udf is only called once:

    INSERT INTO
        y(id)
    SELECT
        udf()
    ;

I'm having a hard time duplicating this with a standalone test case,
and I'm also having difficulty with EXPLAIN QUERY PLAN returning no
data for some statements... so I have a bit of a rabbit hole to explore
before I can come back with more information. But perhaps someone else
knows what might be going on?

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Possible User Defined Function (UDF) Bug?

Hick Gunter
I was unable to replicate a double call of the udf using the sql you provided.

Can you provide the original SQL (both for the INSERT and the CREATE TRIGGER) and the explain output (SQLite byte code, i.e .explain followed by explain <query>)?


-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:[hidden email]] Im Auftrag von [hidden email]
Gesendet: Montag, 20. November 2017 11:53
An: SQLite mailing list <[hidden email]>
Betreff: [EXTERNAL] [sqlite] Possible User Defined Function (UDF) Bug?

[ version: sqlite-snapshot-201711181730.tar.gz embedded in Perl's DBD::SQLite module. ]

I have a user-defined function used as follows:

    CREATE TRIGGER
        after_insert_x
    AFTER INSERT ON
        x
    FOR EACH ROW
    BEGIN

        INSERT INTO
            y(id)
        VALUES(
            udf()
        );

    END;

What I am seeing is that for a row inserted into table y the udf() is called *twice*. This behaviour only seems to occur with the INSERT/VALUES combination. If I change the trigger contents to be the following then the udf is only called once:

    INSERT INTO
        y(id)
    SELECT
        udf()
    ;

I'm having a hard time duplicating this with a standalone test case, and I'm also having difficulty with EXPLAIN QUERY PLAN returning no data for some statements... so I have a bit of a rabbit hole to explore before I can come back with more information. But perhaps someone else knows what might be going on?

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
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
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Possible User Defined Function (UDF) Bug?

nomad
On Mon Nov 20, 2017 at 11:04:01AM +0000, Hick Gunter wrote:
>
> Can you provide the original SQL (both for the INSERT and the CREATE
> TRIGGER) and the explain output (SQLite byte code, i.e .explain
> followed by explain <query>)?

Here is the trigger code:

    CREATE TABLE func_update_project(
        change_id INTEGER NOT NULL,
        id INTEGER NOT NULL,
        name VARCHAR(40),
        parent_id INTEGER,
        project_status_id INTEGER,
        title VARCHAR
    );

    CREATE TRIGGER
        func_update_project_ai_1
    AFTER INSERT ON
        func_update_project
    FOR EACH ROW
    BEGIN

    --    SELECT debug(
    --        ' change_id: ' || NEW.change_id,
    --        ' id: ' || NEW.id,
    --        ' name: ' || COALESCE(NEW.name,''),
    --        ' parent_id: ' || COALESCE(NEW.parent_id,''),
    --        ' project_status_id: ' || COALESCE(NEW.project_status_id,''),
    --        ' title: ' || COALESCE(NEW.title,'')
    --    );

        SELECT
            RAISE(ABORT, 'Bif::Error::InvalidName')
        WHERE
            CAST(NEW.name AS INTEGER) = NEW.name
        ;

        UPDATE
            bifcodes
        SET
            bifcode = bifcode || (
                SELECT
                    '{U1:_,U14:update_project,'
                    || 'U4:name,' ||
                        CASE WHEN
                            NEW.name IS NOT NULL
                        THEN
                            printf('U%d:%s,', LENGTH(CAST(NEW.name AS BLOB)),
                            CAST(NEW.name AS BLOB))
                        ELSE
                            '~'
                        END
                    || 'U11:parent_uuid,' ||
                        CASE WHEN
                            pp.uuid IS NOT NULL
                        THEN
                            printf('U%d:%s,', LENGTH(CAST(pp.uuid AS BLOB)),
                            CAST(pp.uuid AS BLOB))
                        ELSE
                            '~'
                        END
                    || 'U19:project_status_uuid,' ||
                        CASE WHEN
                            ps.uuid IS NOT NULL
                        THEN
                            printf('U%d:%s,', LENGTH(CAST(ps.uuid AS BLOB)),
                            CAST(ps.uuid AS BLOB))
                        ELSE
                            '~'
                        END
                    || 'U5:title,' ||
                        CASE WHEN
                            NEW.title IS NOT NULL
                        THEN
                            printf('U%d:%s,', LENGTH(CAST(NEW.title AS BLOB)),
                            CAST(NEW.title AS BLOB))
                        ELSE
                            '~'
                        END
                    || 'U4:uuid,'
                        || printf('U%d:%s,', LENGTH(p.uuid), p.uuid)
                    || '}'
                FROM
                    nodes p
                LEFT JOIN
                    nodes pp
                ON
                    pp.id = NEW.parent_id
                LEFT JOIN
                    nodes ps
                ON
                    ps.id = NEW.project_status_id
                WHERE
                    p.id = NEW.id
            )
        WHERE
            change_id = NEW.change_id
        ;


        INSERT INTO deltas(
            id,
            change_id,
            function
        )
        SELECT
            nextval('deltas'),
            NEW.change_id,
            'update_project'
        ;


        INSERT INTO
            node_deltas(
                delta_id,
                change_id,
                node_id,
                parent_id,
                name
            )
        SELECT
            currval('deltas'),
            NEW.change_id,
            NEW.id,
            NEW.parent_id,
            NEW.name
        ;


        INSERT INTO
            project_deltas(
                delta_id,
                change_id,
                project_id,
                title,
                project_status_id
            )
        SELECT
            currval('deltas'),
            NEW.change_id,
            NEW.id,
            NEW.title,
            NEW.project_status_id
        WHERE
            COALESCE(NEW.title,NEW.project_status_id) IS NOT NULL
        ;

        DELETE FROM func_update_project;
    END;

The udf that is called twice is the "nextval()" function.

The insert is straightfoward:

        INSERT INTO
                func_update_project(
                        change_id,
                        id,
                        project_status_id,
                        title
                )
        VALUES
                (
                        49,
                        3,
                        NULL,
                        NULL
                )
        ;

I can't use .explain from the sqlite command-line on my database
because of the UDFs, but I can print the formatted output of the
explain command. The VALUES case and the SELECT case are further below,
but here is the diff of just the opcodes:

        --- values.txt  2017-11-20 14:01:17.268360600 +0100
        +++ select.txt  2017-11-20 14:02:11.694907800 +0100
        @@ -124,16 +124,29 @@
         MakeRecord
         Insert
         ResetCount
        -OpenWrite
        -OpenWrite
        +InitCoroutine
         String8
         Function0
        +Param
        +String8
        +Yield
        +EndCoroutine
        +OpenEphemeral
        +Yield
        +MakeRecord
        +NewRowid
        +Insert
        +Goto
        +OpenWrite
        +OpenWrite
        +Rewind
        +Column
         NotNull
         NewRowid
         MustBeInt
         SoftNull
        -Param
        -String8
        +Column
        +Column
         HaltIfNull
         HaltIfNull
         NotExists
        @@ -214,6 +227,8 @@
         MakeRecord
         Insert
         Program
        +Next
        +Close
         ResetCount
         InitCoroutine
         String8

Here is the VALUES case (search for EOF to find the end);

 addr  opcode         p1    p2   p3   p4                             p5  comment
 0     Init           0     13   0                                   00          
 1     OpenWrite      0     94   0    6                              00          
 2     NewRowid       0     1    0                                   00          
 3     Variable       1     2    0                                   00          
 4     Variable       2     3    0                                   00          
 5     Variable       3     6    0                                   00          
 6     Variable       4     7    0                                   00          
 7     HaltIfNull     1299  2    2    func_update_project.change_id  01          
 8     HaltIfNull     1299  2    3    func_update_project.id         01          
 9     MakeRecord     2     6    8    DDBDDB                         00          
 10    Insert         0     8    1    func_update_project            39          
 11    Program        -6    12   9    program                        00          
 12    Halt           0     0    0                                   00          
 13    Transaction    0     1    331  0                              01          
 14    Null           0     4    0                                   00          
 15    Null           0     5    0                                   00          
 16    Goto           0     1    0                                   00          
 0     Init           0     1    0    -- TRIGGER                     00          
                                      func_update_project_ai_1                  
 1     Param          10    1    0                                   00          
 2     Cast           1     68   0                                   00          
 3     Param          10    2    0                                   00          
 4     Ne             2     6    1    (BINARY)                       54          
 5     Halt           1811  2    0    Bif::Error::InvalidName        00          
 6     Null           0     4    5                                   00          
 7     OpenWrite      0     99   0    2                              00          
 8     Param          8     8    0                                   00          
 9     SeekRowid      0     11   8                                   00          
 10    Rowid          0     5    0                                   00          
 11    IsNull         5     108  0                                   00          
 12    Null           0     6    0                                   00          
 13    Column         0     1    2                                   00          
 14    Once           0     104  0                                   00          
 15    Null           0     9    9                                   00          
 16    Integer        1     10   0                                   00          
 17    OpenRead       1     162  0    9                              00          
 18    OpenRead       2     162  0    9                              00          
 19    OpenRead       3     162  0    9                              00          
 20    Param          9     11   0                                   00          
 21    SeekRowid      1     104  11                                  00          
 22    Integer        0     12   0                                   00          
 23    Param          11    13   0                                   00          
 24    SeekRowid      2     101  13                                  00          
 25    Integer        1     12   0                                   00          
 26    Integer        0     14   0                                   00          
 27    Param          12    15   0                                   00          
 28    SeekRowid      3     98   15                                  00          
 29    Integer        1     14   0                                   00          
 30    String8        0     26   0    {U1:_,U14:update_project,      00          
 31    String8        0     27   0    U4:name,                       00          
 32    Concat         27    26   25                                  00          
 33    Param          10    26   0                                   00          
 34    IsNull         26    43   0                                   00          
 35    String8        0     28   0    U%d:%s,                        00          
 36    Param          10    31   0                                   00          
 37    Cast           31    65   0                                   00          
 38    Function0      1     31   29   length(1)                      01          
 39    Param          10    30   0                                   00          
 40    Cast           30    65   0                                   00          
 41    Function0      7     28   27   printf(-1)                     03          
 42    Goto           0     44   0                                   00          
 43    String8        0     27   0    ~                              00          
 44    Concat         27    25   24                                  00          
 45    String8        0     27   0    U11:parent_uuid,               00          
 46    Concat         27    24   23                                  00          
 47    Column         2     8    24                                  00          
 48    IsNull         24    57   0                                   00          
 49    String8        0     32   0    U%d:%s,                        00          
 50    SCopy          24    25   0                                   00          
 51    Cast           25    65   0                                   00          
 52    Function0      0     25   33   length(1)                      01          
 53    SCopy          24    34   0                                   00          
 54    Cast           34    65   0                                   00          
 55    Function0      1     32   27   printf(-1)                     03          
 56    Goto           0     58   0                                   00          
 57    String8        0     27   0    ~                              00          
 58    Concat         27    23   22                                  00          
 59    String8        0     27   0    U19:project_status_uuid,       00          
 60    Concat         27    22   21                                  00          
 61    Column         3     8    22                                  00          
 62    IsNull         22    71   0                                   00          
 63    String8        0     35   0    U%d:%s,                        00          
 64    SCopy          22    23   0                                   00          
 65    Cast           23    65   0                                   00          
 66    Function0      0     23   36   length(1)                      01          
 67    SCopy          22    37   0                                   00          
 68    Cast           37    65   0                                   00          
 69    Function0      1     35   27   printf(-1)                     03          
 70    Goto           0     72   0                                   00          
 71    String8        0     27   0    ~                              00          
 72    Concat         27    21   20                                  00          
 73    String8        0     27   0    U5:title,                      00          
 74    Concat         27    20   19                                  00          
 75    Param          13    20   0                                   00          
 76    IsNull         20    85   0                                   00          
 77    String8        0     38   0    U%d:%s,                        00          
 78    Param          13    41   0                                   00          
 79    Cast           41    65   0                                   00          
 80    Function0      1     41   39   length(1)                      01          
 81    Param          13    40   0                                   00          
 82    Cast           40    65   0                                   00          
 83    Function0      7     38   27   printf(-1)                     03          
 84    Goto           0     86   0                                   00          
 85    String8        0     27   0    ~                              00          
 86    Concat         27    19   18                                  00          
 87    String8        0     27   0    U4:uuid,                       00          
 88    Concat         27    18   17                                  00          
 89    String8        0     42   0    U%d:%s,                        00          
 90    Column         1     8    18                                  40          
 91    Function0      0     18   43   length(1)                      01          
 92    Column         1     8    44                                  00          
 93    Function0      1     42   27   printf(-1)                     03          
 94    Concat         27    17   16                                  00          
 95    String8        0     17   0    }                              00          
 96    Concat         17    16   9                                   00          
 97    DecrJumpZero   10    104  0                                   00          
 98    IfPos          14    101  0                                   00          
 99    NullRow        3     0    0                                   00          
 100   Goto           0     29   0                                   00          
 101   IfPos          12    104  0                                   00          
 102   NullRow        2     0    0                                   00          
 103   Goto           0     25   0                                   00          
 104   Concat         9     2    7                                   00          
 105   HaltIfNull     1299  2    7    bifcodes.bifcode               01          
 106   MakeRecord     6     2    16   D                              00          
 107   Insert         0     16   5    bifcodes                       05          
 108   ResetCount     0     0    0                                   00          
 109   OpenWrite      4     123  0    3                              00          
 110   OpenWrite      5     124  0    k(2,,)                         00          
 111   String8        0     52   0    deltas                         00          
 112   Function0      1     52   45   nextval(1)                     01          
 113   NotNull        45    115  0                                   00          
 114   NewRowid       4     45   0                                   00          
 115   MustBeInt      45    0    0                                   00          
 116   SoftNull       46    0    0                                   00          
 117   Param          8     47   0                                   00          
 118   String8        0     48   0    update_project                 00          
 119   HaltIfNull     1299  2    47   deltas.change_id               01          
 120   HaltIfNull     1299  2    48   deltas.function                01          
 121   NotExists      4     123  45                                  00          
 122   Halt           1555  2    0    deltas.id                      02          
 123   Affinity       46    3    0    DDB                            00          
 124   SCopy          47    50   0                                   00          
 125   IntCopy        45    51   0                                   00          
 126   MakeRecord     50    2    49                                  00          
 127   IsNull         47    134  0                                   00          
 128   SCopy          47    18   0                                   00          
 129   MustBeInt      18    133  0                                   00          
 130   OpenRead       6     108  0    21                             00          
 131   NotExists      6     133  18                                  00          
 132   Goto           0     134  0                                   00          
 133   FkCounter      0     1    0                                   00          
 134   Close          6     0    0                                   00          
 135   FkIfZero       0     139  0                                   00          
 136   OpenRead       7     246  0    0                              00          
 137   SeekRowid      7     139  45                                  00          
 138   FkCounter      0     -1   0                                   00          
 139   FkIfZero       0     143  0                                   00          
 140   OpenRead       8     244  0    0                              00          
 141   SeekRowid      8     143  45                                  00          
 142   FkCounter      0     -1   0                                   00          
 143   FkIfZero       0     147  0                                   00          
 144   OpenRead       9     222  0    0                              00          
 145   SeekRowid      9     147  45                                  00          
 146   FkCounter      0     -1   0                                   00          
 147   FkIfZero       0     151  0                                   00          
 148   OpenRead       10    211  0    0                              00          
 149   SeekRowid      10    151  45                                  00          
 150   FkCounter      0     -1   0                                   00          
 151   FkIfZero       0     155  0                                   00          
 152   OpenRead       11    190  0    0                              00          
 153   SeekRowid      11    155  45                                  00          
 154   FkCounter      0     -1   0                                   00          
 155   FkIfZero       0     159  0                                   00          
 156   OpenRead       12    188  0    0                              00          
 157   SeekRowid      12    159  45                                  00          
 158   FkCounter      0     -1   0                                   00          
 159   FkIfZero       0     163  0                                   00          
 160   OpenRead       13    175  0    0                              00          
 161   SeekRowid      13    163  45                                  00          
 162   FkCounter      0     -1   0                                   00          
 163   FkIfZero       0     167  0                                   00          
 164   OpenRead       14    172  0    0                              00          
 165   SeekRowid      14    167  45                                  00          
 166   FkCounter      0     -1   0                                   00          
 167   FkIfZero       0     171  0                                   00          
 168   OpenRead       15    155  0    0                              00          
 169   SeekRowid      15    171  45                                  00          
 170   FkCounter      0     -1   0                                   00          
 171   FkIfZero       0     175  0                                   00          
 172   OpenRead       16    153  0    0                              00          
 173   SeekRowid      16    175  45                                  00          
 174   FkCounter      0     -1   0                                   00          
 175   FkIfZero       0     179  0                                   00          
 176   OpenRead       17    152  0    0                              00          
 177   SeekRowid      17    179  45                                  00          
 178   FkCounter      0     -1   0                                   00          
 179   FkIfZero       0     183  0                                   00          
 180   OpenRead       18    146  0    0                              00          
 181   SeekRowid      18    183  45                                  00          
 182   FkCounter      0     -1   0                                   00          
 183   FkIfZero       0     187  0                                   00          
 184   OpenRead       19    144  0    0                              00          
 185   SeekRowid      19    187  45                                  00          
 186   FkCounter      0     -1   0                                   00          
 187   FkIfZero       0     191  0                                   00          
 188   OpenRead       20    141  0    0                              00          
 189   SeekRowid      20    191  45                                  00          
 190   FkCounter      0     -1   0                                   00          
 191   FkIfZero       0     195  0                                   00          
 192   OpenRead       21    132  0    0                              00          
 193   SeekRowid      21    195  45                                  00          
 194   FkCounter      0     -1   0                                   00          
 195   IdxInsert      5     49   50   2                              10          
 196   MakeRecord     46    3    53                                  00          
 197   Insert         4     53   45   deltas                         31          
 198   Program        41    199  68   program                        00          
 199   ResetCount     0     0    0                                   00          
 200   InitCoroutine  75    209  201                                 00          
 201   String8        0     76   0    deltas                         00          
 202   Function0      1     76   70   currval(1)                     01          
 203   Param          8     71   0                                   00          
 204   Param          9     72   0                                   00          
 205   Param          11    73   0                                   00          
 206   Param          10    74   0                                   00          
 207   Yield          75    0    0                                   00          
 208   EndCoroutine   75    0    0                                   00          
 209   OpenEphemeral  22    5    0                                   00          
 210   Yield          75    215  0                                   00          
 211   MakeRecord     70    5    77                                  00          
 212   NewRowid       22    78   0                                   00          
 213   Insert         22    77   78                                  00          
 214   Goto           0     210  0                                   00          
 215   OpenWrite      23    155  0    5                              00          
 216   OpenWrite      24    156  0    k(2,,)                         00          
 217   Rewind         22    276  0                                   00          
 218   Column         22    0    69                                  00          
 219   NotNull        69    221  0                                   00          
 220   NewRowid       23    69   0                                   00          
 221   MustBeInt      69    0    0                                   00          
 222   SoftNull       70    0    0                                   00          
 223   Column         22    1    71                                  00          
 224   Column         22    2    72                                  00          
 225   Column         22    3    73                                  00          
 226   Column         22    4    74                                  00          
 227   HaltIfNull     1299  2    71   node_deltas.change_id          01          
 228   HaltIfNull     1299  2    72   node_deltas.node_id            01          
 229   NotExists      23    231  69                                  00          
 230   Halt           1555  2    0    node_deltas.delta_id           02          
 231   Affinity       70    5    0    DDDDB                          00          
 232   SCopy          72    80   0                                   00          
 233   IntCopy        69    81   0                                   00          
 234   MakeRecord     80    2    79                                  00          
 235   IsNull         73    242  0                                   00          
 236   SCopy          73    78   0                                   00          
 237   MustBeInt      78    241  0                                   00          
 238   OpenRead       25    162  0    22                             00          
 239   NotExists      25    241  78                                  00          
 240   Goto           0     242  0                                   00          
 241   FkCounter      0     1    0                                   00          
 242   Close          25    0    0                                   00          
 243   IsNull         72    250  0                                   00          
 244   SCopy          72    78   0                                   00          
 245   MustBeInt      78    249  0                                   00          
 246   OpenRead       26    162  0    22                             00          
 247   NotExists      26    249  78                                  00          
 248   Goto           0     250  0                                   00          
 249   FkCounter      0     1    0                                   00          
 250   Close          26    0    0                                   00          
 251   IsNull         71    258  0                                   00          
 252   SCopy          71    78   0                                   00          
 253   MustBeInt      78    257  0                                   00          
 254   OpenRead       27    108  0    21                             00          
 255   NotExists      27    257  78                                  00          
 256   Goto           0     258  0                                   00          
 257   FkCounter      0     1    0                                   00          
 258   Close          27    0    0                                   00          
 259   IsNull         69    266  0                                   00          
 260   SCopy          69    78   0                                   00          
 261   MustBeInt      78    265  0                                   00          
 262   OpenRead       28    123  0    3                              00          
 263   NotExists      28    265  78                                  00          
 264   Goto           0     266  0                                   00          
 265   FkCounter      0     1    0                                   00          
 266   Close          28    0    0                                   00          
 267   FkIfZero       0     271  0                                   00          
 268   OpenRead       29    217  0    0                              00          
 269   SeekRowid      29    271  69                                  00          
 270   FkCounter      0     -1   0                                   00          
 271   IdxInsert      24    79   80   2                              10          
 272   MakeRecord     70    5    82                                  00          
 273   Insert         23    82   69   node_deltas                    31          
 274   Program        63    275  83   program                        00          
 275   Next           22    218  0                                   00          
 276   Close          22    0    0                                   00          
 277   ResetCount     0     0    0                                   00          
 278   InitCoroutine  90    291  279                                 00          
 279   Param          13    78   0                                   00          
 280   NotNull        78    282  0                                   00          
 281   Param          12    78   0                                   00          
 282   IsNull         78    290  0                                   00          
 283   String8        0     91   0    deltas                         00          
 284   Function0      1     91   85   currval(1)                     01          
 285   Param          8     86   0                                   00          
 286   Param          9     87   0                                   00          
 287   Param          13    88   0                                   00          
 288   Param          12    89   0                                   00          
 289   Yield          90    0    0                                   00          
 290   EndCoroutine   90    0    0                                   00          
 291   OpenEphemeral  30    5    0                                   00          
 292   Yield          90    297  0                                   00          
 293   MakeRecord     85    5    92                                  00          
 294   NewRowid       30    93   0                                   00          
 295   Insert         30    92   93                                  00          
 296   Goto           0     292  0                                   00          
 297   OpenWrite      31    188  0    5                              00          
 298   Rewind         30    338  0                                   00          
 299   Column         30    0    84                                  00          
 300   NotNull        84    302  0                                   00          
 301   NewRowid       31    84   0                                   00          
 302   MustBeInt      84    0    0                                   00          
 303   SoftNull       85    0    0                                   00          
 304   Column         30    1    86                                  00          
 305   Column         30    2    87                                  00          
 306   Column         30    3    88                                  00          
 307   Column         30    4    89                                  00          
 308   HaltIfNull     1299  2    86   project_deltas.change_id       01          
 309   HaltIfNull     1299  2    87   project_deltas.project_id      01          
 310   SCopy          88    93   0                                   00          
 311   NotNull        93    313  0                                   00          
 312   SCopy          89    93   0                                   00          
 313   NotNull        93    315  0                                   00          
 314   Halt           275   2    0    project_deltas_one_of          03          
 315   NotExists      31    317  84                                  00          
 316   Halt           1555  2    0    project_deltas.delta_id        02          
 317   IsNull         89    325  0                                   00          
 318   IsNull         87    325  0                                   00          
 319   OpenRead       32    197  0    k(2,,)                         00          
 320   Copy           89    94   0                                   00          
 321   Copy           87    95   0                                   00          
 322   MakeRecord     94    2    93   DD                             00          
 323   Found          32    325  93   0                              00          
 324   FkCounter      0     1    0                                   00          
 325   Close          32    0    0                                   00          
 326   IsNull         84    333  0                                   00          
 327   SCopy          84    93   0                                   00          
 328   MustBeInt      93    332  0                                   00          
 329   OpenRead       33    123  0    3                              00          
 330   NotExists      33    332  93                                  00          
 331   Goto           0     333  0                                   00          
 332   FkCounter      0     1    0                                   00          
 333   Close          33    0    0                                   00          
 334   MakeRecord     85    5    93   DDDBD                          00          
 335   Insert         31    93   84   project_deltas                 31          
 336   Program        78    337  96   program                        00          
 337   Next           30    299  0                                   00          
 338   Close          30    0    0                                   00          
 339   ResetCount     0     0    0                                   00          
 340   Clear          94    0    -1   func_update_project            00          
 341   ResetCount     0     0    0                                   00          
 342   Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER deltas_ai_seq       00          
 1     Null           0     1    2                                   00          
 2     OpenWrite      0     110  0    2                              00          
 3     Last           0     17   0                                   00          
 4     Column         0     0    5                                   00          
 5     String8        0     6    0    deltas_sequence                00          
 6     Ne             6     16   5    (BINARY)                       51          
 7     Column         0     1    6                                   00          
 8     Param          4     7    0                                   00          
 9     Ge             7     16   6    (BINARY)                       53          
 10    Rowid          0     2    0                                   00          
 11    IsNull         2     17   0                                   00          
 12    SCopy          5     3    0                                   00          
 13    Param          4     4    0                                   00          
 14    MakeRecord     3     2    7                                   00          
 15    Insert         0     7    2    sqlite_sequence                07          
 16    Prev           0     4    0                                   01          
 17    ResetCount     0     0    0                                   00          
 18    Null           0     14   15                                  00          
 19    OpenWrite      1     108  0    21                             00          
 20    Param          6     59   0                                   00          
 21    SeekRowid      1     23   59                                  00          
 22    Rowid          1     15   0                                   00          
 23    OpenWrite      2     112  0    k(2,,)                         00          
 24    OpenWrite      3     111  0    k(1,)                          00          
 25    IsNull         15    124  0                                   00          
 26    Rowid          1     16   0                                   00          
 27    Null           0     17   0                                   00          
 28    Column         1     2    18                                  00          
 29    Null           0     19   0                                   00          
 30    Null           0     20   0                                   00          
 31    Null           0     21   0                                   00          
 32    Null           0     22   0                                   00          
 33    Null           0     23   0                                   00          
 34    Null           0     24   0                                   00          
 35    Column         1     9    25   -1                             00          
 36    Null           0     26   0                                   00          
 37    Null           0     27   0                                   00          
 38    Null           0     28   0                                   00          
 39    Null           0     29   0                                   00          
 40    Null           0     30   0                                   00          
 41    Null           0     31   0                                   00          
 42    Null           0     32   0                                   00          
 43    Null           0     33   0                                   00          
 44    Null           0     34   0                                   00          
 45    Null           0     35   0                                   00          
 46    Null           0     36   0                                   00          
 47    Copy           15    37   0                                   00          
 48    Null           0     38   0                                   00          
 49    Column         1     1    39                                  00          
 50    Column         1     2    40                                  00          
 51    Column         1     3    6    0                              00          
 52    Integer        1     60   0                                   00          
 53    Add            60    6    41                                  00          
 54    Column         1     4    42                                  00          
 55    Column         1     5    43                                  00          
 56    Column         1     6    44                                  00          
 57    Column         1     7    45                                  00          
 58    Column         1     8    46                                  00          
 59    Column         1     9    47   -1                             00          
 60    Column         1     10   48                                  00          
 61    Column         1     11   49                                  00          
 62    Column         1     12   50                                  00          
 63    Column         1     13   51                                  00          
 64    Column         1     14   52                                  00          
 65    Column         1     15   53                                  00          
 66    Column         1     16   54                                  00          
 67    Column         1     17   55   en                             00          
 68    Column         1     18   56                                  00          
 69    Column         1     19   57                                  00          
 70    Column         1     20   58                                  00          
 71    HaltIfNull     1299  2    41   changes.dcount                 01          
 72    Affinity       38    21   0    DBDDDDDBBDBBBBBBBBBBC          00          
 73    Null           0     8    0                                   00          
 74    Integer        0     60   0                                   00          
 75    Ne             60    79   58   (BINARY)                       53          
 76    SCopy          58    9    0                                   00          
 77    IntCopy        37    10   0                                   00          
 78    MakeRecord     9     2    8                                   00          
 79    Null           0     11   0                                   00          
 80    String8        0     60   0                                   00          
 81    Eq             60    89   39   (BINARY)                       52          
 82    SCopy          39    12   0                                   00          
 83    IntCopy        37    13   0                                   00          
 84    MakeRecord     12    2    11                                  00          
 85    NoConflict     3     89   12   1                              00          
 86    IdxRowid       3     60   0                                   00          
 87    Eq             60    89   15                                  90          
 88    Halt           2067  2    0    changes.uuid                   02          
 89    FkIfZero       0     97   0                                   00          
 90    IsNull         18    97   0                                   00          
 91    SCopy          18    60   0                                   00          
 92    MustBeInt      60    96   0                                   00          
 93    OpenRead       4     108  0    21                             00          
 94    NotExists      4     96   60                                  00          
 95    Goto           0     97   0                                   00          
 96    FkCounter      0     -1   0                                   00          
 97    Close          4     0    0                                   00          
 98    Integer        0     60   0                                   00          
 99    Ne             60    103  58   (BINARY)                       53          
 100   Column         1     20   61                                  00          
 101   Rowid          1     62   0                                   00          
 102   IdxDelete      2     61   2                                   00          
 103   Column         1     1    60                                  00          
 104   String8        0     63   0                                   00          
 105   Eq             63    108  60   (BINARY)                       52          
 106   Column         1     1    63                                  00          
 107   IdxDelete      3     63   1                                   00          
 108   Delete         1     0    0                                   00          
 109   IsNull         40    117  0                                   00          
 110   SCopy          40    60   0                                   00          
 111   MustBeInt      60    116  0                                   00          
 112   Eq             37    117  60                                  90          
 113   OpenRead       5     108  0    21                             00          
 114   NotExists      5     116  60                                  00          
 115   Goto           0     117  0                                   00          
 116   FkCounter      0     1    0                                   00          
 117   Close          5     0    0                                   00          
 118   IsNull         8     120  0                                   00          
 119   IdxInsert      2     8    9    2                              00          
 120   IsNull         11    122  0                                   00          
 121   IdxInsert      3     11   12   1                              00          
 122   MakeRecord     38    21   60                                  00          
 123   Insert         1     60   37   changes                        05          
 124   ResetCount     0     0    0                                   00          
 125   Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER node_deltas_ai_1    00          
 1     Param          6     2    0                                   00          
 2     Param          8     3    0                                   00          
 3     Param          9     4    0                                   00          
 4     Param          10    5    0                                   00          
 5     Param          11    6    0                                   00          
 6     Function0      31    2    1    debug(-1)                      05          
 7     Null           0     10   11                                  00          
 8     OpenWrite      0     157  0    4                              00          
 9     Param          9     16   0                                   00          
 10    SeekRowid      0     27   16                                  00          
 11    Column         0     3    17   1                              00          
 12    Integer        0     18   0                                   00          
 13    Eq             18    26   17   (BINARY)                       44          
 14    Column         0     2    18   0                              00          
 15    Integer        1     19   0                                   00          
 16    Param          11    20   0                                   00          
 17    NotNull        20    19   0                                   00          
 18    Integer        0     19   0                                   00          
 19    Ne             19    26   18   (BINARY)                       44          
 20    Column         0     1    18   0                              00          
 21    Integer        1     19   0                                   00          
 22    Param          10    20   0                                   00          
 23    NotNull        20    25   0                                   00          
 24    Integer        0     19   0                                   00          
 25    Eq             19    27   18   (BINARY)                       54          
 26    Rowid          0     11   0                                   00          
 27    OpenWrite      1     158  0    k(2,,)                         00          
 28    IsNull         11    56   0                                   00          
 29    Null           0     12   0                                   00          
 30    Column         0     1    17   0                              00          
 31    Integer        1     18   0                                   00          
 32    Param          10    19   0                                   00          
 33    NotNull        19    35   0                                   00          
 34    Integer        0     18   0                                   00          
 35    Or             18    17   13                                  00          
 36    Column         0     2    18   0                              00          
 37    Integer        1     19   0                                   00          
 38    Param          11    20   0                                   00          
 39    NotNull        20    41   0                                   00          
 40    Integer        0     19   0                                   00          
 41    Or             19    18   14                                  00          
 42    Integer        1     15   0                                   00          
 43    HaltIfNull     1299  2    13   nodes_tomerge.parent_id        01          
 44    HaltIfNull     1299  2    14   nodes_tomerge.name             01          
 45    HaltIfNull     1299  2    15   nodes_tomerge.dirty            01          
 46    Affinity       12    4    0    DDDD                           00          
 47    SCopy          15    8    0                                   00          
 48    IntCopy        11    9    0                                   00          
 49    MakeRecord     8     2    7                                   00          
 50    Column         0     3    21   1                              00          
 51    Rowid          0     22   0                                   00          
 52    IdxDelete      1     21   2                                   00          
 53    IdxInsert      1     7    8    2                              00          
 54    MakeRecord     12    4    19                                  00          
 55    Insert         0     19   11   nodes_tomerge                  05          
 56    ResetCount     0     0    0                                   00          
 57    Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER                     00          
                                      project_deltas_ai_1                        
 1     Param          6     2    0                                   00          
 2     Param          9     3    0                                   00          
 3     Param          10    4    0                                   00          
 4     Param          11    5    0                                   00          
 5     Function0      15    2    1    debug(-1)                      04          
 6     OpenWrite      0     198  0    4                              00          
 7     OpenWrite      1     199  0    k(1,)                          00          
 8     NewRowid       0     6    0                                   00          
 9     Param          9     7    0                                   00          
 10    Integer        0     8    0                                   00          
 11    Integer        0     9    0                                   00          
 12    Null           0     10   0                                   00          
 13    IsNull         7     31   0                                   00          
 14    Affinity       7     4    0    DDDD                           00          
 15    SCopy          7     12   0                                   00          
 16    IntCopy        6     13   0                                   00          
 17    MakeRecord     12    2    11                                  00          
 18    NoConflict     1     20   12   1                              00          
 19    Goto           0     31   0                                   00          
 20    IsNull         7     27   0                                   00          
 21    SCopy          7     14   0                                   00          
 22    MustBeInt      14    26   0                                   00          
 23    OpenRead       2     203  0    9                              00          
 24    NotExists      2     26   14                                  00          
 25    Goto           0     27   0                                   00          
 26    FkCounter      0     1    0                                   00          
 27    Close          2     0    0                                   00          
 28    IdxInsert      1     11   12   1                              10          
 29    MakeRecord     7     4    14                                  00          
 30    Insert         0     14   6    projects_tomerge               39          
 31    ResetCount     0     0    0                                   00          
 32    Null           0     15   16                                  00          
 33    OpenWrite      3     198  0    4                              08          
 34    OpenWrite      4     199  0    k(1,)                          02          
 35    Param          9     21   0                                   00          
 36    IsNull         21    43   0                                   00          
 37    Affinity       21    1    0    D                              00          
 38    SeekLE         4     43   21   1                              00          
 39    IdxLT          4     43   21   1                              00          
 40    IdxRowid       4     22   0                                   00          
 41    NotExists      3     0    22                                  00          
 42    Rowid          3     16   0                                   00          
 43    IsNull         16    60   0                                   00          
 44    Column         3     0    17                                  00          
 45    Column         3     1    23   0                              00          
 46    Integer        1     24   0                                   00          
 47    Param          10    25   0                                   00          
 48    NotNull        25    50   0                                   00          
 49    Integer        0     24   0                                   00          
 50    Add            24    23   18                                  00          
 51    Column         3     2    24   0                              00          
 52    Integer        1     25   0                                   00          
 53    Param          11    26   0                                   00          
 54    NotNull        26    56   0                                   00          
 55    Integer        0     25   0                                   00          
 56    Add            25    24   19                                  00          
 57    Column         3     3    20                                  00          
 58    MakeRecord     17    4    25   DDDD                           00          
 59    Insert         3     25   16   projects_tomerge               05          
 60    ResetCount     0     0    0                                   00          
 61    Halt           0     0    0                                   00          
EOF

Here is the SELECT case (search for EOF to find the end);

 addr  opcode         p1    p2   p3   p4                             p5  comment
 0     Init           0     13   0                                   00          
 1     OpenWrite      0     94   0    6                              00          
 2     NewRowid       0     1    0                                   00          
 3     Variable       1     2    0                                   00          
 4     Variable       2     3    0                                   00          
 5     Variable       3     6    0                                   00          
 6     Variable       4     7    0                                   00          
 7     HaltIfNull     1299  2    2    func_update_project.change_id  01          
 8     HaltIfNull     1299  2    3    func_update_project.id         01          
 9     MakeRecord     2     6    8    DDBDDB                         00          
 10    Insert         0     8    1    func_update_project            39          
 11    Program        -6    12   9    program                        00          
 12    Halt           0     0    0                                   00          
 13    Transaction    0     1    331  0                              01          
 14    Null           0     4    0                                   00          
 15    Null           0     5    0                                   00          
 16    Goto           0     1    0                                   00          
 0     Init           0     1    0    -- TRIGGER                     00          
                                      func_update_project_ai_1                  
 1     Param          10    1    0                                   00          
 2     Cast           1     68   0                                   00          
 3     Param          10    2    0                                   00          
 4     Ne             2     6    1    (BINARY)                       54          
 5     Halt           1811  2    0    Bif::Error::InvalidName        00          
 6     Null           0     4    5                                   00          
 7     OpenWrite      0     99   0    2                              00          
 8     Param          8     8    0                                   00          
 9     SeekRowid      0     11   8                                   00          
 10    Rowid          0     5    0                                   00          
 11    IsNull         5     108  0                                   00          
 12    Null           0     6    0                                   00          
 13    Column         0     1    2                                   00          
 14    Once           0     104  0                                   00          
 15    Null           0     9    9                                   00          
 16    Integer        1     10   0                                   00          
 17    OpenRead       1     162  0    9                              00          
 18    OpenRead       2     162  0    9                              00          
 19    OpenRead       3     162  0    9                              00          
 20    Param          9     11   0                                   00          
 21    SeekRowid      1     104  11                                  00          
 22    Integer        0     12   0                                   00          
 23    Param          11    13   0                                   00          
 24    SeekRowid      2     101  13                                  00          
 25    Integer        1     12   0                                   00          
 26    Integer        0     14   0                                   00          
 27    Param          12    15   0                                   00          
 28    SeekRowid      3     98   15                                  00          
 29    Integer        1     14   0                                   00          
 30    String8        0     26   0    {U1:_,U14:update_project,      00          
 31    String8        0     27   0    U4:name,                       00          
 32    Concat         27    26   25                                  00          
 33    Param          10    26   0                                   00          
 34    IsNull         26    43   0                                   00          
 35    String8        0     28   0    U%d:%s,                        00          
 36    Param          10    31   0                                   00          
 37    Cast           31    65   0                                   00          
 38    Function0      1     31   29   length(1)                      01          
 39    Param          10    30   0                                   00          
 40    Cast           30    65   0                                   00          
 41    Function0      7     28   27   printf(-1)                     03          
 42    Goto           0     44   0                                   00          
 43    String8        0     27   0    ~                              00          
 44    Concat         27    25   24                                  00          
 45    String8        0     27   0    U11:parent_uuid,               00          
 46    Concat         27    24   23                                  00          
 47    Column         2     8    24                                  00          
 48    IsNull         24    57   0                                   00          
 49    String8        0     32   0    U%d:%s,                        00          
 50    SCopy          24    25   0                                   00          
 51    Cast           25    65   0                                   00          
 52    Function0      0     25   33   length(1)                      01          
 53    SCopy          24    34   0                                   00          
 54    Cast           34    65   0                                   00          
 55    Function0      1     32   27   printf(-1)                     03          
 56    Goto           0     58   0                                   00          
 57    String8        0     27   0    ~                              00          
 58    Concat         27    23   22                                  00          
 59    String8        0     27   0    U19:project_status_uuid,       00          
 60    Concat         27    22   21                                  00          
 61    Column         3     8    22                                  00          
 62    IsNull         22    71   0                                   00          
 63    String8        0     35   0    U%d:%s,                        00          
 64    SCopy          22    23   0                                   00          
 65    Cast           23    65   0                                   00          
 66    Function0      0     23   36   length(1)                      01          
 67    SCopy          22    37   0                                   00          
 68    Cast           37    65   0                                   00          
 69    Function0      1     35   27   printf(-1)                     03          
 70    Goto           0     72   0                                   00          
 71    String8        0     27   0    ~                              00          
 72    Concat         27    21   20                                  00          
 73    String8        0     27   0    U5:title,                      00          
 74    Concat         27    20   19                                  00          
 75    Param          13    20   0                                   00          
 76    IsNull         20    85   0                                   00          
 77    String8        0     38   0    U%d:%s,                        00          
 78    Param          13    41   0                                   00          
 79    Cast           41    65   0                                   00          
 80    Function0      1     41   39   length(1)                      01          
 81    Param          13    40   0                                   00          
 82    Cast           40    65   0                                   00          
 83    Function0      7     38   27   printf(-1)                     03          
 84    Goto           0     86   0                                   00          
 85    String8        0     27   0    ~                              00          
 86    Concat         27    19   18                                  00          
 87    String8        0     27   0    U4:uuid,                       00          
 88    Concat         27    18   17                                  00          
 89    String8        0     42   0    U%d:%s,                        00          
 90    Column         1     8    18                                  40          
 91    Function0      0     18   43   length(1)                      01          
 92    Column         1     8    44                                  00          
 93    Function0      1     42   27   printf(-1)                     03          
 94    Concat         27    17   16                                  00          
 95    String8        0     17   0    }                              00          
 96    Concat         17    16   9                                   00          
 97    DecrJumpZero   10    104  0                                   00          
 98    IfPos          14    101  0                                   00          
 99    NullRow        3     0    0                                   00          
 100   Goto           0     29   0                                   00          
 101   IfPos          12    104  0                                   00          
 102   NullRow        2     0    0                                   00          
 103   Goto           0     25   0                                   00          
 104   Concat         9     2    7                                   00          
 105   HaltIfNull     1299  2    7    bifcodes.bifcode               01          
 106   MakeRecord     6     2    16   D                              00          
 107   Insert         0     16   5    bifcodes                       05          
 108   ResetCount     0     0    0                                   00          
 109   InitCoroutine  49    116  110                                 00          
 110   String8        0     50   0    deltas                         00          
 111   Function0      1     50   46   nextval(1)                     01          
 112   Param          8     47   0                                   00          
 113   String8        0     48   0    update_project                 00          
 114   Yield          49    0    0                                   00          
 115   EndCoroutine   49    0    0                                   00          
 116   OpenEphemeral  4     3    0                                   00          
 117   Yield          49    122  0                                   00          
 118   MakeRecord     46    3    51                                  00          
 119   NewRowid       4     52   0                                   00          
 120   Insert         4     51   52                                  00          
 121   Goto           0     117  0                                   00          
 122   OpenWrite      5     123  0    3                              00          
 123   OpenWrite      6     124  0    k(2,,)                         00          
 124   Rewind         4     213  0                                   00          
 125   Column         4     0    45                                  00          
 126   NotNull        45    128  0                                   00          
 127   NewRowid       5     45   0                                   00          
 128   MustBeInt      45    0    0                                   00          
 129   SoftNull       46    0    0                                   00          
 130   Column         4     1    47                                  00          
 131   Column         4     2    48                                  00          
 132   HaltIfNull     1299  2    47   deltas.change_id               01          
 133   HaltIfNull     1299  2    48   deltas.function                01          
 134   NotExists      5     136  45                                  00          
 135   Halt           1555  2    0    deltas.id                      02          
 136   Affinity       46    3    0    DDB                            00          
 137   SCopy          47    54   0                                   00          
 138   IntCopy        45    55   0                                   00          
 139   MakeRecord     54    2    53                                  00          
 140   IsNull         47    147  0                                   00          
 141   SCopy          47    52   0                                   00          
 142   MustBeInt      52    146  0                                   00          
 143   OpenRead       7     108  0    21                             00          
 144   NotExists      7     146  52                                  00          
 145   Goto           0     147  0                                   00          
 146   FkCounter      0     1    0                                   00          
 147   Close          7     0    0                                   00          
 148   FkIfZero       0     152  0                                   00          
 149   OpenRead       8     246  0    0                              00          
 150   SeekRowid      8     152  45                                  00          
 151   FkCounter      0     -1   0                                   00          
 152   FkIfZero       0     156  0                                   00          
 153   OpenRead       9     244  0    0                              00          
 154   SeekRowid      9     156  45                                  00          
 155   FkCounter      0     -1   0                                   00          
 156   FkIfZero       0     160  0                                   00          
 157   OpenRead       10    222  0    0                              00          
 158   SeekRowid      10    160  45                                  00          
 159   FkCounter      0     -1   0                                   00          
 160   FkIfZero       0     164  0                                   00          
 161   OpenRead       11    211  0    0                              00          
 162   SeekRowid      11    164  45                                  00          
 163   FkCounter      0     -1   0                                   00          
 164   FkIfZero       0     168  0                                   00          
 165   OpenRead       12    190  0    0                              00          
 166   SeekRowid      12    168  45                                  00          
 167   FkCounter      0     -1   0                                   00          
 168   FkIfZero       0     172  0                                   00          
 169   OpenRead       13    188  0    0                              00          
 170   SeekRowid      13    172  45                                  00          
 171   FkCounter      0     -1   0                                   00          
 172   FkIfZero       0     176  0                                   00          
 173   OpenRead       14    175  0    0                              00          
 174   SeekRowid      14    176  45                                  00          
 175   FkCounter      0     -1   0                                   00          
 176   FkIfZero       0     180  0                                   00          
 177   OpenRead       15    172  0    0                              00          
 178   SeekRowid      15    180  45                                  00          
 179   FkCounter      0     -1   0                                   00          
 180   FkIfZero       0     184  0                                   00          
 181   OpenRead       16    155  0    0                              00          
 182   SeekRowid      16    184  45                                  00          
 183   FkCounter      0     -1   0                                   00          
 184   FkIfZero       0     188  0                                   00          
 185   OpenRead       17    153  0    0                              00          
 186   SeekRowid      17    188  45                                  00          
 187   FkCounter      0     -1   0                                   00          
 188   FkIfZero       0     192  0                                   00          
 189   OpenRead       18    152  0    0                              00          
 190   SeekRowid      18    192  45                                  00          
 191   FkCounter      0     -1   0                                   00          
 192   FkIfZero       0     196  0                                   00          
 193   OpenRead       19    146  0    0                              00          
 194   SeekRowid      19    196  45                                  00          
 195   FkCounter      0     -1   0                                   00          
 196   FkIfZero       0     200  0                                   00          
 197   OpenRead       20    144  0    0                              00          
 198   SeekRowid      20    200  45                                  00          
 199   FkCounter      0     -1   0                                   00          
 200   FkIfZero       0     204  0                                   00          
 201   OpenRead       21    141  0    0                              00          
 202   SeekRowid      21    204  45                                  00          
 203   FkCounter      0     -1   0                                   00          
 204   FkIfZero       0     208  0                                   00          
 205   OpenRead       22    132  0    0                              00          
 206   SeekRowid      22    208  45                                  00          
 207   FkCounter      0     -1   0                                   00          
 208   IdxInsert      6     53   54   2                              10          
 209   MakeRecord     46    3    61                                  00          
 210   Insert         5     61   45   deltas                         31          
 211   Program        41    212  71   program                        00          
 212   Next           4     125  0                                   00          
 213   Close          4     0    0                                   00          
 214   ResetCount     0     0    0                                   00          
 215   InitCoroutine  78    224  216                                 00          
 216   String8        0     79   0    deltas                         00          
 217   Function0      1     79   73   currval(1)                     01          
 218   Param          8     74   0                                   00          
 219   Param          9     75   0                                   00          
 220   Param          11    76   0                                   00          
 221   Param          10    77   0                                   00          
 222   Yield          78    0    0                                   00          
 223   EndCoroutine   78    0    0                                   00          
 224   OpenEphemeral  23    5    0                                   00          
 225   Yield          78    230  0                                   00          
 226   MakeRecord     73    5    80                                  00          
 227   NewRowid       23    81   0                                   00          
 228   Insert         23    80   81                                  00          
 229   Goto           0     225  0                                   00          
 230   OpenWrite      24    155  0    5                              00          
 231   OpenWrite      25    156  0    k(2,,)                         00          
 232   Rewind         23    291  0                                   00          
 233   Column         23    0    72                                  00          
 234   NotNull        72    236  0                                   00          
 235   NewRowid       24    72   0                                   00          
 236   MustBeInt      72    0    0                                   00          
 237   SoftNull       73    0    0                                   00          
 238   Column         23    1    74                                  00          
 239   Column         23    2    75                                  00          
 240   Column         23    3    76                                  00          
 241   Column         23    4    77                                  00          
 242   HaltIfNull     1299  2    74   node_deltas.change_id          01          
 243   HaltIfNull     1299  2    75   node_deltas.node_id            01          
 244   NotExists      24    246  72                                  00          
 245   Halt           1555  2    0    node_deltas.delta_id           02          
 246   Affinity       73    5    0    DDDDB                          00          
 247   SCopy          75    83   0                                   00          
 248   IntCopy        72    84   0                                   00          
 249   MakeRecord     83    2    82                                  00          
 250   IsNull         76    257  0                                   00          
 251   SCopy          76    81   0                                   00          
 252   MustBeInt      81    256  0                                   00          
 253   OpenRead       26    162  0    22                             00          
 254   NotExists      26    256  81                                  00          
 255   Goto           0     257  0                                   00          
 256   FkCounter      0     1    0                                   00          
 257   Close          26    0    0                                   00          
 258   IsNull         75    265  0                                   00          
 259   SCopy          75    81   0                                   00          
 260   MustBeInt      81    264  0                                   00          
 261   OpenRead       27    162  0    22                             00          
 262   NotExists      27    264  81                                  00          
 263   Goto           0     265  0                                   00          
 264   FkCounter      0     1    0                                   00          
 265   Close          27    0    0                                   00          
 266   IsNull         74    273  0                                   00          
 267   SCopy          74    81   0                                   00          
 268   MustBeInt      81    272  0                                   00          
 269   OpenRead       28    108  0    21                             00          
 270   NotExists      28    272  81                                  00          
 271   Goto           0     273  0                                   00          
 272   FkCounter      0     1    0                                   00          
 273   Close          28    0    0                                   00          
 274   IsNull         72    281  0                                   00          
 275   SCopy          72    81   0                                   00          
 276   MustBeInt      81    280  0                                   00          
 277   OpenRead       29    123  0    3                              00          
 278   NotExists      29    280  81                                  00          
 279   Goto           0     281  0                                   00          
 280   FkCounter      0     1    0                                   00          
 281   Close          29    0    0                                   00          
 282   FkIfZero       0     286  0                                   00          
 283   OpenRead       30    217  0    0                              00          
 284   SeekRowid      30    286  72                                  00          
 285   FkCounter      0     -1   0                                   00          
 286   IdxInsert      25    82   83   2                              10          
 287   MakeRecord     73    5    85                                  00          
 288   Insert         24    85   72   node_deltas                    31          
 289   Program        66    290  86   program                        00          
 290   Next           23    233  0                                   00          
 291   Close          23    0    0                                   00          
 292   ResetCount     0     0    0                                   00          
 293   InitCoroutine  93    306  294                                 00          
 294   Param          13    81   0                                   00          
 295   NotNull        81    297  0                                   00          
 296   Param          12    81   0                                   00          
 297   IsNull         81    305  0                                   00          
 298   String8        0     94   0    deltas                         00          
 299   Function0      1     94   88   currval(1)                     01          
 300   Param          8     89   0                                   00          
 301   Param          9     90   0                                   00          
 302   Param          13    91   0                                   00          
 303   Param          12    92   0                                   00          
 304   Yield          93    0    0                                   00          
 305   EndCoroutine   93    0    0                                   00          
 306   OpenEphemeral  31    5    0                                   00          
 307   Yield          93    312  0                                   00          
 308   MakeRecord     88    5    95                                  00          
 309   NewRowid       31    96   0                                   00          
 310   Insert         31    95   96                                  00          
 311   Goto           0     307  0                                   00          
 312   OpenWrite      32    188  0    5                              00          
 313   Rewind         31    353  0                                   00          
 314   Column         31    0    87                                  00          
 315   NotNull        87    317  0                                   00          
 316   NewRowid       32    87   0                                   00          
 317   MustBeInt      87    0    0                                   00          
 318   SoftNull       88    0    0                                   00          
 319   Column         31    1    89                                  00          
 320   Column         31    2    90                                  00          
 321   Column         31    3    91                                  00          
 322   Column         31    4    92                                  00          
 323   HaltIfNull     1299  2    89   project_deltas.change_id       01          
 324   HaltIfNull     1299  2    90   project_deltas.project_id      01          
 325   SCopy          91    96   0                                   00          
 326   NotNull        96    328  0                                   00          
 327   SCopy          92    96   0                                   00          
 328   NotNull        96    330  0                                   00          
 329   Halt           275   2    0    project_deltas_one_of          03          
 330   NotExists      32    332  87                                  00          
 331   Halt           1555  2    0    project_deltas.delta_id        02          
 332   IsNull         92    340  0                                   00          
 333   IsNull         90    340  0                                   00          
 334   OpenRead       33    197  0    k(2,,)                         00          
 335   Copy           92    97   0                                   00          
 336   Copy           90    98   0                                   00          
 337   MakeRecord     97    2    96   DD                             00          
 338   Found          33    340  96   0                              00          
 339   FkCounter      0     1    0                                   00          
 340   Close          33    0    0                                   00          
 341   IsNull         87    348  0                                   00          
 342   SCopy          87    96   0                                   00          
 343   MustBeInt      96    347  0                                   00          
 344   OpenRead       34    123  0    3                              00          
 345   NotExists      34    347  96                                  00          
 346   Goto           0     348  0                                   00          
 347   FkCounter      0     1    0                                   00          
 348   Close          34    0    0                                   00          
 349   MakeRecord     88    5    96   DDDBD                          00          
 350   Insert         32    96   87   project_deltas                 31          
 351   Program        81    352  99   program                        00          
 352   Next           31    314  0                                   00          
 353   Close          31    0    0                                   00          
 354   ResetCount     0     0    0                                   00          
 355   Clear          94    0    -1   func_update_project            00          
 356   ResetCount     0     0    0                                   00          
 357   Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER deltas_ai_seq       00          
 1     Null           0     1    2                                   00          
 2     OpenWrite      0     110  0    2                              00          
 3     Last           0     17   0                                   00          
 4     Column         0     0    5                                   00          
 5     String8        0     6    0    deltas_sequence                00          
 6     Ne             6     16   5    (BINARY)                       51          
 7     Column         0     1    6                                   00          
 8     Param          4     7    0                                   00          
 9     Ge             7     16   6    (BINARY)                       53          
 10    Rowid          0     2    0                                   00          
 11    IsNull         2     17   0                                   00          
 12    SCopy          5     3    0                                   00          
 13    Param          4     4    0                                   00          
 14    MakeRecord     3     2    7                                   00          
 15    Insert         0     7    2    sqlite_sequence                07          
 16    Prev           0     4    0                                   01          
 17    ResetCount     0     0    0                                   00          
 18    Null           0     14   15                                  00          
 19    OpenWrite      1     108  0    21                             00          
 20    Param          6     59   0                                   00          
 21    SeekRowid      1     23   59                                  00          
 22    Rowid          1     15   0                                   00          
 23    OpenWrite      2     112  0    k(2,,)                         00          
 24    OpenWrite      3     111  0    k(1,)                          00          
 25    IsNull         15    124  0                                   00          
 26    Rowid          1     16   0                                   00          
 27    Null           0     17   0                                   00          
 28    Column         1     2    18                                  00          
 29    Null           0     19   0                                   00          
 30    Null           0     20   0                                   00          
 31    Null           0     21   0                                   00          
 32    Null           0     22   0                                   00          
 33    Null           0     23   0                                   00          
 34    Null           0     24   0                                   00          
 35    Column         1     9    25   -1                             00          
 36    Null           0     26   0                                   00          
 37    Null           0     27   0                                   00          
 38    Null           0     28   0                                   00          
 39    Null           0     29   0                                   00          
 40    Null           0     30   0                                   00          
 41    Null           0     31   0                                   00          
 42    Null           0     32   0                                   00          
 43    Null           0     33   0                                   00          
 44    Null           0     34   0                                   00          
 45    Null           0     35   0                                   00          
 46    Null           0     36   0                                   00          
 47    Copy           15    37   0                                   00          
 48    Null           0     38   0                                   00          
 49    Column         1     1    39                                  00          
 50    Column         1     2    40                                  00          
 51    Column         1     3    6    0                              00          
 52    Integer        1     60   0                                   00          
 53    Add            60    6    41                                  00          
 54    Column         1     4    42                                  00          
 55    Column         1     5    43                                  00          
 56    Column         1     6    44                                  00          
 57    Column         1     7    45                                  00          
 58    Column         1     8    46                                  00          
 59    Column         1     9    47   -1                             00          
 60    Column         1     10   48                                  00          
 61    Column         1     11   49                                  00          
 62    Column         1     12   50                                  00          
 63    Column         1     13   51                                  00          
 64    Column         1     14   52                                  00          
 65    Column         1     15   53                                  00          
 66    Column         1     16   54                                  00          
 67    Column         1     17   55   en                             00          
 68    Column         1     18   56                                  00          
 69    Column         1     19   57                                  00          
 70    Column         1     20   58                                  00          
 71    HaltIfNull     1299  2    41   changes.dcount                 01          
 72    Affinity       38    21   0    DBDDDDDBBDBBBBBBBBBBC          00          
 73    Null           0     8    0                                   00          
 74    Integer        0     60   0                                   00          
 75    Ne             60    79   58   (BINARY)                       53          
 76    SCopy          58    9    0                                   00          
 77    IntCopy        37    10   0                                   00          
 78    MakeRecord     9     2    8                                   00          
 79    Null           0     11   0                                   00          
 80    String8        0     60   0                                   00          
 81    Eq             60    89   39   (BINARY)                       52          
 82    SCopy          39    12   0                                   00          
 83    IntCopy        37    13   0                                   00          
 84    MakeRecord     12    2    11                                  00          
 85    NoConflict     3     89   12   1                              00          
 86    IdxRowid       3     60   0                                   00          
 87    Eq             60    89   15                                  90          
 88    Halt           2067  2    0    changes.uuid                   02          
 89    FkIfZero       0     97   0                                   00          
 90    IsNull         18    97   0                                   00          
 91    SCopy          18    60   0                                   00          
 92    MustBeInt      60    96   0                                   00          
 93    OpenRead       4     108  0    21                             00          
 94    NotExists      4     96   60                                  00          
 95    Goto           0     97   0                                   00          
 96    FkCounter      0     -1   0                                   00          
 97    Close          4     0    0                                   00          
 98    Integer        0     60   0                                   00          
 99    Ne             60    103  58   (BINARY)                       53          
 100   Column         1     20   61                                  00          
 101   Rowid          1     62   0                                   00          
 102   IdxDelete      2     61   2                                   00          
 103   Column         1     1    60                                  00          
 104   String8        0     63   0                                   00          
 105   Eq             63    108  60   (BINARY)                       52          
 106   Column         1     1    63                                  00          
 107   IdxDelete      3     63   1                                   00          
 108   Delete         1     0    0                                   00          
 109   IsNull         40    117  0                                   00          
 110   SCopy          40    60   0                                   00          
 111   MustBeInt      60    116  0                                   00          
 112   Eq             37    117  60                                  90          
 113   OpenRead       5     108  0    21                             00          
 114   NotExists      5     116  60                                  00          
 115   Goto           0     117  0                                   00          
 116   FkCounter      0     1    0                                   00          
 117   Close          5     0    0                                   00          
 118   IsNull         8     120  0                                   00          
 119   IdxInsert      2     8    9    2                              00          
 120   IsNull         11    122  0                                   00          
 121   IdxInsert      3     11   12   1                              00          
 122   MakeRecord     38    21   60                                  00          
 123   Insert         1     60   37   changes                        05          
 124   ResetCount     0     0    0                                   00          
 125   Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER node_deltas_ai_1    00          
 1     Param          6     2    0                                   00          
 2     Param          8     3    0                                   00          
 3     Param          9     4    0                                   00          
 4     Param          10    5    0                                   00          
 5     Param          11    6    0                                   00          
 6     Function0      31    2    1    debug(-1)                      05          
 7     Null           0     10   11                                  00          
 8     OpenWrite      0     157  0    4                              00          
 9     Param          9     16   0                                   00          
 10    SeekRowid      0     27   16                                  00          
 11    Column         0     3    17   1                              00          
 12    Integer        0     18   0                                   00          
 13    Eq             18    26   17   (BINARY)                       44          
 14    Column         0     2    18   0                              00          
 15    Integer        1     19   0                                   00          
 16    Param          11    20   0                                   00          
 17    NotNull        20    19   0                                   00          
 18    Integer        0     19   0                                   00          
 19    Ne             19    26   18   (BINARY)                       44          
 20    Column         0     1    18   0                              00          
 21    Integer        1     19   0                                   00          
 22    Param          10    20   0                                   00          
 23    NotNull        20    25   0                                   00          
 24    Integer        0     19   0                                   00          
 25    Eq             19    27   18   (BINARY)                       54          
 26    Rowid          0     11   0                                   00          
 27    OpenWrite      1     158  0    k(2,,)                         00          
 28    IsNull         11    56   0                                   00          
 29    Null           0     12   0                                   00          
 30    Column         0     1    17   0                              00          
 31    Integer        1     18   0                                   00          
 32    Param          10    19   0                                   00          
 33    NotNull        19    35   0                                   00          
 34    Integer        0     18   0                                   00          
 35    Or             18    17   13                                  00          
 36    Column         0     2    18   0                              00          
 37    Integer        1     19   0                                   00          
 38    Param          11    20   0                                   00          
 39    NotNull        20    41   0                                   00          
 40    Integer        0     19   0                                   00          
 41    Or             19    18   14                                  00          
 42    Integer        1     15   0                                   00          
 43    HaltIfNull     1299  2    13   nodes_tomerge.parent_id        01          
 44    HaltIfNull     1299  2    14   nodes_tomerge.name             01          
 45    HaltIfNull     1299  2    15   nodes_tomerge.dirty            01          
 46    Affinity       12    4    0    DDDD                           00          
 47    SCopy          15    8    0                                   00          
 48    IntCopy        11    9    0                                   00          
 49    MakeRecord     8     2    7                                   00          
 50    Column         0     3    21   1                              00          
 51    Rowid          0     22   0                                   00          
 52    IdxDelete      1     21   2                                   00          
 53    IdxInsert      1     7    8    2                              00          
 54    MakeRecord     12    4    19                                  00          
 55    Insert         0     19   11   nodes_tomerge                  05          
 56    ResetCount     0     0    0                                   00          
 57    Halt           0     0    0                                   00          
 0     Init           0     1    0    -- TRIGGER                     00          
                                      project_deltas_ai_1                        
 1     Param          6     2    0                                   00          
 2     Param          9     3    0                                   00          
 3     Param          10    4    0                                   00          
 4     Param          11    5    0                                   00          
 5     Function0      15    2    1    debug(-1)                      04          
 6     OpenWrite      0     198  0    4                              00          
 7     OpenWrite      1     199  0    k(1,)                          00          
 8     NewRowid       0     6    0                                   00          
 9     Param          9     7    0                                   00          
 10    Integer        0     8    0                                   00          
 11    Integer        0     9    0                                   00          
 12    Null           0     10   0                                   00          
 13    IsNull         7     31   0                                   00          
 14    Affinity       7     4    0    DDDD                           00          
 15    SCopy          7     12   0                                   00          
 16    IntCopy        6     13   0                                   00          
 17    MakeRecord     12    2    11                                  00          
 18    NoConflict     1     20   12   1                              00          
 19    Goto           0     31   0                                   00          
 20    IsNull         7     27   0                                   00          
 21    SCopy          7     14   0                                   00          
 22    MustBeInt      14    26   0                                   00          
 23    OpenRead       2     203  0    9                              00          
 24    NotExists      2     26   14                                  00          
 25    Goto           0     27   0                                   00          
 26    FkCounter      0     1    0                                   00          
 27    Close          2     0    0                                   00          
 28    IdxInsert      1     11   12   1                              10          
 29    MakeRecord     7     4    14                                  00          
 30    Insert         0     14   6    projects_tomerge               39          
 31    ResetCount     0     0    0                                   00          
 32    Null           0     15   16                                  00          
 33    OpenWrite      3     198  0    4                              08          
 34    OpenWrite      4     199  0    k(1,)                          02          
 35    Param          9     21   0                                   00          
 36    IsNull         21    43   0                                   00          
 37    Affinity       21    1    0    D                              00          
 38    SeekLE         4     43   21   1                              00          
 39    IdxLT          4     43   21   1                              00          
 40    IdxRowid       4     22   0                                   00          
 41    NotExists      3     0    22                                  00          
 42    Rowid          3     16   0                                   00          
 43    IsNull         16    60   0                                   00          
 44    Column         3     0    17                                  00          
 45    Column         3     1    23   0                              00          
 46    Integer        1     24   0                                   00          
 47    Param          10    25   0                                   00          
 48    NotNull        25    50   0                                   00          
 49    Integer        0     24   0                                   00          
 50    Add            24    23   18                                  00          
 51    Column         3     2    24   0                              00          
 52    Integer        1     25   0                                   00          
 53    Param          11    26   0                                   00          
 54    NotNull        26    56   0                                   00          
 55    Integer        0     25   0                                   00          
 56    Add            25    24   19                                  00          
 57    Column         3     3    20                                  00          
 58    MakeRecord     17    4    25   DDDD                           00          
 59    Insert         3     25   16   projects_tomerge               05          
 60    ResetCount     0     0    0                                   00          
 61    Halt           0     0    0                                   00          
EOF

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Possible User Defined Function (UDF) Bug?

nomad
My previous explain outputs were probably not quite right. With the
following code inside the previously posted trigger:

    INSERT INTO deltas(
        id,
        change_id,
        function
    )
    VALUES(
        nextval('deltas'),
        NEW.change_id,
       'update_project'
    );

I now see the below explain output with its two Function0 optcodes
where I believe there should only be one.


 140   Insert         0     26   15    bifcodes                                05          
 141   Program        12    142  56    program                                 00          
 142   ResetCount     0     0    0                                             00          
 143   OpenWrite      4     124  0     3                                       00          
 144   OpenWrite      5     125  0     k(2,,)                                  00          
 145   String8        0     68   0     deltas                                  00          
 146   Function0      1     68   64    nextval(1)                              01          
 147   NotNull        64    149  0                                             00          
 148   Integer        -1    64   0                                             00          
 149   MustBeInt      64    0    0                                             00          
 150   String8        0     69   0     deltas                                  00          
 151   Function0      1     69   65    nextval(1)                              01          
 152   Copy           65    70   0                                             00          
 153   Param          8     66   0                                             00          
 154   Copy           66    71   0                                             00          
 155   String8        0     67   0     update_project                          00          
 156   Copy           67    72   0                                             00          
 157   Affinity       65    3    0     DDB                                     00          
 158   Program        60    247  73    program                                 00          

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: Possible User Defined Function (UDF) Bug?

nomad
Here is a trimmed-down test case for my issue:

        CREATE TABLE d (
                id INTEGER NOT NULL PRIMARY KEY
        );


        CREATE TRIGGER
                bi_d
        BEFORE INSERT ON
                d
        FOR EACH ROW
        BEGIN
                select 1;
        END;


        INSERT INTO
                d
        VALUES(
                udf(1)
        );

VDBE Program Listing:
   0 Init             0   20    0               00 Start at 20
   1 OpenWrite        0    2    0 1             00 root=2 iDb=0; d
   2 Function0        1    5    3 udf(1)        01 r[3]=func(r[5])
   3 NotNull          3    5    0               00 if r[3]!=NULL goto 5
   4 Integer         -1    3    0               00 r[3]=-1
   5 MustBeInt        3    0    0               00
   6 Function0        1    6    4 udf(1)        01 r[4]=func(r[6])
   7 Copy             4    7    0               00 r[7]=r[4]
   8 Affinity         4    1    0 D             00 affinity(r[4])
   9 Program          1   19    8 program       00 Call: bi_d.default
  10 Copy             7    1    0               00 r[1]=r[7]
  11 NotNull          1   13    0               00 if r[1]!=NULL goto 13
  12 NewRowid         0    1    0               00 r[1]=rowid
  13 MustBeInt        1    0    0               00
  14 SoftNull         2    0    0               00 r[2]=NULL
  15 NotExists        0   17    1               00 intkey=r[1]
  16 Halt          1555    2    0 d.id          02
  17 MakeRecord       2    1    9 D             00 r[9]=mkrec(r[2])
  18 Insert           0    9    1 d             31 intkey=r[1] data=r[9]
  19 Halt             0    0    0               00
  20 Transaction      0    1    2 0             01 usesStmtJournal=1
  21 TableLock        0    2    1 d             00 iDb=0 root=2 write=1
  22 Integer          1    5    0               00 r[5]=1
  23 Integer          1    6    0               00 r[6]=1
  24 Goto             0    1    0               00

Note the two calls to Function0 in the above. If you create a udf()
function that prints a message you will see that it does in fact get
called twice.

I only see this happening when all three of the following statements
are true:

    - The UDF is used in a VALUES() statement
    - The destination table "d" has a PRIMARY KEY
    - There is a BEFORE INSERT trigger on "d"

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Re: Possible User Defined Function (UDF) Bug?

Hick Gunter
I suspect that the udf() function is called once to build the record and once again to build the parameter list for the trigger program.

-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:[hidden email]] Im Auftrag von [hidden email]
Gesendet: Dienstag, 28. November 2017 15:04
An: SQLite mailing list <[hidden email]>
Betreff: [EXTERNAL] Re: [sqlite] Possible User Defined Function (UDF) Bug?

Here is a trimmed-down test case for my issue:

        CREATE TABLE d (
                id INTEGER NOT NULL PRIMARY KEY
        );


        CREATE TRIGGER
                bi_d
        BEFORE INSERT ON
                d
        FOR EACH ROW
        BEGIN
                select 1;
        END;


        INSERT INTO
                d
        VALUES(
                udf(1)
        );

VDBE Program Listing:
   0 Init             0   20    0               00 Start at 20
   1 OpenWrite        0    2    0 1             00 root=2 iDb=0; d
   2 Function0        1    5    3 udf(1)        01 r[3]=func(r[5])
   3 NotNull          3    5    0               00 if r[3]!=NULL goto 5
   4 Integer         -1    3    0               00 r[3]=-1
   5 MustBeInt        3    0    0               00
   6 Function0        1    6    4 udf(1)        01 r[4]=func(r[6])
   7 Copy             4    7    0               00 r[7]=r[4]
   8 Affinity         4    1    0 D             00 affinity(r[4])
   9 Program          1   19    8 program       00 Call: bi_d.default
  10 Copy             7    1    0               00 r[1]=r[7]
  11 NotNull          1   13    0               00 if r[1]!=NULL goto 13
  12 NewRowid         0    1    0               00 r[1]=rowid
  13 MustBeInt        1    0    0               00
  14 SoftNull         2    0    0               00 r[2]=NULL
  15 NotExists        0   17    1               00 intkey=r[1]
  16 Halt          1555    2    0 d.id          02
  17 MakeRecord       2    1    9 D             00 r[9]=mkrec(r[2])
  18 Insert           0    9    1 d             31 intkey=r[1] data=r[9]
  19 Halt             0    0    0               00
  20 Transaction      0    1    2 0             01 usesStmtJournal=1
  21 TableLock        0    2    1 d             00 iDb=0 root=2 write=1
  22 Integer          1    5    0               00 r[5]=1
  23 Integer          1    6    0               00 r[6]=1
  24 Goto             0    1    0               00

Note the two calls to Function0 in the above. If you create a udf() function that prints a message you will see that it does in fact get called twice.

I only see this happening when all three of the following statements are true:

    - The UDF is used in a VALUES() statement
    - The destination table "d" has a PRIMARY KEY
    - There is a BEFORE INSERT trigger on "d"

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
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
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Re: Possible User Defined Function (UDF) Bug?

David Raymond
With an integer primary key, not just any primary key. Probably something to do with the deterministic flag as well. Looks like in checking if it's gonna be a good integer for a rowid it calls it twice. Below you can see where random() gets called twice, so what the before trigger inserts into another table is different than what gets put into the original table. If you have a deterministic function like abs() it just calls it once, or if you have a non-integer-primary-key table it just calls it once.


sqlite> create table d (id integer primary key);

sqlite> create table d2 (id int primary key);

sqlite> create table t (tableName text, id int);

sqlite> create trigger bi_d before insert on d begin insert into t values ('d', new.id); end;

sqlite> create trigger bi_d2 before insert on d2 begin insert into t values ('d2', new.id); end;

sqlite> insert into d values (random());

sqlite> insert into d2 values (random());

sqlite> select * from t;
tableName|id
d|-5810358455625904630
d2|-3456845157187719103

sqlite> select * from d;
id
6606271909038536929

sqlite> select * from d2;
id
-3456845157187719103

sqlite> explain insert into d values (random());
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     20    0                    00  Start at 20
1     OpenWrite      0     3     0     1              00  root=3 iDb=0; d
2     Function0      0     0     3     random(0)      00  r[3]=func(r[0])
3     NotNull        3     5     0                    00  if r[3]!=NULL goto 5
4     Integer        -1    3     0                    00  r[3]=-1
5     MustBeInt      3     0     0                    00
6     Function0      0     0     4     random(0)      00  r[4]=func(r[0])
7     Copy           4     5     0                    00  r[5]=r[4]
8     Affinity       4     1     0     D              00  affinity(r[4])
9     Program        1     19    6     program        01  Call: bi_d.default
10    Copy           5     1     0                    00  r[1]=r[5]
11    NotNull        1     13    0                    00  if r[1]!=NULL goto 13
12    NewRowid       0     1     0                    00  r[1]=rowid
13    MustBeInt      1     0     0                    00
14    SoftNull       2     0     0                    00  r[2]=NULL
15    NotExists      0     17    1                    00  intkey=r[1]
16    Halt           1555  2     0     d.id           02
17    MakeRecord     2     1     7     D              00  r[7]=mkrec(r[2])
18    Insert         0     7     1     d              31  intkey=r[1] data=r[7]
19    Halt           0     0     0                    00
20    Transaction    0     1     39    0              01  usesStmtJournal=1
21    Goto           0     1     0                    00
0     Init           0     1     0     -- TRIGGER bi_d  00  Start at 1; Start: bi_d.default (BEFORE INSERT ON d)
1     OpenWrite      0     2     0     2              00  root=2 iDb=0; t
2     NewRowid       0     1     0                    00  r[1]=rowid
3     String8        0     2     0     d              00  r[2]='d'
4     Param          2     3     0                    00  new.rowid -> $3
5     MakeRecord     2     2     4     BD             00  r[4]=mkrec(r[2..3])
6     Insert         0     4     1     t              39  intkey=r[1] data=r[4]
7     ResetCount     0     0     0                    00
8     Halt           0     0     0                    00  End: bi_d.default

sqlite> explain insert into d2 values (random());
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     20    0                    00  Start at 20
1     OpenWrite      0     4     0     1              00  root=4 iDb=0; d2
2     OpenWrite      1     5     0     k(2,,)         00  root=5 iDb=0; sqlite_autoindex_d2_1
3     Integer        -1    6     0                    00  r[6]=-1
4     Function0      0     0     7     random(0)      00  r[7]=func(r[0])
5     Copy           7     8     0                    00  r[8]=r[7]
6     Affinity       7     1     0     D              00  affinity(r[7])
7     Program        4     19    9     program        01  Call: bi_d2.default
8     NewRowid       0     1     0                    00  r[1]=rowid
9     Copy           8     2     0                    00  r[2]=r[8]
10    Affinity       2     1     0     D              00  affinity(r[2])
11    SCopy          2     4     0                    00  r[4]=r[2]; id
12    IntCopy        1     5     0                    00  r[5]=r[1]; rowid
13    MakeRecord     4     2     3                    00  r[3]=mkrec(r[4..5]); for sqlite_autoindex_d2_1
14    NoConflict     1     16    4     1              00  key=r[4]
15    Halt           1555  2     0     d2.id          02
16    IdxInsert      1     3     4     2              10  key=r[3]
17    MakeRecord     2     1     10                   00  r[10]=mkrec(r[2])
18    Insert         0     10    1     d2             39  intkey=r[1] data=r[10]
19    Halt           0     0     0                    00
20    Transaction    0     1     39    0              01  usesStmtJournal=1
21    Goto           0     1     0                    00
0     Init           0     1     0     -- TRIGGER bi_d2  00  Start at 1; Start: bi_d2.default (BEFORE INSERT ON d2)
1     OpenWrite      0     2     0     2              00  root=2 iDb=0; t
2     NewRowid       0     1     0                    00  r[1]=rowid
3     String8        0     2     0     d2             00  r[2]='d2'
4     Param          3     3     0                    00  new.id -> $3
5     MakeRecord     2     2     4     BD             00  r[4]=mkrec(r[2..3])
6     Insert         0     4     1     t              39  intkey=r[1] data=r[4]
7     ResetCount     0     0     0                    00
8     Halt           0     0     0                    00  End: bi_d2.default

sqlite> explain insert into d values (abs(1));
addr  opcode         p1    p2    p3    p4             p5  comment
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     20    0                    00  Start at 20
1     OpenWrite      0     3     0     1              00  root=3 iDb=0; d
2     SCopy          5     3     0                    00  r[3]=r[5]
3     NotNull        3     5     0                    00  if r[3]!=NULL goto 5
4     Integer        -1    3     0                    00  r[3]=-1
5     MustBeInt      3     0     0                    00
6     SCopy          5     4     0                    00  r[4]=r[5]
7     Copy           4     6     0                    00  r[6]=r[4]
8     Affinity       4     1     0     D              00  affinity(r[4])
9     Program        1     19    7     program        01  Call: bi_d.default
10    Copy           6     1     0                    00  r[1]=r[6]
11    NotNull        1     13    0                    00  if r[1]!=NULL goto 13
12    NewRowid       0     1     0                    00  r[1]=rowid
13    MustBeInt      1     0     0                    00
14    SoftNull       2     0     0                    00  r[2]=NULL
15    NotExists      0     17    1                    00  intkey=r[1]
16    Halt           1555  2     0     d.id           02
17    MakeRecord     2     1     8     D              00  r[8]=mkrec(r[2])
18    Insert         0     8     1     d              31  intkey=r[1] data=r[8]
19    Halt           0     0     0                    00
20    Transaction    0     1     39    0              01  usesStmtJournal=1
21    Integer        1     9     0                    00  r[9]=1
22    Function0      1     9     5     abs(1)         01  r[5]=func(r[9])
23    Goto           0     1     0                    00
0     Init           0     1     0     -- TRIGGER bi_d  00  Start at 1; Start: bi_d.default (BEFORE INSERT ON d)
1     OpenWrite      0     2     0     2              00  root=2 iDb=0; t
2     NewRowid       0     1     0                    00  r[1]=rowid
3     String8        0     2     0     d              00  r[2]='d'
4     Param          2     3     0                    00  new.rowid -> $3
5     MakeRecord     2     2     4     BD             00  r[4]=mkrec(r[2..3])
6     Insert         0     4     1     t              39  intkey=r[1] data=r[4]
7     ResetCount     0     0     0                    00
8     Halt           0     0     0                    00  End: bi_d.default

sqlite>


-----Original Message-----
From: sqlite-users [mailto:[hidden email]] On Behalf Of Hick Gunter
Sent: Tuesday, November 28, 2017 9:35 AM
To: 'SQLite mailing list'
Subject: Re: [sqlite] [EXTERNAL] Re: Possible User Defined Function (UDF) Bug?

I suspect that the udf() function is called once to build the record and once again to build the parameter list for the trigger program.

-----Ursprüngliche Nachricht-----
Von: sqlite-users [mailto:[hidden email]] Im Auftrag von [hidden email]
Gesendet: Dienstag, 28. November 2017 15:04
An: SQLite mailing list <[hidden email]>
Betreff: [EXTERNAL] Re: [sqlite] Possible User Defined Function (UDF) Bug?

Here is a trimmed-down test case for my issue:

        CREATE TABLE d (
                id INTEGER NOT NULL PRIMARY KEY
        );


        CREATE TRIGGER
                bi_d
        BEFORE INSERT ON
                d
        FOR EACH ROW
        BEGIN
                select 1;
        END;


        INSERT INTO
                d
        VALUES(
                udf(1)
        );

VDBE Program Listing:
   0 Init             0   20    0               00 Start at 20
   1 OpenWrite        0    2    0 1             00 root=2 iDb=0; d
   2 Function0        1    5    3 udf(1)        01 r[3]=func(r[5])
   3 NotNull          3    5    0               00 if r[3]!=NULL goto 5
   4 Integer         -1    3    0               00 r[3]=-1
   5 MustBeInt        3    0    0               00
   6 Function0        1    6    4 udf(1)        01 r[4]=func(r[6])
   7 Copy             4    7    0               00 r[7]=r[4]
   8 Affinity         4    1    0 D             00 affinity(r[4])
   9 Program          1   19    8 program       00 Call: bi_d.default
  10 Copy             7    1    0               00 r[1]=r[7]
  11 NotNull          1   13    0               00 if r[1]!=NULL goto 13
  12 NewRowid         0    1    0               00 r[1]=rowid
  13 MustBeInt        1    0    0               00
  14 SoftNull         2    0    0               00 r[2]=NULL
  15 NotExists        0   17    1               00 intkey=r[1]
  16 Halt          1555    2    0 d.id          02
  17 MakeRecord       2    1    9 D             00 r[9]=mkrec(r[2])
  18 Insert           0    9    1 d             31 intkey=r[1] data=r[9]
  19 Halt             0    0    0               00
  20 Transaction      0    1    2 0             01 usesStmtJournal=1
  21 TableLock        0    2    1 d             00 iDb=0 root=2 write=1
  22 Integer          1    5    0               00 r[5]=1
  23 Integer          1    6    0               00 r[6]=1
  24 Goto             0    1    0               00

Note the two calls to Function0 in the above. If you create a udf() function that prints a message you will see that it does in fact get called twice.

I only see this happening when all three of the following statements are true:

    - The UDF is used in a VALUES() statement
    - The destination table "d" has a PRIMARY KEY
    - There is a BEFORE INSERT trigger on "d"

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
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
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Re: Possible User Defined Function (UDF) Bug?

nomad
On Tue Nov 28, 2017 at 03:30:54PM +0000, David Raymond wrote:

> With an integer primary key, not just any primary key. Probably
> something to do with the deterministic flag as well. Looks like in
> checking if it's gonna be a good integer for a rowid it calls it
> twice. Below you can see where random() gets called twice, so what
> the before trigger inserts into another table is different than what
> gets put into the original table. If you have a deterministic
> function like abs() it just calls it once, or if you have a
> non-integer-primary-key table it just calls it once.
>
>
> sqlite> create table d (id integer primary key);
>
> sqlite> create table d2 (id int primary key);
>
> sqlite> create table t (tableName text, id int);
>
> sqlite> create trigger bi_d before insert on d begin insert into t values ('d', new.id); end;
>
> sqlite> create trigger bi_d2 before insert on d2 begin insert into t values ('d2', new.id); end;
>
> sqlite> insert into d values (random());
>
> sqlite> insert into d2 values (random());
>
> sqlite> select * from t;
> tableName|id
> d|-5810358455625904630
> d2|-3456845157187719103
>
> sqlite> select * from d;
> id
> 6606271909038536929
>
> sqlite> select * from d2;
> id
> -3456845157187719103

That looks like a good test case to me. This is certainly a regression
as earlier versions of SQLite don't show the same behaviour.

SQLite developers, do you recognise this thread as an issue? I've seen
other topics come and go and be fixed in the meantime, but no statement
on this one.

--
Mark Lawrence
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
Reply | Threaded
Open this post in threaded view
|

Re: [EXTERNAL] Re: Possible User Defined Function (UDF) Bug?

Richard Hipp-3
On 12/5/17, [hidden email] <[hidden email]> wrote:
> On Tue Nov 28, 2017 at 03:30:54PM +0000, David Raymond wrote:
>
> SQLite developers, do you recognise this thread as an issue?

Not a serious issue, no.  I might look into it when I have time, but
I'm neck-deep in other issues at the moment.

--
D. Richard Hipp
[hidden email]
_______________________________________________
sqlite-users mailing list
[hidden email]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users