• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / tarantool / 11857

pending completion
11857

push

travis-ci

kshcherbatov
sql: remove zName and nColumn from SQL

1. Removed zName from SQL Column.
2. Removed zColumns from SQL Table.
3. Refactored Parser to use def_expression directly.
4. Introduced sql_table_def_rebuild intended for collect
fragmented with sql_field_retrieve space_def into memory
located in one allocation.

Needed for #3272.

236 of 236 new or added lines in 15 files covered. (100.0%)

60574 of 74997 relevant lines covered (80.77%)

1467669.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.06
/src/box/sql/fkey.c
1
/*
2
 * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above
9
 *    copyright notice, this list of conditions and the
10
 *    following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above
13
 *    copyright notice, this list of conditions and the following
14
 *    disclaimer in the documentation and/or other materials
15
 *    provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
 * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
 * SUCH DAMAGE.
30
 */
31

32
/*
33
 * This file contains code used by the compiler to add foreign key
34
 * support to compiled SQL statements.
35
 */
36
#include <box/coll.h>
37
#include "sqliteInt.h"
38
#include "box/session.h"
39
#include "tarantoolInt.h"
40

41
#ifndef SQLITE_OMIT_FOREIGN_KEY
42
#ifndef SQLITE_OMIT_TRIGGER
43

44
/*
45
 * Deferred and Immediate FKs
46
 * --------------------------
47
 *
48
 * Foreign keys in SQLite come in two flavours: deferred and immediate.
49
 * If an immediate foreign key constraint is violated,
50
 * SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current
51
 * statement transaction rolled back. If a
52
 * deferred foreign key constraint is violated, no action is taken
53
 * immediately. However if the application attempts to commit the
54
 * transaction before fixing the constraint violation, the attempt fails.
55
 *
56
 * Deferred constraints are implemented using a simple counter associated
57
 * with the database handle. The counter is set to zero each time a
58
 * database transaction is opened. Each time a statement is executed
59
 * that causes a foreign key violation, the counter is incremented. Each
60
 * time a statement is executed that removes an existing violation from
61
 * the database, the counter is decremented. When the transaction is
62
 * committed, the commit fails if the current value of the counter is
63
 * greater than zero. This scheme has two big drawbacks:
64
 *
65
 *   * When a commit fails due to a deferred foreign key constraint,
66
 *     there is no way to tell which foreign constraint is not satisfied,
67
 *     or which row it is not satisfied for.
68
 *
69
 *   * If the database contains foreign key violations when the
70
 *     transaction is opened, this may cause the mechanism to malfunction.
71
 *
72
 * Despite these problems, this approach is adopted as it seems simpler
73
 * than the alternatives.
74
 *
75
 * INSERT operations:
76
 *
77
 *   I.1) For each FK for which the table is the child table, search
78
 *        the parent table for a match. If none is found increment the
79
 *        constraint counter.
80
 *
81
 *   I.2) For each FK for which the table is the parent table,
82
 *        search the child table for rows that correspond to the new
83
 *        row in the parent table. Decrement the counter for each row
84
 *        found (as the constraint is now satisfied).
85
 *
86
 * DELETE operations:
87
 *
88
 *   D.1) For each FK for which the table is the child table,
89
 *        search the parent table for a row that corresponds to the
90
 *        deleted row in the child table. If such a row is not found,
91
 *        decrement the counter.
92
 *
93
 *   D.2) For each FK for which the table is the parent table, search
94
 *        the child table for rows that correspond to the deleted row
95
 *        in the parent table. For each found increment the counter.
96
 *
97
 * UPDATE operations:
98
 *
99
 *   An UPDATE command requires that all 4 steps above are taken, but only
100
 *   for FK constraints for which the affected columns are actually
101
 *   modified (values must be compared at runtime).
102
 *
103
 * Note that I.1 and D.1 are very similar operations, as are I.2 and D.2.
104
 * This simplifies the implementation a bit.
105
 *
106
 * For the purposes of immediate FK constraints, the OR REPLACE conflict
107
 * resolution is considered to delete rows before the new row is inserted.
108
 * If a delete caused by OR REPLACE violates an FK constraint, an exception
109
 * is thrown, even if the FK constraint would be satisfied after the new
110
 * row is inserted.
111
 *
112
 * Immediate constraints are usually handled similarly. The only difference
113
 * is that the counter used is stored as part of each individual statement
114
 * object (struct Vdbe). If, after the statement has run, its immediate
115
 * constraint counter is greater than zero,
116
 * it returns SQLITE_CONSTRAINT_FOREIGNKEY
117
 * and the statement transaction is rolled back. An exception is an INSERT
118
 * statement that inserts a single row only (no triggers). In this case,
119
 * instead of using a counter, an exception is thrown immediately if the
120
 * INSERT violates a foreign key constraint. This is necessary as such
121
 * an INSERT does not open a statement transaction.
122
 *
123
 * TODO: How should dropping a table be handled? How should renaming a
124
 * table be handled?
125
 *
126
 *
127
 * Query API Notes
128
 * ---------------
129
 *
130
 * Before coding an UPDATE or DELETE row operation, the code-generator
131
 * for those two operations needs to know whether or not the operation
132
 * requires any FK processing and, if so, which columns of the original
133
 * row are required by the FK processing VDBE code (i.e. if FKs were
134
 * implemented using triggers, which of the old.* columns would be
135
 * accessed). No information is required by the code-generator before
136
 * coding an INSERT operation. The functions used by the UPDATE/DELETE
137
 * generation code to query for this information are:
138
 *
139
 *   sqlite3FkRequired() - Test to see if FK processing is required.
140
 *   sqlite3FkOldmask()  - Query for the set of required old.* columns.
141
 *
142
 *
143
 * Externally accessible module functions
144
 * --------------------------------------
145
 *
146
 *   sqlite3FkCheck()    - Check for foreign key violations.
147
 *   sqlite3FkActions()  - Code triggers for ON UPDATE/ON DELETE actions.
148
 *   sqlite3FkDelete()   - Delete an FKey structure.
149
 */
150

151
/*
152
 * VDBE Calling Convention
153
 * -----------------------
154
 *
155
 * Example:
156
 *
157
 *   For the following INSERT statement:
158
 *
159
 *     CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c);
160
 *     INSERT INTO t1 VALUES(1, 2, 3.1);
161
 *
162
 *   Register (x):        2    (type integer)
163
 *   Register (x+1):      1    (type integer)
164
 *   Register (x+2):      NULL (type NULL)
165
 *   Register (x+3):      3.1  (type real)
166
 */
167

168
/*
169
 * A foreign key constraint requires that the key columns in the parent
170
 * table are collectively subject to a UNIQUE or PRIMARY KEY constraint.
171
 * Given that pParent is the parent table for foreign key constraint pFKey,
172
 * search the schema for a unique index on the parent key columns.
173
 *
174
 * If successful, zero is returned. If the parent key is an INTEGER PRIMARY
175
 * KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx
176
 * is set to point to the unique index.
177
 *
178
 * If the parent key consists of a single column (the foreign key constraint
179
 * is not a composite foreign key), output variable *paiCol is set to NULL.
180
 * Otherwise, it is set to point to an allocated array of size N, where
181
 * N is the number of columns in the parent key. The first element of the
182
 * array is the index of the child table column that is mapped by the FK
183
 * constraint to the parent table column stored in the left-most column
184
 * of index *ppIdx. The second element of the array is the index of the
185
 * child table column that corresponds to the second left-most column of
186
 * *ppIdx, and so on.
187
 *
188
 * If the required index cannot be found, either because:
189
 *
190
 *   1) The named parent key columns do not exist, or
191
 *
192
 *   2) The named parent key columns do exist, but are not subject to a
193
 *      UNIQUE or PRIMARY KEY constraint, or
194
 *
195
 *   3) No parent key columns were provided explicitly as part of the
196
 *      foreign key definition, and the parent table does not have a
197
 *      PRIMARY KEY, or
198
 *
199
 *   4) No parent key columns were provided explicitly as part of the
200
 *      foreign key definition, and the PRIMARY KEY of the parent table
201
 *      consists of a different number of columns to the child key in
202
 *      the child table.
203
 *
204
 * then non-zero is returned, and a "foreign key mismatch" error loaded
205
 * into pParse. If an OOM error occurs, non-zero is returned and the
206
 * pParse->db->mallocFailed flag is set.
207
 */
208
int
209
sqlite3FkLocateIndex(Parse * pParse,        /* Parse context to store any error in */
646✔
210
                     Table * pParent,        /* Parent table of FK constraint pFKey */
211
                     FKey * pFKey,        /* Foreign key to find index for */
212
                     Index ** ppIdx,        /* OUT: Unique index on parent table */
213
                     int **paiCol        /* OUT: Map of index columns in pFKey */
214
    )
