SQLite

Check-in [521f1d36]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Correction to check-in [bec5b6d4d083556d] so that it detects *all* triggers that might perturb the insertion cursor. Ticket [50c09fc2cf0d91ce].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 521f1d36282549488a47a434484a24924ee970d29f05a8ae499b7d536bcd692b
User & Date: drh 2019-10-24 19:35:26
Context
2019-10-24
20:35
In fts5, fix a case of overreading a buffer by 1 byte when counting characters in malformed utf-8. Fix for [dd1f67bf]. (check-in: 8d964e1c user: dan tags: trunk)
19:35
Correction to check-in [bec5b6d4d083556d] so that it detects *all* triggers that might perturb the insertion cursor. Ticket [50c09fc2cf0d91ce]. (check-in: 521f1d36 user: drh tags: trunk)
2019-10-23
21:00
Add an experimental set of UUID processing functions as the uuid.c extension in ext/misc/uuid.c. (check-in: 1a6e0093 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/insert.c.

1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
      ** constraints or (b) there are no triggers and this table is not a
      ** parent table in a foreign key constraint. It is safe to set the
      ** flag in the second case as if any REPLACE constraint is hit, an
      ** OP_Delete or OP_IdxDelete instruction will be executed on each 
      ** cursor that is disturbed. And these instructions both clear the
      ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
      ** functionality.  */
      bUseSeek = (isReplace==0 || (pTrigger==0 &&
          ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
      ));
      sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
          regIns, aRegIdx, 0, appendFlag, bUseSeek
      );
    }
  }

  /* Update the count of rows that are inserted







|
<
<







1054
1055
1056
1057
1058
1059
1060
1061


1062
1063
1064
1065
1066
1067
1068
      ** constraints or (b) there are no triggers and this table is not a
      ** parent table in a foreign key constraint. It is safe to set the
      ** flag in the second case as if any REPLACE constraint is hit, an
      ** OP_Delete or OP_IdxDelete instruction will be executed on each 
      ** cursor that is disturbed. And these instructions both clear the
      ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
      ** functionality.  */
      bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v));


      sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
          regIns, aRegIdx, 0, appendFlag, bUseSeek
      );
    }
  }

  /* Update the count of rows that are inserted

Changes to src/vdbe.h.

274
275
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);

typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);

#ifndef SQLITE_OMIT_TRIGGER
void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif


int sqlite3NotPureFunc(sqlite3_context*);

/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
**
** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op







<

<
>







274
275
276
277
278
279
280

281

282
283
284
285
286
287
288
289
int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);

typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);


void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);

int sqlite3VdbeHasSubProgram(Vdbe*);

int sqlite3NotPureFunc(sqlite3_context*);

/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
**
** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op

Changes to src/vdbeaux.c.

1093
1094
1095
1096
1097
1098
1099







1100
1101
1102
1103
1104
1105
1106
** list at Vdbe.pSubProgram. This list is used to delete all sub-program
** objects when the VM is no longer required.
*/
void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
  p->pNext = pVdbe->pProgram;
  pVdbe->pProgram = p;
}








/*
** Change the opcode at addr into OP_Noop
*/
int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
  VdbeOp *pOp;
  if( p->db->mallocFailed ) return 0;







>
>
>
>
>
>
>







1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
** list at Vdbe.pSubProgram. This list is used to delete all sub-program
** objects when the VM is no longer required.
*/
void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
  p->pNext = pVdbe->pProgram;
  pVdbe->pProgram = p;
}

/*
** Return true if the given Vdbe has any SubPrograms.
*/
int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){
  return pVdbe->pProgram!=0;
}

/*
** Change the opcode at addr into OP_Noop
*/
int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
  VdbeOp *pOp;
  if( p->db->mallocFailed ) return 0;

Changes to test/trigger1.test.

777
778
779
780
781
782
783
















784
785
  ATTACH ':memory:' AS aux;
  CREATE TABLE aux.t20_2(y);
  CREATE TABLE aux.t20_3(z);
  CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END;
  DETACH aux;
  DROP TRIGGER r20_3;
} {}

















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
  ATTACH ':memory:' AS aux;
  CREATE TABLE aux.t20_2(y);
  CREATE TABLE aux.t20_3(z);
  CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END;
  DETACH aux;
  DROP TRIGGER r20_3;
} {}

# 2019-10-24 ticket 50c09fc2cf0d91ce
#
db close
sqlite3 db :memory:
do_execsql_test trigger1-21.1 {
  PRAGMA recursive_triggers = true;
  CREATE TABLE t0(a, b, c UNIQUE);
  CREATE UNIQUE INDEX i0 ON t0(b) WHERE a;
  CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN
    DELETE FROM t0;
  END;
  INSERT INTO t0(a,b,c) VALUES(0,0,9),(1,1,1);
  REPLACE INTO t0(a,b,c) VALUES(2,0,9);
  SELECT * FROM t0;
} {2 0 9}

finish_test