215
{
216
        Index *pIdx = 0;        /* Value to return via *ppIdx */
646✔
217
        int *aiCol = 0;                /* Value to return via *paiCol */
646✔
218
        int nCol = pFKey->nCol;        /* Number of columns in parent key */
646✔
219
        char *zKey = pFKey->aCol[0].zCol;        /* Name of left-most parent key column */
646✔
220

221
        /* The caller is responsible for zeroing output parameters. */
222
        assert(ppIdx && *ppIdx == 0);
646✔
223
        assert(!paiCol || *paiCol == 0);
646✔
224
        assert(pParse);
646✔
225

226
        /* If this is a non-composite (single column) foreign key, check if it
227
         * maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx
228
         * and *paiCol set to zero and return early.
229
         *
230
         * Otherwise, for a composite foreign key (more than one column), allocate
231
         * space for the aiCol array (returned via output parameter *paiCol).
232
         * Non-composite foreign keys do not require the aiCol array.
233
         */
234
        if (nCol == 1) {
646✔
235
                /* The FK maps to the IPK if any of the following are true:
236
                 *
237
                 *   1) There is an INTEGER PRIMARY KEY column and the FK is implicitly
238
                 *      mapped to the primary key of table pParent, or
239
                 *   2) The FK is explicitly mapped to a column declared as INTEGER
240
                 *      PRIMARY KEY.
241
                 */
242
                if (pParent->iPKey >= 0) {
549✔
243
                        if (!zKey)
×
244
                                return 0;
×
245
                        if (!strcmp
×
246
                            (pParent->def->fields[pParent->iPKey].name, zKey))
×
247
                                return 0;
×
248
                }
249
        } else if (paiCol) {
97✔
250
                assert(nCol > 1);
78✔
251
                aiCol =
78✔
252
                    (int *)sqlite3DbMallocRawNN(pParse->db, nCol * sizeof(int));
78✔
253
                if (!aiCol)
78✔
254
                        return 1;
×
255
                *paiCol = aiCol;
78✔
256
        }
257

258
        for (pIdx = pParent->pIndex; pIdx; pIdx = pIdx->pNext) {
754✔
259
                int nIdxCol = index_column_count(pIdx);
747✔
260
                if (nIdxCol == nCol && index_is_unique(pIdx)
747✔
261
                    && pIdx->pPartIdxWhere == 0) {
675✔
262
                        /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
263
                         * of columns. If each indexed column corresponds to a foreign key
264
                         * column of pFKey, then this index is a winner.
265
                         */
266

267
                        if (zKey == 0) {
674✔
268
                                /* If zKey is NULL, then this foreign key is implicitly mapped to
269
                                 * the PRIMARY KEY of table pParent. The PRIMARY KEY index may be
270
                                 * identified by the test.
271
                                 */
272
                                if (IsPrimaryKeyIndex(pIdx)) {
377✔
273
                                        if (aiCol) {
377✔
274
                                                int i;
275
                                                for (i = 0; i < nCol; i++)
81✔
276
                                                        aiCol[i] =
108✔
277
                                                            pFKey->aCol[i].
54✔
278
                                                            iFrom;
279
                                        }
280
                                        break;
377✔
281
                                }
282
                        } else {
283
                                /* If zKey is non-NULL, then this foreign key was declared to
284
                                 * map to an explicit list of columns in table pParent. Check if this
285
                                 * index matches those columns. Also, check that the index uses
286
                                 * the default collation sequences for each column.
287
                                 */
288
                                int i, j;
289
                                for (i = 0; i < nCol; i++) {
624✔
290
                                        i16 iCol = pIdx->aiColumn[i];        /* Index of column in parent tbl */
362✔
291
                                        const char *zDfltColl;        /* Def. collation for column */
292
                                        char *zIdxCol;        /* Name of indexed column */
293

294
                                        if (iCol < 0)
362✔
295
                                                break;        /* No foreign keys against expression indexes */
×
296

297
                                        /* If the index uses a collation sequence that is different from
298
                                         * the default collation sequence for the column, this index is
299
                                         * unusable. Bail out early in this case.
300
                                         */
301
                                        zDfltColl =
362✔
302
                                                column_collation_name(pParent,
362✔
303
                                                                      iCol);
304
                                        if (strcmp
362✔
305
                                            (index_collation_name(pIdx, i), zDfltColl))
306
                                                break;
1✔
307

308
                                        zIdxCol = pParent->def->fields[iCol].name;
361✔
309
                                        for (j = 0; j < nCol; j++) {
460✔
310
                                                if (strcmp
426✔
311
                                                    (pFKey->aCol[j].zCol,
426✔
312
                                                     zIdxCol) == 0) {
313
                                                        if (aiCol)
327✔
314
                                                                aiCol[i] =
202✔
315
                                                                    pFKey->
316
                                                                    aCol[j].
101✔
317
                                                                    iFrom;
318
                                                        break;
327✔
319
                                                }
320
                                        }
321
                                        if (j == nCol)
361✔
322
                                                break;
34✔
323
                                }
324
                                if (i == nCol)
297✔
325
                                        break;        /* pIdx is usable */
262✔
326
                        }
327
                }
328
        }
329

330
        if (!pIdx) {
646✔
331
                if (!pParse->disableTriggers) {
7✔
332
                        sqlite3ErrorMsg(pParse,
14✔
333
                                        "foreign key mismatch - \"%w\" referencing \"%w\"",
334
                                        pFKey->pFrom->zName, pFKey->zTo);
7✔
335
                }
336
                sqlite3DbFree(pParse->db, aiCol);
7✔
337
                return 1;
7✔
338
        }
339

340
        *ppIdx = pIdx;
639✔
341
        return 0;
639✔
342
}
343

344
/*
345
 * This function is called when a row is inserted into or deleted from the
346
 * child table of foreign key constraint pFKey. If an SQL UPDATE is executed
347
 * on the child table of pFKey, this function is invoked twice for each row
348
 * affected - once to "delete" the old row, and then again to "insert" the
349
 * new row.
350
 *
351
 * Each time it is called, this function generates VDBE code to locate the
352
 * row in the parent table that corresponds to the row being inserted into
353
 * or deleted from the child table. If the parent row can be found, no
354
 * special action is taken. Otherwise, if the parent row can *not* be
355
 * found in the parent table:
356
 *
357
 *   Operation | FK type   | Action taken
358
 *   --------------------------------------------------------------------------
359
 *   INSERT      immediate   Increment the "immediate constraint counter".
360
 *
361
 *   DELETE      immediate   Decrement the "immediate constraint counter".
362
 *
363
 *   INSERT      deferred    Increment the "deferred constraint counter".
364
 *
365
 *   DELETE      deferred    Decrement the "deferred constraint counter".
366
 *
367
 * These operations are identified in the comment at the top of this file
368
 * (fkey.c) as "I.1" and "D.1".
369
 */
370
static void
371
fkLookupParent(Parse * pParse,        /* Parse context */
306✔
372
               Table * pTab,        /* Parent table of FK pFKey */
373
               Index * pIdx,        /* Unique index on parent key columns in pTab */
374
               FKey * pFKey,        /* Foreign key constraint */
375
               int *aiCol,        /* Map from parent key columns to child table columns */
376
               int regData,        /* Address of array containing child table row */
377
               int nIncr,        /* Increment constraint counter by this */
378
               int isIgnore        /* If true, pretend pTab contains all NULL values */
379
    )
380
{
381
        int i;                        /* Iterator variable */
382
        Vdbe *v = sqlite3GetVdbe(pParse);        /* Vdbe to add code to */
306✔
383
        int iCur = pParse->nTab - 1;        /* Cursor number to use */
306✔
384
        int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */
306✔
385
        struct session *user_session = current_session();
306✔
386

387
        /* If nIncr is less than zero, then check at runtime if there are any
388
         * outstanding constraints to resolve. If there are not, there is no need
389
         * to check if deleting this row resolves any outstanding violations.
390
         *
391
         * Check if any of the key columns in the child table row are NULL. If
392
         * any are, then the constraint is considered satisfied. No need to
393
         * search for a matching row in the parent table.
394
         */
395
        if (nIncr < 0) {
306✔
396
                sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
93✔
397
                VdbeCoverage(v);
398
        }
399
        for (i = 0; i < pFKey->nCol; i++) {
660✔
400
                int iReg = aiCol[i] + regData + 1;
354✔
401
                sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
354✔
402
                VdbeCoverage(v);
403
        }
404

405
        if (isIgnore == 0) {
306✔
406
                if (pIdx == 0) {
306✔
407
                        /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY
408
                         * column of the parent table (table pTab).
409
                         */
410
                        int regTemp = sqlite3GetTempReg(pParse);
×
411

412
                        /* Invoke MustBeInt to coerce the child key value to an integer (i.e.
413
                         * apply the affinity of the parent key). If this fails, then there
414
                         * is no matching parent key. Before using MustBeInt, make a copy of
415
                         * the value. Otherwise, the value inserted into the child key column
416
                         * will have INTEGER affinity applied to it, which may not be correct.
417
                         */
418
                        sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0] + 1 + regData,
×
419
                                          regTemp);
420
                        VdbeCoverage(v);
421

422
                        /* If the parent table is the same as the child table, and we are about
423
                         * to increment the constraint-counter (i.e. this is an INSERT operation),
424
                         * then check if the row being inserted matches itself. If so, do not
425
                         * increment the constraint-counter.
426
                         */
427
                        if (pTab == pFKey->pFrom && nIncr == 1) {
×
428
                                sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk,
×
429
                                                  regTemp);
430
                                VdbeCoverage(v);
431
                                sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
×
432
                        }
433

434
                } else {
435
                        int nCol = pFKey->nCol;
306✔
436
                        int regTemp = sqlite3GetTempRange(pParse, nCol);
306✔
437
                        int regRec = sqlite3GetTempReg(pParse);
306✔
438

439
                        emit_open_cursor(pParse, iCur, pIdx->tnum);
306✔
440
                        sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
306✔
441
                        for (i = 0; i < nCol; i++) {
660✔
442
                                sqlite3VdbeAddOp2(v, OP_Copy,
708✔
443
                                                  aiCol[i] + 1 + regData,
354✔
444
                                                  regTemp + i);
445
                        }
446

447
                        /* If the parent table is the same as the child table, and we are about
448
                         * to increment the constraint-counter (i.e. this is an INSERT operation),
449
                         * then check if the row being inserted matches itself. If so, do not
450
                         * increment the constraint-counter.
451
                         *
452
                         * If any of the parent-key values are NULL, then the row cannot match
453
                         * itself. So set JUMPIFNULL to make sure we do the OP_Found if any
454
                         * of the parent-key values are NULL (at this point it is known that
455
                         * none of the child key values are).
456
                         */
457
                        if (pTab == pFKey->pFrom && nIncr == 1) {
306✔
458
                                int iJump =
73✔
459
                                    sqlite3VdbeCurrentAddr(v) + nCol + 1;
73✔
460
                                for (i = 0; i < nCol; i++) {
167✔
461
                                        int iChild = aiCol[i] + 1 + regData;
94✔
462
                                        int iParent =
94✔
463
                                            pIdx->aiColumn[i] + 1 + regData;
94✔
464
                                        assert(pIdx->aiColumn[i] >= 0);
94✔
465
                                        assert(aiCol[i] != pTab->iPKey);
94✔
466
                                        if (pIdx->aiColumn[i] == pTab->iPKey) {
94✔
467
                                                /* The parent key is a composite key that includes the IPK column */
468
                                                iParent = regData;
×
469
                                        }
470
                                        sqlite3VdbeAddOp3(v, OP_Ne, iChild,
94✔
471
                                                          iJump, iParent);
472
                                        VdbeCoverage(v);
473
                                        sqlite3VdbeChangeP5(v,
94✔
474
                                                            SQLITE_JUMPIFNULL);
475
                                }
476
                                sqlite3VdbeGoto(v, iOk);
73✔
477
                        }
478

479
                        sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol,
306✔
480
                                          regRec,
481
                                          sqlite3IndexAffinityStr(pParse->db,
482
                                                                  pIdx), nCol);
483
                        sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
306✔
484
                        VdbeCoverage(v);
485

486
                        sqlite3ReleaseTempReg(pParse, regRec);
306✔
487
                        sqlite3ReleaseTempRange(pParse, regTemp, nCol);
306✔
488
                }
489
        }
490

491
        if (!pFKey->isDeferred && !(user_session->sql_flags & SQLITE_DeferFKs)
306✔
492
            && !pParse->pToplevel && !pParse->isMultiWrite) {
285✔
493
                /* Special case: If this is an INSERT statement that will insert exactly
494
                 * one row into the table, raise a constraint immediately instead of
495
                 * incrementing a counter. This is necessary as the VM code is being
496
                 * generated for will not open a statement transaction.
497
                 */
498
                assert(nIncr == 1);
146✔
499
                sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
146✔
500
                                      ON_CONFLICT_ACTION_ABORT, 0, P4_STATIC,
501
                                      P5_ConstraintFK);
502
        } else {
503
                if (nIncr > 0 && pFKey->isDeferred == 0) {
160✔
504
                        sqlite3MayAbort(pParse);
54✔
505
                }
506
                sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
160✔
507
        }
508

509
        sqlite3VdbeResolveLabel(v, iOk);
306✔
510
        sqlite3VdbeAddOp1(v, OP_Close, iCur);
306✔
511
}
306✔
512

513
/*
514
 * Return an Expr object that refers to a memory register corresponding
515
 * to column iCol of table pTab.
516
 *
517
 * regBase is the first of an array of register that contains the data
518
 * for pTab.  regBase+1 holds the first column.
519
 * regBase+2 holds the second column, and so forth.
520
 */
521
static Expr *
522
exprTableRegister(Parse * pParse,        /* Parsing and code generating context */
245✔
523
                  Table * pTab,        /* The table whose content is at r[regBase]... */
524
                  int regBase,        /* Contents of table pTab */
525
                  i16 iCol        /* Which column of pTab is desired */
526
    )
527
{
528
        Expr *pExpr;
529
        Column *pCol;
530
        const char *zColl;
531
        sqlite3 *db = pParse->db;
245✔
532

533
        pExpr = sqlite3Expr(db, TK_REGISTER, 0);
245✔
534
        if (pExpr) {
245✔
535
                if (iCol >= 0 && iCol != pTab->iPKey) {
245✔
536
                        pCol = &pTab->aCol[iCol];
245✔
537
                        pExpr->iTable = regBase + iCol + 1;
245✔
538
                        pExpr->affinity = pCol->affinity;
245✔
539
                        zColl = column_collation_name(pTab, iCol);
245✔
540
                        pExpr =
245✔
541
                            sqlite3ExprAddCollateString(pParse, pExpr, zColl);
542
                } else {
543
                        pExpr->iTable = regBase;
×
544
                        pExpr->affinity = SQLITE_AFF_INTEGER;
×
545
                }
546
        }
547
        return pExpr;
245✔
548
}
549

550
/*
551
 * Return an Expr object that refers to column iCol of table pTab which
552
 * has cursor iCur.
553
 */
554
static Expr *
555
exprTableColumn(sqlite3 * db,        /* The database connection */
37✔
556
                Table * pTab,        /* The table whose column is desired */
557
                int iCursor,        /* The open cursor on the table */
558
                i16 iCol        /* The column that is wanted */
559
    )
560
{
561
        Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
37✔
562
        if (pExpr) {
37✔
563
                pExpr->pTab = pTab;
37✔
564
                pExpr->iTable = iCursor;
37✔
565
                pExpr->iColumn = iCol;
37✔
566
        }
567
        return pExpr;
37✔
568
}
569

570
/*
571
 * This function is called to generate code executed when a row is deleted
572
 * from the parent table of foreign key constraint pFKey and, if pFKey is
573
 * deferred, when a row is inserted into the same table. When generating
574
 * code for an SQL UPDATE operation, this function may be called twice -
575
 * once to "delete" the old row and once to "insert" the new row.
576
 *
577
 * Parameter nIncr is passed -1 when inserting a row (as this may decrease
578
 * the number of FK violations in the db) or +1 when deleting one (as this
579
 * may increase the number of FK constraint problems).
580
 *
581
 * The code generated by this function scans through the rows in the child
582
 * table that correspond to the parent table row being deleted or inserted.
583
 * For each child row found, one of the following actions is taken:
584
 *
585
 *   Operation | FK type   | Action taken
586
 *   --------------------------------------------------------------------------
587
 *   DELETE      immediate   Increment the "immediate constraint counter".
588
 *                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
589
 *                           throw a "FOREIGN KEY constraint failed" exception.
590
 *
591
 *   INSERT      immediate   Decrement the "immediate constraint counter".
592
 *
593
 *   DELETE      deferred    Increment the "deferred constraint counter".
594
 *                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
595
 *                           throw a "FOREIGN KEY constraint failed" exception.
596
 *
597
 *   INSERT      deferred    Decrement the "deferred constraint counter".
598
 *
599
 * These operations are identified in the comment at the top of this file
600
 * (fkey.c) as "I.2" and "D.2".
601
 */
602
static void
603
fkScanChildren(Parse * pParse,        /* Parse context */
183✔
604
               SrcList * pSrc,        /* The child table to be scanned */
605
               Table * pTab,        /* The parent table */
606
               Index * pIdx,        /* Index on parent covering the foreign key */
607
               FKey * pFKey,        /* The foreign key linking pSrc to pTab */
608
               int *aiCol,        /* Map from pIdx cols to child table cols */
609
               int regData,        /* Parent row data starts here */
610
               int nIncr        /* Amount to increment deferred counter by */
611
    )
612
{
613
        sqlite3 *db = pParse->db;        /* Database handle */
183✔
614
        int i;                        /* Iterator variable */
615
        Expr *pWhere = 0;        /* WHERE clause to scan with */
183✔
616
        NameContext sNameContext;        /* Context used to resolve WHERE clause */
617
        WhereInfo *pWInfo;        /* Context used by sqlite3WhereXXX() */
618
        int iFkIfZero = 0;        /* Address of OP_FkIfZero */
183✔
619
        Vdbe *v = sqlite3GetVdbe(pParse);
183✔
620

621
        assert(pIdx == 0 || pIdx->pTable == pTab);
183✔
622
        assert(pIdx == 0 || (int)index_column_count(pIdx) == pFKey->nCol);
183✔
623
        assert(pIdx != 0);
183✔
624

625
        if (nIncr < 0) {
183✔
626
                iFkIfZero =
74✔
627
                    sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
74✔
628
                VdbeCoverage(v);
629
        }
630

631
        /* Create an Expr object representing an SQL expression like:
632
         *
633
         *   <parent-key1> = <child-key1> AND <parent-key2> = <child-key2> ...
634
         *
635
         * The collation sequence used for the comparison should be that of
636
         * the parent key columns. The affinity of the parent key column should
637
         * be applied to each child key value before the comparison takes place.
638
         */
639
        for (i = 0; i < pFKey->nCol; i++) {
391✔
640
                Expr *pLeft;        /* Value from parent table row */
641
                Expr *pRight;        /* Column ref to child table */
642
                Expr *pEq;        /* Expression (pLeft = pRight) */
643
                i16 iCol;        /* Index of column in child table */
644
                const char *zCol;        /* Name of column in child table */
645

646
                iCol = pIdx ? pIdx->aiColumn[i] : -1;
208✔
647
                pLeft = exprTableRegister(pParse, pTab, regData, iCol);
208✔
648
                iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
208✔
649
                assert(iCol >= 0);
208✔
650
                zCol = pFKey->pFrom->def->fields[iCol].name;
208✔
651
                pRight = sqlite3Expr(db, TK_ID, zCol);
208✔
652
                pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
208✔
653
                pWhere = sqlite3ExprAnd(db, pWhere, pEq);
208✔
654
        }
655

656
        /* If the child table is the same as the parent table, then add terms
657
         * to the WHERE clause that prevent this entry from being scanned.
658
         * The added WHERE clause terms are like this:
659
         *
660
         *     NOT( $current_a==a AND $current_b==b AND ... )
661
         *     The primary key is (a,b,...)
662
         */
663
        if (pTab == pFKey->pFrom && nIncr > 0) {
183✔
664
                Expr *pNe;        /* Expression (pLeft != pRight) */
665
                Expr *pLeft;        /* Value from parent table row */
666
                Expr *pRight;        /* Column ref to child table */
667

668
                Expr *pEq, *pAll = 0;
37✔
669
                Index *pPk = sqlite3PrimaryKeyIndex(pTab);
37✔
670
                assert(pIdx != 0);
37✔
671
                int col_count = index_column_count(pPk);
37✔
672
                for (i = 0; i < col_count; i++) {
74✔
673
                        i16 iCol = pIdx->aiColumn[i];
37✔
674
                        assert(iCol >= 0);
37✔
675
                        pLeft = exprTableRegister(pParse, pTab, regData, iCol);
37✔
676
                        pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor,
37✔
677
                                                 iCol);
678
                        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
37✔
679
                        pAll = sqlite3ExprAnd(db, pAll, pEq);
37✔
680
                }
681
                pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
37✔
682
                pWhere = sqlite3ExprAnd(db, pWhere, pNe);
37✔
683
        }
684

685
        /* Resolve the references in the WHERE clause. */
686
        memset(&sNameContext, 0, sizeof(NameContext));
183✔
687
        sNameContext.pSrcList = pSrc;
183✔
688
        sNameContext.pParse = pParse;
183✔
689
        sqlite3ResolveExprNames(&sNameContext, pWhere);
183✔
690

691
        /* Create VDBE to loop through the entries in pSrc that match the WHERE
692
         * clause. For each row found, increment either the deferred or immediate
693
         * foreign key constraint counter.
694
         */
695
        pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
183✔
696
        sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
183✔
697
        if (pWInfo) {
183✔
698
                sqlite3WhereEnd(pWInfo);
183✔
699
        }
700

701
        /* Clean up the WHERE clause constructed above. */
702
        sql_expr_free(db, pWhere, false);
183✔
703
        if (iFkIfZero)
183✔
704
                sqlite3VdbeJumpHere(v, iFkIfZero);
74✔
705
}
183✔
706

707
/*
708
 * This function returns a linked list of FKey objects (connected by
709
 * FKey.pNextTo) holding all children of table pTab.  For example,
710
 * given the following schema:
711
 *
712
 *   CREATE TABLE t1(a PRIMARY KEY);
713
 *   CREATE TABLE t2(b REFERENCES t1(a);
714
 *
715
 * Calling this function with table "t1" as an argument returns a pointer
716
 * to the FKey structure representing the foreign key constraint on table
717
 * "t2". Calling this function with "t2" as the argument would return a
718
 * NULL pointer (as there are no FK constraints for which t2 is the parent
719
 * table).
720
 */
721
FKey *
722
sqlite3FkReferences(Table * pTab)
231,479✔
723
{
724
        return (FKey *) sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
231,479✔
725
}
726

727
/*
728
 * The second argument is a Trigger structure allocated by the
729
 * fkActionTrigger() routine. This function deletes the Trigger structure
730
 * and all of its sub-components.
731
 *
732
 * The Trigger structure or any of its sub-components may be allocated from
733
 * the lookaside buffer belonging to database handle dbMem.
734
 */
735
static void
736
fkTriggerDelete(sqlite3 * dbMem, Trigger * p)
326✔
737
{
738
        if (p) {
326✔
739
                TriggerStep *pStep = p->step_list;
22✔
740
                sql_expr_free(dbMem, pStep->pWhere, false);
22✔
741
                sqlite3ExprListDelete(dbMem, pStep->pExprList);
22✔
742
                sqlite3SelectDelete(dbMem, pStep->pSelect);
22✔
743
                sql_expr_free(dbMem, p->pWhen, false);
22✔
744
                sqlite3DbFree(dbMem, p);
22✔
745
        }
746
}
326✔
747

748
/*
749
 * This function is called to generate code that runs when table pTab is
750
 * being dropped from the database. The SrcList passed as the second argument
751
 * to this function contains a single entry guaranteed to resolve to
752
 * table pTab.
753
 *
754
 * Normally, no code is required. However, if either
755
 *
756
 *   (a) The table is the parent table of a FK constraint, or
757
 *   (b) The table is the child table of a deferred FK constraint and it is
758
 *       determined at runtime that there are outstanding deferred FK
759
 *       constraint violations in the database,
760
 *
761
 * then the equivalent of "DELETE FROM <tbl>" is executed in a single transaction
762
 * before dropping the table from the database. If any FK violations occur,
763
 * rollback transaction and halt VDBE. Triggers are disabled while running this
764
 * DELETE, but foreign key actions are not.
765
 */
766
void
767
sqlite3FkDropTable(Parse * pParse, SrcList * pName, Table * pTab)
3,130✔
768
{
769
        sqlite3 *db = pParse->db;
3,130✔
770
        struct session *user_session = current_session();
3,130✔
771

772
        if ((user_session->sql_flags & SQLITE_ForeignKeys) &&
6,252✔
773
            !space_is_view(pTab)) {
3,122✔
774
                int iSkip = 0;
2,965✔
775
                Vdbe *v = sqlite3GetVdbe(pParse);
2,965✔
776

777
                assert(v);        /* VDBE has already been allocated */
2,965✔
778
                if (sqlite3FkReferences(pTab) == 0) {
2,965✔
779
                        /* Search for a deferred foreign key constraint for which this table
780
                         * is the child table. If one cannot be found, return without
781
                         * generating any VDBE code. If one can be found, then jump over
782
                         * the entire DELETE if there are no outstanding deferred constraints
783
                         * when this statement is run.
784
                         */
785
                        FKey *p;
786
                        for (p = pTab->pFKey; p; p = p->pNextFrom) {
2,992✔
787
                                if (p->isDeferred
51✔
788
                                    || (user_session->
84✔
789
                                        sql_flags & SQLITE_DeferFKs))
42✔
790
                                        break;
791
                        }
792
                        if (!p)
2,950✔
793
                                return;
2,941✔
794
                        iSkip = sqlite3VdbeMakeLabel(v);
9✔
795
                        sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
9✔
796
                        VdbeCoverage(v);
797
                }
798

799
                pParse->disableTriggers = 1;
24✔
800
                /* Staring new transaction before DELETE FROM <tbl> */
801
                sqlite3VdbeAddOp0(v, OP_TTransaction);
24✔
802
                sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
24✔
803
                pParse->disableTriggers = 0;
24✔
804

805
                /* If the DELETE has generated immediate foreign key constraint
806
                 * violations, rollback, halt the VDBE and return
807
                 * an error at this point, before any modifications of
808
                 * the _space and _index spaces. This is because these spaces
809
                 * don't support multistatement transactions. Otherwise, just
810
                 * commit changes.
811
                 */
812
                sqlite3VdbeAddOp0(v, OP_FkCheckCommit);
24✔
813

814
                if (iSkip) {
24✔
815
                        sqlite3VdbeResolveLabel(v, iSkip);
9✔
816
                }
817
        }
818
}
819

820
/*
821
 * The second argument points to an FKey object representing a foreign key
822
 * for which pTab is the child table. An UPDATE statement against pTab
823
 * is currently being processed. For each column of the table that is
824
 * actually updated, the corresponding element in the aChange[] array
825
 * is zero or greater (if a column is unmodified the corresponding element
826
 * is set to -1).
827
 *
828
 * This function returns true if any of the columns that are part of the
829
 * child key for FK constraint *p are modified.
830
 */
831
static int
832
fkChildIsModified(FKey * p,        /* Foreign key for which pTab is the child */
100✔
833
                  int *aChange        /* Array indicating modified columns */
834
    )
835
{
836
        int i;
837
        for (i = 0; i < p->nCol; i++) {
107✔
838
                int iChildKey = p->aCol[i].iFrom;
104✔
839
                if (aChange[iChildKey] >= 0)
104✔
840
                        return 1;
97✔
841
        }
842
        return 0;
3✔
843
}
844

845
/*
846
 * The second argument points to an FKey object representing a foreign key
847
 * for which pTab is the parent table. An UPDATE statement against pTab
848
 * is currently being processed. For each column of the table that is
849
 * actually updated, the corresponding element in the aChange[] array
850
 * is zero or greater (if a column is unmodified the corresponding element
851
 * is set to -1).
852
 *
853
 * This function returns true if any of the columns that are part of the
854
 * parent key for FK constraint *p are modified.
855
 */
856
static int
857
fkParentIsModified(Table * pTab, FKey * p, int *aChange)
135✔
858
{
859
        int i;
860
        for (i = 0; i < p->nCol; i++) {
184✔
861
                char *zKey = p->aCol[i].zCol;
164✔
862
                int iKey;
863
                for (iKey = 0; iKey < (int)pTab->def->field_count; iKey++) {
504✔
864
                        if (aChange[iKey] >= 0) {
455✔
865
                                if (zKey) {
170✔
866
                                        if (0 ==
112✔
867
                                            strcmp(pTab->def->fields[iKey].name,
112✔
868
                                                   zKey))
869
                                                return 1;
58✔
870
                                } else if (table_column_is_in_pk(pTab, iKey)) {
58✔
871
                                        return 1;
57✔
872
                                }
873
                        }
874
                }
875
        }
876
        return 0;
20✔
877
}
878

879
/*
880
 * Return true if the parser passed as the first argument is being
881
 * used to code a trigger that is really a "SET NULL" action belonging
882
 * to trigger pFKey.
883
 */
884
static int
885
isSetNullAction(Parse * pParse, FKey * pFKey)
218✔
886
{
887
        Parse *pTop = sqlite3ParseToplevel(pParse);
218✔
888
        if (pTop->pTriggerPrg) {
218✔
889
                Trigger *p = pTop->pTriggerPrg->pTrigger;
25✔
890
                if ((p == pFKey->apTrigger[0]
25✔
891
                     && pFKey->aAction[0] == OE_SetNull)
16✔
892
                    || (p == pFKey->apTrigger[1]
21✔
893
                        && pFKey->aAction[1] == OE_SetNull)
9✔
894
                    ) {
895
                        return 1;
5✔
896
                }
897
        }
898
        return 0;
213✔
899
}
900

901
/*
902
 * This function is called when inserting, deleting or updating a row of
903
 * table pTab to generate VDBE code to perform foreign key constraint
904
 * processing for the operation.
905
 *
906
 * For a DELETE operation, parameter regOld is passed the index of the
907
 * first register in an array of (pTab->nCol+1) registers containing the
908
 * PK of the row being deleted, followed by each of the column values
909
 * of the row being deleted, from left to right. Parameter regNew is passed
910
 * zero in this case.
911
 *
912
 * For an INSERT operation, regOld is passed zero and regNew is passed the
913
 * first register of an array of (pTab->nCol+1) registers containing the new
914
 * row data.
915
 *
916
 * For an UPDATE operation, this function is called twice. Once before
917
 * the original record is deleted from the table using the calling convention
918
 * described for DELETE. Then again after the original record is deleted
919
 * but before the new record is inserted using the INSERT convention.
920
 */
921
void
922
sqlite3FkCheck(Parse * pParse,        /* Parse context */
176,015✔
923
               Table * pTab,        /* Row is being deleted from this table */
924
               int regOld,        /* Previous row data is stored here */
925
               int regNew,        /* New row data is stored here */
926
               int *aChange        /* Array indicating UPDATEd columns (or 0) */
927
    )
928
{
929
        sqlite3 *db = pParse->db;        /* Database handle */
176,015✔
930
        FKey *pFKey;                /* Used to iterate through FKs */
931
        int isIgnoreErrors = pParse->disableTriggers;
176,015✔
932
        struct session *user_session = current_session();
176,015✔
933

934
        /* Exactly one of regOld and regNew should be non-zero. */
935
        assert((regOld == 0) != (regNew == 0));
176,015✔
936

937
        /* If foreign-keys are disabled, this function is a no-op. */
938
        if ((user_session->sql_flags & SQLITE_ForeignKeys) == 0)
176,015✔
939
                return;
19✔
940

941
        /* Loop through all the foreign key constraints for which pTab is the
942
         * child table (the table that the foreign key definition is part of).
943
         */
944
        for (pFKey = pTab->pFKey; pFKey; pFKey = pFKey->pNextFrom) {
176,311✔
945
                Table *pTo;        /* Parent table of foreign key pFKey */
946
                Index *pIdx = 0;        /* Index on key columns in pTo */
324✔
947
                int *aiFree = 0;
324✔
948
                int *aiCol;
949
                int iCol;
950
                int i;
951
                int bIgnore = 0;
324✔
952

953
                if (aChange
324✔
954
                    && sqlite3_stricmp(pTab->zName, pFKey->zTo) != 0
86✔
955
                    && fkChildIsModified(pFKey, aChange) == 0) {
56✔
956
                        continue;
4✔
957
                }
958

959
                /* Find the parent table of this foreign key. Also find a unique index
960
                 * on the parent key columns in the parent table. If either of these
961
                 * schema items cannot be located, set an error in pParse and return
962
                 * early.
963
                 */
964
                if (pParse->disableTriggers) {
324✔
965
                        pTo = sqlite3HashFind(&db->pSchema->tblHash,
14✔
966
                                              pFKey->zTo);
14✔
967
                } else {
968
                        pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo);
310✔
969
                }
970
                if (!pTo
324✔
971
                    || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx,
318✔
972
                                            &aiFree)) {
973
                        assert(isIgnoreErrors == 0
13✔
974
                               || (regOld != 0 && regNew == 0));
975
                        if (!isIgnoreErrors || db->mallocFailed)
13✔
976
                                return;
9✔
977
                        if (pTo == 0) {
4✔
978
                                /* If isIgnoreErrors is true, then a table is being dropped. In this
979
                                 * case SQLite runs a "DELETE FROM xxx" on the table being dropped
980
                                 * before actually dropping it in order to check FK constraints.
981
                                 * If the parent table of an FK constraint on the current table is
982
                                 * missing, behave as if it is empty. i.e. decrement the relevant
983
                                 * FK counter for each row of the current table with non-NULL keys.
984
                                 */
985
                                Vdbe *v = sqlite3GetVdbe(pParse);
4✔
986
                                int iJump =
4✔
987
                                    sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
4✔
988
                                for (i = 0; i < pFKey->nCol; i++) {
9✔
989
                                        int iReg =
5✔
990
                                            pFKey->aCol[i].iFrom + regOld + 1;
5✔
991
                                        sqlite3VdbeAddOp2(v, OP_IsNull, iReg,
5✔
992
                                                          iJump);
993
                                        VdbeCoverage(v);
994
                                }
995
                                sqlite3VdbeAddOp2(v, OP_FkCounter,
4✔
996
                                                  pFKey->isDeferred, -1);
4✔
997
                        }
998
                        continue;
4✔
999
                }
1000
                assert(pFKey->nCol == 1 || (aiFree && pIdx));
311✔
1001

1002
                if (aiFree) {
311✔
1003
                        aiCol = aiFree;
49✔
1004
                } else {
1005
                        iCol = pFKey->aCol[0].iFrom;
262✔
1006
                        aiCol = &iCol;
262✔
1007
                }
1008
                for (i = 0; i < pFKey->nCol; i++) {
671✔
1009
                        if (aiCol[i] == pTab->iPKey) {
360✔
1010
                                aiCol[i] = -1;
×
1011
                        }
1012
                        assert(pIdx == 0 || pIdx->aiColumn[i] >= 0);
360✔
1013
                }
1014

1015
                pParse->nTab++;
311✔
1016

1017
                if (regOld != 0) {
311✔
1018
                        /* A row is being removed from the child table. Search for the parent.
1019
                         * If the parent does not exist, removing the child row resolves an
1020
                         * outstanding foreign key constraint violation.
1021
                         */
1022
                        fkLookupParent(pParse, pTo, pIdx, pFKey, aiCol,
93✔
1023
                                       regOld, -1, bIgnore);
1024
                }
1025
                if (regNew != 0 && !isSetNullAction(pParse, pFKey)) {
311✔
1026
                        /* A row is being added to the child table. If a parent row cannot
1027
                         * be found, adding the child row has violated the FK constraint.
1028
                         *
1029
                         * If this operation is being performed as part of a trigger program
1030
                         * that is actually a "SET NULL" action belonging to this very
1031
                         * foreign key, then omit this scan altogether. As all child key
1032
                         * values are guaranteed to be NULL, it is not possible for adding
1033
                         * this row to cause an FK violation.
1034
                         */
1035
                        fkLookupParent(pParse, pTo, pIdx, pFKey, aiCol,
213✔
1036
                                       regNew, +1, bIgnore);
1037
                }
1038

1039
                sqlite3DbFree(db, aiFree);
311✔
1040
        }
1041

1042
        /* Loop through all the foreign key constraints that refer to this table.
1043
         * (the "child" constraints)
1044
         */
1045
        for (pFKey = sqlite3FkReferences(pTab); pFKey; pFKey = pFKey->pNextTo) {
176,285✔
1046
                Index *pIdx = 0;        /* Foreign key index for pFKey */
298✔
1047
                SrcList *pSrc;
1048
                int *aiCol = 0;
298✔
1049

1050
                if (aChange
298✔
1051
                    && fkParentIsModified(pTab, pFKey, aChange) == 0) {
74✔
1052
                        continue;
127✔
1053
                }
1054

1055
                if (!pFKey->isDeferred
286✔
1056
                    && !(user_session->sql_flags & SQLITE_DeferFKs)
265✔
1057
                    && !pParse->pToplevel && !pParse->isMultiWrite) {
265✔
1058
                        assert(regOld == 0 && regNew != 0);
103✔
1059
                        /* Inserting a single row into a parent table cannot cause (or fix)
1060
                         * an immediate foreign key violation. So do nothing in this case.
1061
                         */
1062
                        continue;
103✔
1063
                }
1064

1065
                if (sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol)) {
183✔
1066
                        if (!isIgnoreErrors || db->mallocFailed)
×
1067
                                return;
×
1068
                        continue;
×
1069
                }
1070
                assert(aiCol || pFKey->nCol == 1);
183✔
1071

1072
                /* Create a SrcList structure containing the child table.  We need the
1073
                 * child table as a SrcList for sqlite3WhereBegin()
1074
                 */
1075
                pSrc = sqlite3SrcListAppend(db, 0, 0);
183✔
1076
                if (pSrc) {
183✔
1077
                        struct SrcList_item *pItem = pSrc->a;
183✔
1078
                        pItem->pTab = pFKey->pFrom;
183✔
1079
                        pItem->zName = pFKey->pFrom->zName;
183✔
1080
                        pItem->pTab->nTabRef++;
183✔
1081
                        pItem->iCursor = pParse->nTab++;
183✔
1082

1083
                        if (regNew != 0) {
183✔
1084
                                fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey,
74✔
1085
                                               aiCol, regNew, -1);
1086
                        }
1087
                        if (regOld != 0) {
183✔
1088
                                int eAction = pFKey->aAction[aChange != 0];
109✔
1089
                                fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey,
109✔
1090
                                               aiCol, regOld, 1);
1091
                                /* If this is a deferred FK constraint, or a CASCADE or SET NULL
1092
                                 * action applies, then any foreign key violations caused by
1093
                                 * removing the parent key will be rectified by the action trigger.
1094
                                 * So do not set the "may-abort" flag in this case.
1095
                                 *
1096
                                 * Note 1: If the FK is declared "ON UPDATE CASCADE", then the
1097
                                 * may-abort flag will eventually be set on this statement anyway
1098
                                 * (when this function is called as part of processing the UPDATE
1099
                                 * within the action trigger).
1100
                                 *
1101
                                 * Note 2: At first glance it may seem like SQLite could simply omit
1102
                                 * all OP_FkCounter related scans when either CASCADE or SET NULL
1103
                                 * applies. The trouble starts if the CASCADE or SET NULL action
1104
                                 * trigger causes other triggers or action rules attached to the
1105
                                 * child table to fire. In these cases the fk constraint counters
1106
                                 * might be set incorrectly if any OP_FkCounter related scans are
1107
                                 * omitted.
1108
                                 */
1109
                                if (!pFKey->isDeferred && eAction != OE_Cascade
109✔
1110
                                    && eAction != OE_SetNull) {
63✔
1111
                                        sqlite3MayAbort(pParse);
58✔
1112
                                }
1113
                        }
1114
                        pItem->zName = 0;
183✔
1115
                        sqlite3SrcListDelete(db, pSrc);
183✔
1116
                }
1117
                sqlite3DbFree(db, aiCol);
183✔
1118
        }
1119
}
1120

1121
#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x)))
1122

1123
/*
1124
 * This function is called before generating code to update or delete a
1125
 * row contained in table pTab.
1126
 */
1127
u32
1128
sqlite3FkOldmask(Parse * pParse,        /* Parse context */
291✔
1129
                 Table * pTab        /* Table being modified */
1130
    )
1131
{
1132
        u32 mask = 0;
291✔
1133
        struct session *user_session = current_session();
291✔
1134

1135
        if (user_session->sql_flags & SQLITE_ForeignKeys) {
291✔
1136
                FKey *p;
1137
                int i;
1138
                for (p = pTab->pFKey; p; p = p->pNextFrom) {
386✔
1139
                        for (i = 0; i < p->nCol; i++)
207✔
1140
                                mask |= COLUMN_MASK(p->aCol[i].iFrom);
110✔
1141
                }
1142
                for (p = sqlite3FkReferences(pTab); p; p = p->pNextTo) {
404✔
1143
                        Index *pIdx = 0;
115✔
1144
                        sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
115✔
1145
                        if (pIdx) {
115✔
1146
                                int nIdxCol = index_column_count(pIdx);
115✔
1147
                                for (i = 0; i < nIdxCol; i++) {
249✔
1148
                                        assert(pIdx->aiColumn[i] >= 0);
134✔
1149
                                        mask |= COLUMN_MASK(pIdx->aiColumn[i]);
134✔
1150
                                }
1151
                        }
1152
                }
1153
        }
1154
        return mask;
291✔
1155
}
1156

1157
/*
1158
 * This function is called before generating code to update or delete a
1159
 * row contained in table pTab. If the operation is a DELETE, then
1160
 * parameter aChange is passed a NULL value. For an UPDATE, aChange points
1161
 * to an array of size N, where N is the number of columns in table pTab.
1162
 * If the i'th column is not modified by the UPDATE, then the corresponding
1163
 * entry in the aChange[] array is set to -1. If the column is modified,
1164
 * the value is 0 or greater.
1165
 *
1166
 * If any foreign key processing will be required, this function returns
1167
 * true. If there is no foreign key related processing, this function
1168
 * returns false.
1169
 */
1170
int
1171
sqlite3FkRequired(Table * pTab,        /* Table being modified */
14,437✔
1172
                  int *aChange        /* Non-NULL for UPDATE operations */
1173
    )
1174
{
1175
        struct session *user_session = current_session();
14,437✔
1176
        if (user_session->sql_flags & SQLITE_ForeignKeys) {
14,437✔
1177
                if (!aChange) {
14,402✔
1178
                        /* A DELETE operation. Foreign key processing is required if the
1179
                         * table in question is either the child or parent table for any
1180
                         * foreign key constraint.
1181
                         */
1182
                        return (sqlite3FkReferences(pTab) || pTab->pFKey);
13,830✔
1183
                } else {
1184
                        /* This is an UPDATE. Foreign key processing is only required if the
1185
                         * operation modifies one or more child or parent key columns.
1186
                         */
1187
                        FKey *p;
1188

1189
                        /* Check if any child key columns are being modified. */
1190
                        for (p = pTab->pFKey; p; p = p->pNextFrom) {
575✔
1191
                                if (fkChildIsModified(p, aChange))
44✔
1192
                                        return 1;
41✔
1193
                        }
1194

1195
                        /* Check if any parent key columns are being modified. */
1196
                        for (p = sqlite3FkReferences(pTab); p; p = p->pNextTo) {
533✔
1197
                                if (fkParentIsModified(pTab, p, aChange))
24✔
1198
                                        return 1;
22✔
1199
                        }
1200
                }
1201
        }
1202
        return 0;
544✔
1203
}
1204

1205
/*
1206
 * This function is called when an UPDATE or DELETE operation is being
1207
 * compiled on table pTab, which is the parent table of foreign-key pFKey.
1208
 * If the current operation is an UPDATE, then the pChanges parameter is
1209
 * passed a pointer to the list of columns being modified. If it is a
1210
 * DELETE, pChanges is passed a NULL pointer.
1211
 *
1212
 * It returns a pointer to a Trigger structure containing a trigger
1213
 * equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
1214
 * If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
1215
 * returned (these actions require no special handling by the triggers
1216
 * sub-system, code for them is created by fkScanChildren()).
1217
 *
1218
 * For example, if pFKey is the foreign key and pTab is table "p" in
1219
 * the following schema:
1220
 *
1221
 *   CREATE TABLE p(pk PRIMARY KEY);
1222
 *   CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE);
1223
 *
1224
 * then the returned trigger structure is equivalent to:
1225
 *
1226
 *   CREATE TRIGGER ... DELETE ON p BEGIN
1227
 *     DELETE FROM c WHERE ck = old.pk;
1228
 *   END;
1229
 *
1230
 * The returned pointer is cached as part of the foreign key object. It
1231
 * is eventually freed along with the rest of the foreign key object by
1232
 * sqlite3FkDelete().
1233
 */
1234
static Trigger *
1235
fkActionTrigger(Parse * pParse,        /* Parse context */
109✔
1236
                Table * pTab,        /* Table being updated or deleted from */
1237
                FKey * pFKey,        /* Foreign key to get action for */
1238
                ExprList * pChanges        /* Change-list for UPDATE, NULL for DELETE */
1239
    )
1240
{
1241
        sqlite3 *db = pParse->db;        /* Database handle */
109✔
1242
        int action;                /* One of OE_None, OE_Cascade etc. */
1243
        Trigger *pTrigger;        /* Trigger definition to return */
1244
        int iAction = (pChanges != 0);        /* 1 for UPDATE, 0 for DELETE */
109✔
1245
        struct session *user_session = current_session();
109✔
1246

1247
        action = pFKey->aAction[iAction];
109✔
1248
        if (action == OE_Restrict
109✔
1249
            && (user_session->sql_flags & SQLITE_DeferFKs)) {
3✔
1250
                return 0;
×
1251
        }
1252
        pTrigger = pFKey->apTrigger[iAction];
109✔
1253

1254
        if (action != ON_CONFLICT_ACTION_NONE && !pTrigger) {
109✔
1255
                char const *zFrom;        /* Name of child table */
1256
                int nFrom;        /* Length in bytes of zFrom */
1257
                Index *pIdx = 0;        /* Parent key index for this FK */
30✔
1258
                int *aiCol = 0;        /* child table cols -> parent key cols */
30✔
1259
                TriggerStep *pStep = 0;        /* First (only) step of trigger program */
30✔
1260
                Expr *pWhere = 0;        /* WHERE clause of trigger step */
30✔
1261
                ExprList *pList = 0;        /* Changes list if ON UPDATE CASCADE */
30✔
1262
                Select *pSelect = 0;        /* If RESTRICT, "SELECT RAISE(...)" */
30✔
1263
                int i;                /* Iterator variable */
1264
                Expr *pWhen = 0;        /* WHEN clause for the trigger */
30✔
1265

1266
                if (sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol))
30✔
1267
                        return 0;
×
1268
                assert(aiCol || pFKey->nCol == 1);
30✔
1269

1270
                for (i = 0; i < pFKey->nCol; i++) {
63✔
1271
                        Token tOld = { "old", 3, false };        /* Literal "old" token */
33✔
1272
                        Token tNew = { "new", 3, false };        /* Literal "new" token */
33✔
1273
                        Token tFromCol;        /* Name of column in child table */
1274
                        Token tToCol;        /* Name of column in parent table */
1275
                        int iFromCol;        /* Idx of column in child table */
1276
                        Expr *pEq;        /* tFromCol = OLD.tToCol */
1277

1278
                        iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
33✔
1279
                        assert(iFromCol >= 0);
33✔
1280
                        assert(pIdx != 0
33✔
1281
                               || (pTab->iPKey >= 0
1282
                                   && pTab->iPKey < (int)pTab->def->field_count));
1283
                        assert(pIdx == 0 || pIdx->aiColumn[i] >= 0);
33✔
1284
                        sqlite3TokenInit(&tToCol,
33✔
1285
                                         pTab->def->fields[pIdx ? pIdx->
66✔
1286
                                                    aiColumn[i] : pTab->iPKey].
33✔
1287
                                         name);
1288
                        sqlite3TokenInit(&tFromCol,
33✔
1289
                                         pFKey->pFrom->def->fields[iFromCol].name);
33✔
1290

1291
                        /* Create the expression "OLD.zToCol = zFromCol". It is important
1292
                         * that the "OLD.zToCol" term is on the LHS of the = operator, so
1293
                         * that the affinity and collation sequence associated with the
1294
                         * parent table are used for the comparison.
1295
                         */
1296
                        pEq = sqlite3PExpr(pParse, TK_EQ,
33✔
1297
                                           sqlite3PExpr(pParse, TK_DOT,
1298
                                                        sqlite3ExprAlloc(db,
1299
                                                                         TK_ID,
1300
                                                                         &tOld,
1301
                                                                         0),
1302
                                                        sqlite3ExprAlloc(db,
1303
                                                                         TK_ID,
1304
                                                                         &tToCol,
1305
                                                                         0)),
1306
                                           sqlite3ExprAlloc(db, TK_ID,
1307
                                                            &tFromCol, 0)
1308
                            );
1309
                        pWhere = sqlite3ExprAnd(db, pWhere, pEq);
33✔
1310

1311
                        /* For ON UPDATE, construct the next term of the WHEN clause.
1312
                         * The final WHEN clause will be like this:
1313
                         *
1314
                         *    WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN)
1315
                         */
1316
                        if (pChanges) {
33✔
1317
                                pEq = sqlite3PExpr(pParse, TK_IS,
10✔
1318
                                                   sqlite3PExpr(pParse, TK_DOT,
1319
                                                                sqlite3ExprAlloc
1320
                                                                (db, TK_ID,
1321
                                                                 &tOld, 0),
1322
                                                                sqlite3ExprAlloc
1323
                                                                (db, TK_ID,
1324
                                                                 &tToCol, 0)),
1325
                                                   sqlite3PExpr(pParse, TK_DOT,
1326
                                                                sqlite3ExprAlloc
1327
                                                                (db, TK_ID,
1328
                                                                 &tNew, 0),
1329
                                                                sqlite3ExprAlloc
1330
                                                                (db, TK_ID,
1331
                                                                 &tToCol, 0))
1332
                                    );
1333
                                pWhen = sqlite3ExprAnd(db, pWhen, pEq);
10✔
1334
                        }
1335

1336
                        if (action != OE_Restrict
33✔
1337
                            && (action != OE_Cascade || pChanges)) {
31✔
1338
                                Expr *pNew;
1339
                                if (action == OE_Cascade) {
17✔
1340
                                        pNew = sqlite3PExpr(pParse, TK_DOT,
6✔
1341
                                                            sqlite3ExprAlloc(db,
1342
                                                                             TK_ID,
1343
                                                                             &tNew,
1344
                                                                             0),
1345
                                                            sqlite3ExprAlloc(db,
1346
                                                                             TK_ID,
1347
                                                                             &tToCol,
1348
                                                                             0));
1349
                                } else if (action == OE_SetDflt) {
11✔
1350
                                        uint32_t space_id =
5✔
1351
                                                SQLITE_PAGENO_TO_SPACEID(
5✔
1352
                                                        pFKey->pFrom->tnum);
1353
                                        Expr *pDflt =
5✔
1354
                                                space_column_default_expr(
5✔
1355
                                                        space_id, (uint32_t)iFromCol);
1356
                                        if (pDflt) {
5✔
1357
                                                pNew =
5✔
1358
                                                    sqlite3ExprDup(db, pDflt,
1359
                                                                   0);
1360
                                        } else {
1361
                                                pNew =
×
1362
                                                    sqlite3ExprAlloc(db,
1363
                                                                     TK_NULL, 0,
1364
                                                                     0);
1365
                                        }
1366
                                } else {
1367
                                        pNew =
6✔
1368
                                            sqlite3ExprAlloc(db, TK_NULL, 0, 0);
1369
                                }
1370
                                pList =
17✔
1371
                                    sqlite3ExprListAppend(pParse, pList, pNew);
1372
                                sqlite3ExprListSetName(pParse, pList, &tFromCol,
17✔
1373
                                                       0);
1374
                        }
1375
                }
1376
                sqlite3DbFree(db, aiCol);
30✔
1377

1378
                zFrom = pFKey->pFrom->zName;
30✔
1379
                nFrom = sqlite3Strlen30(zFrom);
30✔
1380

1381
                if (action == OE_Restrict) {
30✔
1382
                        Token tFrom;
1383
                        Expr *pRaise;
1384

1385
                        tFrom.z = zFrom;
2✔
1386
                        tFrom.n = nFrom;
2✔
1387
                        pRaise =
2✔
1388
                            sqlite3Expr(db, TK_RAISE,
1389
                                        "FOREIGN KEY constraint failed");
1390
                        if (pRaise) {
2✔
1391
                                pRaise->affinity = ON_CONFLICT_ACTION_ABORT;
2✔
1392
                        }
1393
                        pSelect = sqlite3SelectNew(pParse,
2✔
1394
                                                   sqlite3ExprListAppend(pParse,
1395
                                                                         0,
1396
                                                                         pRaise),
1397
                                                   sqlite3SrcListAppend(db, 0,
1398
                                                                        &tFrom),
1399
                                                   pWhere, 0, 0, 0, 0, 0, 0);
1400
                        pWhere = 0;
2✔
1401
                }
1402

1403
                /* Disable lookaside memory allocation */
1404
                db->lookaside.bDisable++;
30✔
1405

1406
                pTrigger = (Trigger *) sqlite3DbMallocZero(db, sizeof(Trigger) +        /* struct Trigger */
60✔
1407
                                                           sizeof(TriggerStep) +        /* Single step in trigger program */
1408
                                                           nFrom + 1        /* Space for pStep->zTarget */
30✔
1409
                    );
1410
                if (pTrigger) {
30✔
1411
                        pStep = pTrigger->step_list =
30✔
1412
                            (TriggerStep *) & pTrigger[1];
30✔
1413
                        pStep->zTarget = (char *)&pStep[1];
30✔
1414
                        memcpy((char *)pStep->zTarget, zFrom, nFrom);
30✔
1415

1416
                        pStep->pWhere =
30✔
1417
                            sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
30✔
1418
                        pStep->pExprList =
30✔
1419
                            sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
30✔
1420
                        pStep->pSelect =
30✔
1421
                            sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
30✔
1422
                        if (pWhen) {
30✔
1423
                                pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
8✔
1424
                                pTrigger->pWhen =
8✔
1425
                                    sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
8✔
1426
                        }
1427
                }
1428

1429
                /* Re-enable the lookaside buffer, if it was disabled earlier. */
1430
                db->lookaside.bDisable--;
30✔
1431

1432
                sql_expr_free(db, pWhere, false);
30✔
1433
                sql_expr_free(db, pWhen, false);
30✔
1434
                sqlite3ExprListDelete(db, pList);
30✔
1435
                sqlite3SelectDelete(db, pSelect);
30✔
1436
                if (db->mallocFailed == 1) {
30✔
1437
                        fkTriggerDelete(db, pTrigger);
×
1438
                        return 0;
×
1439
                }
1440
                assert(pStep != 0);
30✔
1441

1442
                switch (action) {
30✔
1443
                case OE_Restrict:
1444
                        pStep->op = TK_SELECT;
2✔
1445
                        break;
2✔
1446
                case OE_Cascade:
1447
                        if (!pChanges) {
19✔
1448
                                pStep->op = TK_DELETE;
14✔
1449
                                break;
14✔
1450
                        }
1451
                        FALLTHROUGH;
1452
                default:
1453
                        pStep->op = TK_UPDATE;
14✔
1454
                }
1455
                pStep->pTrig = pTrigger;
30✔
1456
                pTrigger->pSchema = pTab->pSchema;
30✔
1457
                pTrigger->pTabSchema = pTab->pSchema;
30✔
1458
                pFKey->apTrigger[iAction] = pTrigger;
30✔
1459
                pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE);
30✔
1460
        }
1461

1462
        return pTrigger;
109✔
1463
}
1464

1465
/*
1466
 * This function is called when deleting or updating a row to implement
1467
 * any required CASCADE, SET NULL or SET DEFAULT actions.
1468
 */
1469
void
1470
sqlite3FkActions(Parse * pParse,        /* Parse context */
6,978✔
1471
                 Table * pTab,        /* Table being updated or deleted from */
1472
                 ExprList * pChanges,        /* Change-list for UPDATE, NULL for DELETE */
1473
                 int regOld,        /* Address of array containing old row */
1474
                 int *aChange        /* Array indicating UPDATEd columns (or 0) */
1475
    )
1476
{
1477
        struct session *user_session = current_session();
6,978✔
1478
        /* If foreign-key support is enabled, iterate through all FKs that
1479
         * refer to table pTab. If there is an action associated with the FK
1480
         * for this operation (either update or delete), invoke the associated
1481
         * trigger sub-program.
1482
         */
1483
        if (user_session->sql_flags & SQLITE_ForeignKeys) {
6,978✔
1484
                FKey *pFKey;        /* Iterator variable */
1485
                for (pFKey = sqlite3FkReferences(pTab); pFKey;
14,035✔
1486
                     pFKey = pFKey->pNextTo) {
115✔
1487
                        if (aChange == 0
115✔
1488
                            || fkParentIsModified(pTab, pFKey, aChange)) {
37✔
1489
                                Trigger *pAct =
109✔
1490
                                    fkActionTrigger(pParse, pTab, pFKey,
1491
                                                    pChanges);
1492
                                if (pAct) {
109✔
1493
                                        sqlite3CodeRowTriggerDirect(pParse,
54✔
1494
                                                                    pAct, pTab,
1495
                                                                    regOld,
1496
                                                                    ON_CONFLICT_ACTION_ABORT,
1497
                                                                    0);
1498
                                }
1499
                        }
1500
                }
1501
        }
1502
}
6,978✔
1503

1504
#endif                                /* ifndef SQLITE_OMIT_TRIGGER */
1505

1506
/*
1507
 * Free all memory associated with foreign key definitions attached to
1508
 * table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
1509
 * hash table.
1510
 */
1511
void
1512
sqlite3FkDelete(sqlite3 * db, Table * pTab)
9,085✔
1513
{
1514
        FKey *pFKey;                /* Iterator variable */
1515
        FKey *pNext;                /* Copy of pFKey->pNextFrom */
1516

1517
        for (pFKey = pTab->pFKey; pFKey; pFKey = pNext) {
9,248✔
1518
                /* Remove the FK from the fkeyHash hash table. */
1519
                if (!db || db->pnBytesFreed == 0) {
163✔
1520
                        if (pFKey->pPrevTo) {
163✔
1521
                                pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
5✔
1522
                        } else {
1523
                                void *p = (void *)pFKey->pNextTo;
158✔
1524
                                const char *z =
175✔
1525
                                    (p ? pFKey->pNextTo->zTo : pFKey->zTo);
17✔
1526
                                sqlite3HashInsert(&pTab->pSchema->fkeyHash, z,
158✔
1527
                                                  p);
1528
                        }
1529
                        if (pFKey->pNextTo) {
163✔
1530
                                pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
20✔
1531
                        }
1532
                }
1533

1534
                /* EV: R-30323-21917 Each foreign key constraint in SQLite is
1535
                 * classified as either immediate or deferred.
1536
                 */
1537
                assert(pFKey->isDeferred == 0 || pFKey->isDeferred == 1);
163✔
1538

1539
                /* Delete any triggers created to implement actions for this FK. */
1540
#ifndef SQLITE_OMIT_TRIGGER
1541
                fkTriggerDelete(db, pFKey->apTrigger[0]);
163✔
1542
                fkTriggerDelete(db, pFKey->apTrigger[1]);
163✔
1543
#endif
1544

1545
                pNext = pFKey->pNextFrom;
163✔
1546
                sqlite3DbFree(db, pFKey);
163✔
1547
        }
1548
}
9,085✔
1549
#endif                                /* ifndef SQLITE_OMIT_FOREIGN_KEY */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc