/ Hex Artifact Content
Login

Artifact e1552bd5a26418c32b8516cb5602bf5473651c68:


0000: 2f 2a 0a 2a 2a 20 32 30 30 31 20 53 65 70 74 65  /*.** 2001 Septe
0010: 6d 62 65 72 20 31 35 0a 2a 2a 0a 2a 2a 20 54 68  mber 15.**.** Th
0020: 65 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69  e author disclai
0030: 6d 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20  ms copyright to 
0040: 74 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65  this source code
0050: 2e 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a  .  In place of.*
0060: 2a 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65  * a legal notice
0070: 2c 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73  , here is a bles
0080: 73 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d  sing:.**.**    M
0090: 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61  ay you do good a
00a0: 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20  nd not evil..** 
00b0: 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20     May you find 
00c0: 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20  forgiveness for 
00d0: 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72  yourself and for
00e0: 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20  give others..** 
00f0: 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65     May you share
0100: 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74   freely, never t
0110: 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20  aking more than 
0120: 79 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a  you give..**.***
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66  ******.** This f
0180: 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 43 20 63  ile contains C c
0190: 6f 64 65 20 72 6f 75 74 69 6e 65 73 20 74 68 61  ode routines tha
01a0: 74 20 61 72 65 20 63 61 6c 6c 65 64 20 62 79 20  t are called by 
01b0: 74 68 65 20 70 61 72 73 65 72 0a 2a 2a 20 74 6f  the parser.** to
01c0: 20 68 61 6e 64 6c 65 20 44 45 4c 45 54 45 20 46   handle DELETE F
01d0: 52 4f 4d 20 73 74 61 74 65 6d 65 6e 74 73 2e 0a  ROM statements..
01e0: 2a 2a 0a 2a 2a 20 24 49 64 3a 20 64 65 6c 65 74  **.** $Id: delet
01f0: 65 2e 63 2c 76 20 31 2e 34 38 20 32 30 30 33 2f  e.c,v 1.48 2003/
0200: 30 33 2f 32 37 20 31 32 3a 35 31 3a 32 34 20 64  03/27 12:51:24 d
0210: 72 68 20 45 78 70 20 24 0a 2a 2f 0a 23 69 6e 63  rh Exp $.*/.#inc
0220: 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74 2e  lude "sqliteInt.
0230: 68 22 0a 0a 0a 2f 2a 0a 2a 2a 20 47 69 76 65 6e  h".../*.** Given
0240: 20 61 20 74 61 62 6c 65 20 6e 61 6d 65 2c 20 66   a table name, f
0250: 69 6e 64 20 74 68 65 20 63 6f 72 72 65 73 70 6f  ind the correspo
0260: 6e 64 69 6e 67 20 74 61 62 6c 65 20 61 6e 64 20  nding table and 
0270: 6d 61 6b 65 20 73 75 72 65 20 74 68 65 0a 2a 2a  make sure the.**
0280: 20 74 61 62 6c 65 20 69 73 20 77 72 69 74 65 61   table is writea
0290: 62 6c 65 2e 20 20 47 65 6e 65 72 61 74 65 20 61  ble.  Generate a
02a0: 6e 20 65 72 72 6f 72 20 61 6e 64 20 72 65 74 75  n error and retu
02b0: 72 6e 20 4e 55 4c 4c 20 69 66 20 6e 6f 74 2e 20  rn NULL if not. 
02c0: 20 49 66 0a 2a 2a 20 65 76 65 72 79 74 68 69 6e   If.** everythin
02d0: 67 20 63 68 65 63 6b 73 20 6f 75 74 2c 20 72 65  g checks out, re
02e0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
02f0: 6f 20 74 68 65 20 54 61 62 6c 65 20 73 74 72 75  o the Table stru
0300: 63 74 75 72 65 2e 0a 2a 2f 0a 54 61 62 6c 65 20  cture..*/.Table 
0310: 2a 73 71 6c 69 74 65 54 61 62 6c 65 4e 61 6d 65  *sqliteTableName
0320: 54 6f 54 61 62 6c 65 28 50 61 72 73 65 20 2a 70  ToTable(Parse *p
0330: 50 61 72 73 65 2c 20 63 6f 6e 73 74 20 63 68 61  Parse, const cha
0340: 72 20 2a 7a 54 61 62 2c 20 63 6f 6e 73 74 20 63  r *zTab, const c
0350: 68 61 72 20 2a 7a 44 62 29 7b 0a 20 20 54 61 62  har *zDb){.  Tab
0360: 6c 65 20 2a 70 54 61 62 3b 0a 20 20 70 54 61 62  le *pTab;.  pTab
0370: 20 3d 20 73 71 6c 69 74 65 46 69 6e 64 54 61 62   = sqliteFindTab
0380: 6c 65 28 70 50 61 72 73 65 2d 3e 64 62 2c 20 7a  le(pParse->db, z
0390: 54 61 62 2c 20 7a 44 62 29 3b 0a 20 20 69 66 28  Tab, zDb);.  if(
03a0: 20 70 54 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20   pTab==0 ){.    
03b0: 69 66 28 20 7a 44 62 3d 3d 30 20 7c 7c 20 7a 44  if( zDb==0 || zD
03c0: 62 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20  b[0]==0 ){.     
03d0: 20 73 71 6c 69 74 65 53 65 74 53 74 72 69 6e 67   sqliteSetString
03e0: 28 26 70 50 61 72 73 65 2d 3e 7a 45 72 72 4d 73  (&pParse->zErrMs
03f0: 67 2c 20 22 6e 6f 20 73 75 63 68 20 74 61 62 6c  g, "no such tabl
0400: 65 3a 20 22 2c 20 7a 54 61 62 2c 20 30 29 3b 0a  e: ", zTab, 0);.
0410: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
0420: 20 73 71 6c 69 74 65 53 65 74 53 74 72 69 6e 67   sqliteSetString
0430: 28 26 70 50 61 72 73 65 2d 3e 7a 45 72 72 4d 73  (&pParse->zErrMs
0440: 67 2c 20 22 6e 6f 20 73 75 63 68 20 74 61 62 6c  g, "no such tabl
0450: 65 3a 20 22 2c 20 7a 44 62 2c 20 22 2e 22 2c 20  e: ", zDb, ".", 
0460: 7a 54 61 62 2c 20 30 29 3b 0a 20 20 20 20 7d 0a  zTab, 0);.    }.
0470: 20 20 20 20 70 50 61 72 73 65 2d 3e 6e 45 72 72      pParse->nErr
0480: 2b 2b 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30  ++;.    return 0
0490: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 54 61 62  ;.  }.  if( pTab
04a0: 2d 3e 72 65 61 64 4f 6e 6c 79 20 7c 7c 20 70 54  ->readOnly || pT
04b0: 61 62 2d 3e 70 53 65 6c 65 63 74 20 29 7b 0a 20  ab->pSelect ){. 
04c0: 20 20 20 73 71 6c 69 74 65 53 65 74 53 74 72 69     sqliteSetStri
04d0: 6e 67 28 26 70 50 61 72 73 65 2d 3e 7a 45 72 72  ng(&pParse->zErr
04e0: 4d 73 67 2c 20 0a 20 20 20 20 20 20 70 54 61 62  Msg, .      pTab
04f0: 2d 3e 70 53 65 6c 65 63 74 20 3f 20 22 76 69 65  ->pSelect ? "vie
0500: 77 20 22 20 3a 20 22 74 61 62 6c 65 20 22 2c 0a  w " : "table ",.
0510: 20 20 20 20 20 20 7a 54 61 62 2c 0a 20 20 20 20        zTab,.    
0520: 20 20 22 20 6d 61 79 20 6e 6f 74 20 62 65 20 6d    " may not be m
0530: 6f 64 69 66 69 65 64 22 2c 20 30 29 3b 0a 20 20  odified", 0);.  
0540: 20 20 70 50 61 72 73 65 2d 3e 6e 45 72 72 2b 2b    pParse->nErr++
0550: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 20  ;.    return 0; 
0560: 20 20 20 20 20 0a 20 20 7d 0a 20 20 72 65 74 75       .  }.  retu
0570: 72 6e 20 70 54 61 62 3b 0a 7d 0a 0a 2f 2a 0a 2a  rn pTab;.}../*.*
0580: 2a 20 50 72 6f 63 65 73 73 20 61 20 44 45 4c 45  * Process a DELE
0590: 54 45 20 46 52 4f 4d 20 73 74 61 74 65 6d 65 6e  TE FROM statemen
05a0: 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  t..*/.void sqlit
05b0: 65 44 65 6c 65 74 65 46 72 6f 6d 28 0a 20 20 50  eDeleteFrom(.  P
05c0: 61 72 73 65 20 2a 70 50 61 72 73 65 2c 20 20 20  arse *pParse,   
05d0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 70 61 72        /* The par
05e0: 73 65 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  ser context */. 
05f0: 20 53 72 63 4c 69 73 74 20 2a 70 54 61 62 4c 69   SrcList *pTabLi
0600: 73 74 2c 20 20 20 20 20 2f 2a 20 54 68 65 20 74  st,     /* The t
0610: 61 62 6c 65 20 66 72 6f 6d 20 77 68 69 63 68 20  able from which 
0620: 77 65 20 73 68 6f 75 6c 64 20 64 65 6c 65 74 65  we should delete
0630: 20 74 68 69 6e 67 73 20 2a 2f 0a 20 20 45 78 70   things */.  Exp
0640: 72 20 2a 70 57 68 65 72 65 20 20 20 20 20 20 20  r *pWhere       
0650: 20 20 20 20 2f 2a 20 54 68 65 20 57 48 45 52 45      /* The WHERE
0660: 20 63 6c 61 75 73 65 2e 20 20 4d 61 79 20 62 65   clause.  May be
0670: 20 6e 75 6c 6c 20 2a 2f 0a 29 7b 0a 20 20 56 64   null */.){.  Vd
0680: 62 65 20 2a 76 3b 20 20 20 20 20 20 20 20 20 20  be *v;          
0690: 20 20 20 20 20 2f 2a 20 54 68 65 20 76 69 72 74       /* The virt
06a0: 75 61 6c 20 64 61 74 61 62 61 73 65 20 65 6e 67  ual database eng
06b0: 69 6e 65 20 2a 2f 0a 20 20 54 61 62 6c 65 20 2a  ine */.  Table *
06c0: 70 54 61 62 3b 20 20 20 20 20 20 20 20 20 20 20  pTab;           
06d0: 2f 2a 20 54 68 65 20 74 61 62 6c 65 20 66 72 6f  /* The table fro
06e0: 6d 20 77 68 69 63 68 20 72 65 63 6f 72 64 73 20  m which records 
06f0: 77 69 6c 6c 20 62 65 20 64 65 6c 65 74 65 64 20  will be deleted 
0700: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 61 62 3b  */.  char *zTab;
0710: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
0720: 61 6d 65 20 6f 66 20 74 68 65 20 74 61 62 6c 65  ame of the table
0730: 20 66 72 6f 6d 20 77 68 69 63 68 20 77 65 20 61   from which we a
0740: 72 65 20 64 65 6c 65 74 69 6e 67 20 2a 2f 0a 20  re deleting */. 
0750: 20 63 68 61 72 20 2a 7a 44 62 3b 20 20 20 20 20   char *zDb;     
0760: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
0770: 6f 66 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  of database cont
0780: 61 69 6e 69 6e 67 20 74 61 62 6c 65 20 7a 54 61  aining table zTa
0790: 62 20 2a 2f 0a 20 20 69 6e 74 20 65 6e 64 2c 20  b */.  int end, 
07a0: 61 64 64 72 3b 20 20 20 20 20 20 20 20 20 2f 2a  addr;         /*
07b0: 20 41 20 63 6f 75 70 6c 65 20 61 64 64 72 65 73   A couple addres
07c0: 73 65 73 20 6f 66 20 67 65 6e 65 72 61 74 65 64  ses of generated
07d0: 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69   code */.  int i
07e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
07f0: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
0800: 72 20 2a 2f 0a 20 20 57 68 65 72 65 49 6e 66 6f  r */.  WhereInfo
0810: 20 2a 70 57 49 6e 66 6f 3b 20 20 20 20 20 2f 2a   *pWInfo;     /*
0820: 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   Information abo
0830: 75 74 20 74 68 65 20 57 48 45 52 45 20 63 6c 61  ut the WHERE cla
0840: 75 73 65 20 2a 2f 0a 20 20 49 6e 64 65 78 20 2a  use */.  Index *
0850: 70 49 64 78 3b 20 20 20 20 20 20 20 20 20 20 20  pIdx;           
0860: 2f 2a 20 46 6f 72 20 6c 6f 6f 70 69 6e 67 20 6f  /* For looping o
0870: 76 65 72 20 69 6e 64 69 63 65 73 20 6f 66 20 74  ver indices of t
0880: 68 65 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  he table */.  in
0890: 74 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20  t base;         
08a0: 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66       /* Index of
08b0: 20 74 68 65 20 66 69 72 73 74 20 61 76 61 69 6c   the first avail
08c0: 61 62 6c 65 20 74 61 62 6c 65 20 63 75 72 73 6f  able table curso
08d0: 72 20 2a 2f 0a 20 20 73 71 6c 69 74 65 20 2a 64  r */.  sqlite *d
08e0: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b;            /*
08f0: 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20 73   Main database s
0900: 74 72 75 63 74 75 72 65 20 2a 2f 0a 0a 20 20 69  tructure */..  i
0910: 6e 74 20 72 6f 77 5f 74 72 69 67 67 65 72 73 5f  nt row_triggers_
0920: 65 78 69 73 74 20 3d 20 30 3b 0a 20 20 69 6e 74  exist = 0;.  int
0930: 20 6f 6c 64 49 64 78 20 3d 20 2d 31 3b 0a 0a 20   oldIdx = -1;.. 
0940: 20 69 66 28 20 70 50 61 72 73 65 2d 3e 6e 45 72   if( pParse->nEr
0950: 72 20 7c 7c 20 73 71 6c 69 74 65 5f 6d 61 6c 6c  r || sqlite_mall
0960: 6f 63 5f 66 61 69 6c 65 64 20 29 7b 0a 20 20 20  oc_failed ){.   
0970: 20 70 54 61 62 4c 69 73 74 20 3d 20 30 3b 0a 20   pTabList = 0;. 
0980: 20 20 20 67 6f 74 6f 20 64 65 6c 65 74 65 5f 66     goto delete_f
0990: 72 6f 6d 5f 63 6c 65 61 6e 75 70 3b 0a 20 20 7d  rom_cleanup;.  }
09a0: 0a 20 20 64 62 20 3d 20 70 50 61 72 73 65 2d 3e  .  db = pParse->
09b0: 64 62 3b 0a 20 20 61 73 73 65 72 74 28 20 70 54  db;.  assert( pT
09c0: 61 62 4c 69 73 74 2d 3e 6e 53 72 63 3d 3d 31 20  abList->nSrc==1 
09d0: 29 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20 66  );..  /* Check f
09e0: 6f 72 20 74 68 65 20 73 70 65 63 69 61 6c 20 63  or the special c
09f0: 61 73 65 20 6f 66 20 61 20 56 49 45 57 20 77 69  ase of a VIEW wi
0a00: 74 68 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 4f  th one or more O
0a10: 4e 20 44 45 4c 45 54 45 20 74 72 69 67 67 65 72  N DELETE trigger
0a20: 73 20 0a 20 20 2a 2a 20 64 65 66 69 6e 65 64 20  s .  ** defined 
0a30: 0a 20 20 2a 2f 0a 20 20 7a 54 61 62 20 3d 20 70  .  */.  zTab = p
0a40: 54 61 62 4c 69 73 74 2d 3e 61 5b 30 5d 2e 7a 4e  TabList->a[0].zN
0a50: 61 6d 65 3b 0a 20 20 7a 44 62 20 3d 20 70 54 61  ame;.  zDb = pTa
0a60: 62 4c 69 73 74 2d 3e 61 5b 30 5d 2e 7a 44 61 74  bList->a[0].zDat
0a70: 61 62 61 73 65 3b 0a 20 20 69 66 28 20 7a 54 61  abase;.  if( zTa
0a80: 62 20 21 3d 20 30 20 29 7b 0a 20 20 20 20 70 54  b != 0 ){.    pT
0a90: 61 62 20 3d 20 73 71 6c 69 74 65 46 69 6e 64 54  ab = sqliteFindT
0aa0: 61 62 6c 65 28 70 50 61 72 73 65 2d 3e 64 62 2c  able(pParse->db,
0ab0: 20 7a 54 61 62 2c 20 7a 44 62 29 3b 0a 20 20 20   zTab, zDb);.   
0ac0: 20 69 66 28 20 70 54 61 62 20 29 7b 0a 20 20 20   if( pTab ){.   
0ad0: 20 20 20 72 6f 77 5f 74 72 69 67 67 65 72 73 5f     row_triggers_
0ae0: 65 78 69 73 74 20 3d 20 0a 20 20 20 20 20 20 20  exist = .       
0af0: 20 73 71 6c 69 74 65 54 72 69 67 67 65 72 73 45   sqliteTriggersE
0b00: 78 69 73 74 28 70 50 61 72 73 65 2c 20 70 54 61  xist(pParse, pTa
0b10: 62 2d 3e 70 54 72 69 67 67 65 72 2c 20 0a 20 20  b->pTrigger, .  
0b20: 20 20 20 20 20 20 20 20 20 20 54 4b 5f 44 45 4c            TK_DEL
0b30: 45 54 45 2c 20 54 4b 5f 42 45 46 4f 52 45 2c 20  ETE, TK_BEFORE, 
0b40: 54 4b 5f 52 4f 57 2c 20 30 29 20 7c 7c 0a 20 20  TK_ROW, 0) ||.  
0b50: 20 20 20 20 20 20 73 71 6c 69 74 65 54 72 69 67        sqliteTrig
0b60: 67 65 72 73 45 78 69 73 74 28 70 50 61 72 73 65  gersExist(pParse
0b70: 2c 20 70 54 61 62 2d 3e 70 54 72 69 67 67 65 72  , pTab->pTrigger
0b80: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 54  , .            T
0b90: 4b 5f 44 45 4c 45 54 45 2c 20 54 4b 5f 41 46 54  K_DELETE, TK_AFT
0ba0: 45 52 2c 20 54 4b 5f 52 4f 57 2c 20 30 29 3b 0a  ER, TK_ROW, 0);.
0bb0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 6f      }.    if( ro
0bc0: 77 5f 74 72 69 67 67 65 72 73 5f 65 78 69 73 74  w_triggers_exist
0bd0: 20 26 26 20 20 70 54 61 62 2d 3e 70 53 65 6c 65   &&  pTab->pSele
0be0: 63 74 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 4a  ct ){.      /* J
0bf0: 75 73 74 20 66 69 72 65 20 56 49 45 57 20 74 72  ust fire VIEW tr
0c00: 69 67 67 65 72 73 20 2a 2f 0a 20 20 20 20 20 20  iggers */.      
0c10: 73 71 6c 69 74 65 53 72 63 4c 69 73 74 44 65 6c  sqliteSrcListDel
0c20: 65 74 65 28 70 54 61 62 4c 69 73 74 29 3b 0a 20  ete(pTabList);. 
0c30: 20 20 20 20 20 73 71 6c 69 74 65 56 69 65 77 54       sqliteViewT
0c40: 72 69 67 67 65 72 73 28 70 50 61 72 73 65 2c 20  riggers(pParse, 
0c50: 70 54 61 62 2c 20 70 57 68 65 72 65 2c 20 4f 45  pTab, pWhere, OE
0c60: 5f 52 65 70 6c 61 63 65 2c 20 30 29 3b 0a 20 20  _Replace, 0);.  
0c70: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20      return;.    
0c80: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 63 61  }.  }..  /* Loca
0c90: 74 65 20 74 68 65 20 74 61 62 6c 65 20 77 68 69  te the table whi
0ca0: 63 68 20 77 65 20 77 61 6e 74 20 74 6f 20 64 65  ch we want to de
0cb0: 6c 65 74 65 2e 20 20 54 68 69 73 20 74 61 62 6c  lete.  This tabl
0cc0: 65 20 68 61 73 20 74 6f 20 62 65 0a 20 20 2a 2a  e has to be.  **
0cd0: 20 70 75 74 20 69 6e 20 61 6e 20 53 72 63 4c 69   put in an SrcLi
0ce0: 73 74 20 73 74 72 75 63 74 75 72 65 20 62 65 63  st structure bec
0cf0: 61 75 73 65 20 73 6f 6d 65 20 6f 66 20 74 68 65  ause some of the
0d00: 20 73 75 62 72 6f 75 74 69 6e 65 73 20 77 65 0a   subroutines we.
0d10: 20 20 2a 2a 20 77 69 6c 6c 20 62 65 20 63 61 6c    ** will be cal
0d20: 6c 69 6e 67 20 61 72 65 20 64 65 73 69 67 6e 65  ling are designe
0d30: 64 20 74 6f 20 77 6f 72 6b 20 77 69 74 68 20 6d  d to work with m
0d40: 75 6c 74 69 70 6c 65 20 74 61 62 6c 65 73 20 61  ultiple tables a
0d50: 6e 64 20 65 78 70 65 63 74 0a 20 20 2a 2a 20 61  nd expect.  ** a
0d60: 6e 20 53 72 63 4c 69 73 74 2a 20 70 61 72 61 6d  n SrcList* param
0d70: 65 74 65 72 20 69 6e 73 74 65 61 64 20 6f 66 20  eter instead of 
0d80: 6a 75 73 74 20 61 20 54 61 62 6c 65 2a 20 70 61  just a Table* pa
0d90: 72 61 6d 65 74 65 72 2e 0a 20 20 2a 2f 0a 20 20  rameter..  */.  
0da0: 70 54 61 62 20 3d 20 70 54 61 62 4c 69 73 74 2d  pTab = pTabList-
0db0: 3e 61 5b 30 5d 2e 70 54 61 62 20 3d 20 73 71 6c  >a[0].pTab = sql
0dc0: 69 74 65 54 61 62 6c 65 4e 61 6d 65 54 6f 54 61  iteTableNameToTa
0dd0: 62 6c 65 28 70 50 61 72 73 65 2c 20 7a 54 61 62  ble(pParse, zTab
0de0: 2c 20 7a 44 62 29 3b 0a 20 20 69 66 28 20 70 54  , zDb);.  if( pT
0df0: 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20 67 6f 74  ab==0 ){.    got
0e00: 6f 20 64 65 6c 65 74 65 5f 66 72 6f 6d 5f 63 6c  o delete_from_cl
0e10: 65 61 6e 75 70 3b 0a 20 20 7d 0a 20 20 61 73 73  eanup;.  }.  ass
0e20: 65 72 74 28 20 70 54 61 62 2d 3e 70 53 65 6c 65  ert( pTab->pSele
0e30: 63 74 3d 3d 30 20 29 3b 20 20 2f 2a 20 54 68 69  ct==0 );  /* Thi
0e40: 73 20 74 61 62 6c 65 20 69 73 20 6e 6f 74 20 61  s table is not a
0e50: 20 76 69 65 77 20 2a 2f 0a 20 20 69 66 28 20 73   view */.  if( s
0e60: 71 6c 69 74 65 41 75 74 68 43 68 65 63 6b 28 70  qliteAuthCheck(p
0e70: 50 61 72 73 65 2c 20 53 51 4c 49 54 45 5f 44 45  Parse, SQLITE_DE
0e80: 4c 45 54 45 2c 20 70 54 61 62 2d 3e 7a 4e 61 6d  LETE, pTab->zNam
0e90: 65 2c 20 30 29 20 29 7b 0a 20 20 20 20 67 6f 74  e, 0) ){.    got
0ea0: 6f 20 64 65 6c 65 74 65 5f 66 72 6f 6d 5f 63 6c  o delete_from_cl
0eb0: 65 61 6e 75 70 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  eanup;.  }..  /*
0ec0: 20 41 6c 6c 6f 63 61 74 65 20 61 20 63 75 72 73   Allocate a curs
0ed0: 6f 72 20 75 73 65 64 20 74 6f 20 73 74 6f 72 65  or used to store
0ee0: 20 74 68 65 20 6f 6c 64 2e 2a 20 64 61 74 61 20   the old.* data 
0ef0: 66 6f 72 20 61 20 74 72 69 67 67 65 72 2e 0a 20  for a trigger.. 
0f00: 20 2a 2f 0a 20 20 69 66 28 20 72 6f 77 5f 74 72   */.  if( row_tr
0f10: 69 67 67 65 72 73 5f 65 78 69 73 74 20 29 7b 20  iggers_exist ){ 
0f20: 0a 20 20 20 20 6f 6c 64 49 64 78 20 3d 20 70 50  .    oldIdx = pP
0f30: 61 72 73 65 2d 3e 6e 54 61 62 2b 2b 3b 0a 20 20  arse->nTab++;.  
0f40: 7d 0a 0a 20 20 2f 2a 20 52 65 73 6f 6c 76 65 20  }..  /* Resolve 
0f50: 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  the column names
0f60: 20 69 6e 20 61 6c 6c 20 74 68 65 20 65 78 70 72   in all the expr
0f70: 65 73 73 69 6f 6e 73 2e 0a 20 20 2a 2f 0a 20 20  essions..  */.  
0f80: 62 61 73 65 20 3d 20 70 50 61 72 73 65 2d 3e 6e  base = pParse->n
0f90: 54 61 62 2b 2b 3b 0a 20 20 69 66 28 20 70 57 68  Tab++;.  if( pWh
0fa0: 65 72 65 20 29 7b 0a 20 20 20 20 69 66 28 20 73  ere ){.    if( s
0fb0: 71 6c 69 74 65 45 78 70 72 52 65 73 6f 6c 76 65  qliteExprResolve
0fc0: 49 64 73 28 70 50 61 72 73 65 2c 20 62 61 73 65  Ids(pParse, base
0fd0: 2c 20 70 54 61 62 4c 69 73 74 2c 20 30 2c 20 70  , pTabList, 0, p
0fe0: 57 68 65 72 65 29 20 29 7b 0a 20 20 20 20 20 20  Where) ){.      
0ff0: 67 6f 74 6f 20 64 65 6c 65 74 65 5f 66 72 6f 6d  goto delete_from
1000: 5f 63 6c 65 61 6e 75 70 3b 0a 20 20 20 20 7d 0a  _cleanup;.    }.
1010: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 45 78      if( sqliteEx
1020: 70 72 43 68 65 63 6b 28 70 50 61 72 73 65 2c 20  prCheck(pParse, 
1030: 70 57 68 65 72 65 2c 20 30 2c 20 30 29 20 29 7b  pWhere, 0, 0) ){
1040: 0a 20 20 20 20 20 20 67 6f 74 6f 20 64 65 6c 65  .      goto dele
1050: 74 65 5f 66 72 6f 6d 5f 63 6c 65 61 6e 75 70 3b  te_from_cleanup;
1060: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
1070: 20 42 65 67 69 6e 20 67 65 6e 65 72 61 74 69 6e   Begin generatin
1080: 67 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20 76  g code..  */.  v
1090: 20 3d 20 73 71 6c 69 74 65 47 65 74 56 64 62 65   = sqliteGetVdbe
10a0: 28 70 50 61 72 73 65 29 3b 0a 20 20 69 66 28 20  (pParse);.  if( 
10b0: 76 3d 3d 30 20 29 7b 0a 20 20 20 20 67 6f 74 6f  v==0 ){.    goto
10c0: 20 64 65 6c 65 74 65 5f 66 72 6f 6d 5f 63 6c 65   delete_from_cle
10d0: 61 6e 75 70 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  anup;.  }.  sqli
10e0: 74 65 42 65 67 69 6e 57 72 69 74 65 4f 70 65 72  teBeginWriteOper
10f0: 61 74 69 6f 6e 28 70 50 61 72 73 65 2c 20 72 6f  ation(pParse, ro
1100: 77 5f 74 72 69 67 67 65 72 73 5f 65 78 69 73 74  w_triggers_exist
1110: 2c 0a 20 20 20 20 20 20 20 21 72 6f 77 5f 74 72  ,.       !row_tr
1120: 69 67 67 65 72 73 5f 65 78 69 73 74 20 26 26 20  iggers_exist && 
1130: 70 54 61 62 2d 3e 69 44 62 3d 3d 31 29 3b 0a 0a  pTab->iDb==1);..
1140: 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20    /* Initialize 
1150: 74 68 65 20 63 6f 75 6e 74 65 72 20 6f 66 20 74  the counter of t
1160: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77  he number of row
1170: 73 20 64 65 6c 65 74 65 64 2c 20 69 66 0a 20 20  s deleted, if.  
1180: 2a 2a 20 77 65 20 61 72 65 20 63 6f 75 6e 74 69  ** we are counti
1190: 6e 67 20 72 6f 77 73 2e 0a 20 20 2a 2f 0a 20 20  ng rows..  */.  
11a0: 69 66 28 20 64 62 2d 3e 66 6c 61 67 73 20 26 20  if( db->flags & 
11b0: 53 51 4c 49 54 45 5f 43 6f 75 6e 74 52 6f 77 73  SQLITE_CountRows
11c0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 56 64   ){.    sqliteVd
11d0: 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 49 6e  beAddOp(v, OP_In
11e0: 74 65 67 65 72 2c 20 30 2c 20 30 29 3b 0a 20 20  teger, 0, 0);.  
11f0: 7d 0a 0a 20 20 2f 2a 20 53 70 65 63 69 61 6c 20  }..  /* Special 
1200: 63 61 73 65 3a 20 41 20 44 45 4c 45 54 45 20 77  case: A DELETE w
1210: 69 74 68 6f 75 74 20 61 20 57 48 45 52 45 20 63  ithout a WHERE c
1220: 6c 61 75 73 65 20 64 65 6c 65 74 65 73 20 65 76  lause deletes ev
1230: 65 72 79 74 68 69 6e 67 2e 0a 20 20 2a 2a 20 49  erything..  ** I
1240: 74 20 69 73 20 65 61 73 69 65 72 20 6a 75 73 74  t is easier just
1250: 20 74 6f 20 65 72 61 73 65 20 74 68 65 20 77 68   to erase the wh
1260: 6f 6c 65 20 74 61 62 6c 65 2e 20 20 4e 6f 74 65  ole table.  Note
1270: 2c 20 68 6f 77 65 76 65 72 2c 20 74 68 61 74 0a  , however, that.
1280: 20 20 2a 2a 20 74 68 69 73 20 6d 65 61 6e 73 20    ** this means 
1290: 74 68 61 74 20 74 68 65 20 72 6f 77 20 63 68 61  that the row cha
12a0: 6e 67 65 20 63 6f 75 6e 74 20 77 69 6c 6c 20 62  nge count will b
12b0: 65 20 69 6e 63 6f 72 72 65 63 74 2e 0a 20 20 2a  e incorrect..  *
12c0: 2f 0a 20 20 69 66 28 20 70 57 68 65 72 65 3d 3d  /.  if( pWhere==
12d0: 30 20 26 26 20 21 72 6f 77 5f 74 72 69 67 67 65  0 && !row_trigge
12e0: 72 73 5f 65 78 69 73 74 20 29 7b 0a 20 20 20 20  rs_exist ){.    
12f0: 69 66 28 20 64 62 2d 3e 66 6c 61 67 73 20 26 20  if( db->flags & 
1300: 53 51 4c 49 54 45 5f 43 6f 75 6e 74 52 6f 77 73  SQLITE_CountRows
1310: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20   ){.      /* If 
1320: 63 6f 75 6e 74 69 6e 67 20 72 6f 77 73 20 64 65  counting rows de
1330: 6c 65 74 65 64 2c 20 6a 75 73 74 20 63 6f 75 6e  leted, just coun
1340: 74 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62  t the total numb
1350: 65 72 20 6f 66 0a 20 20 20 20 20 20 2a 2a 20 65  er of.      ** e
1360: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 74 61  ntries in the ta
1370: 62 6c 65 2e 20 2a 2f 0a 20 20 20 20 20 20 69 6e  ble. */.      in
1380: 74 20 65 6e 64 4f 66 4c 6f 6f 70 20 3d 20 73 71  t endOfLoop = sq
1390: 6c 69 74 65 56 64 62 65 4d 61 6b 65 4c 61 62 65  liteVdbeMakeLabe
13a0: 6c 28 76 29 3b 0a 20 20 20 20 20 20 69 6e 74 20  l(v);.      int 
13b0: 61 64 64 72 3b 0a 20 20 20 20 20 20 73 71 6c 69  addr;.      sqli
13c0: 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f  teVdbeAddOp(v, O
13d0: 50 5f 49 6e 74 65 67 65 72 2c 20 70 54 61 62 2d  P_Integer, pTab-
13e0: 3e 69 44 62 2c 20 30 29 3b 0a 20 20 20 20 20 20  >iDb, 0);.      
13f0: 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f 70 28  sqliteVdbeAddOp(
1400: 76 2c 20 4f 50 5f 4f 70 65 6e 52 65 61 64 2c 20  v, OP_OpenRead, 
1410: 62 61 73 65 2c 20 70 54 61 62 2d 3e 74 6e 75 6d  base, pTab->tnum
1420: 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 56  );.      sqliteV
1430: 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 52  dbeAddOp(v, OP_R
1440: 65 77 69 6e 64 2c 20 62 61 73 65 2c 20 73 71 6c  ewind, base, sql
1450: 69 74 65 56 64 62 65 43 75 72 72 65 6e 74 41 64  iteVdbeCurrentAd
1460: 64 72 28 76 29 2b 32 29 3b 0a 20 20 20 20 20 20  dr(v)+2);.      
1470: 61 64 64 72 20 3d 20 73 71 6c 69 74 65 56 64 62  addr = sqliteVdb
1480: 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 41 64 64  eAddOp(v, OP_Add
1490: 49 6d 6d 2c 20 31 2c 20 30 29 3b 0a 20 20 20 20  Imm, 1, 0);.    
14a0: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
14b0: 70 28 76 2c 20 4f 50 5f 4e 65 78 74 2c 20 62 61  p(v, OP_Next, ba
14c0: 73 65 2c 20 61 64 64 72 29 3b 0a 20 20 20 20 20  se, addr);.     
14d0: 20 73 71 6c 69 74 65 56 64 62 65 52 65 73 6f 6c   sqliteVdbeResol
14e0: 76 65 4c 61 62 65 6c 28 76 2c 20 65 6e 64 4f 66  veLabel(v, endOf
14f0: 4c 6f 6f 70 29 3b 0a 20 20 20 20 20 20 73 71 6c  Loop);.      sql
1500: 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20  iteVdbeAddOp(v, 
1510: 4f 50 5f 43 6c 6f 73 65 2c 20 62 61 73 65 2c 20  OP_Close, base, 
1520: 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  0);.    }.    sq
1530: 6c 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c  liteVdbeAddOp(v,
1540: 20 4f 50 5f 43 6c 65 61 72 2c 20 70 54 61 62 2d   OP_Clear, pTab-
1550: 3e 74 6e 75 6d 2c 20 70 54 61 62 2d 3e 69 44 62  >tnum, pTab->iDb
1560: 29 3b 0a 20 20 20 20 66 6f 72 28 70 49 64 78 3d  );.    for(pIdx=
1570: 70 54 61 62 2d 3e 70 49 6e 64 65 78 3b 20 70 49  pTab->pIndex; pI
1580: 64 78 3b 20 70 49 64 78 3d 70 49 64 78 2d 3e 70  dx; pIdx=pIdx->p
1590: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 73 71 6c  Next){.      sql
15a0: 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20  iteVdbeAddOp(v, 
15b0: 4f 50 5f 43 6c 65 61 72 2c 20 70 49 64 78 2d 3e  OP_Clear, pIdx->
15c0: 74 6e 75 6d 2c 20 70 49 64 78 2d 3e 69 44 62 29  tnum, pIdx->iDb)
15d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
15e0: 2a 20 54 68 65 20 75 73 75 61 6c 20 63 61 73 65  * The usual case
15f0: 3a 20 54 68 65 72 65 20 69 73 20 61 20 57 48 45  : There is a WHE
1600: 52 45 20 63 6c 61 75 73 65 20 73 6f 20 77 65 20  RE clause so we 
1610: 68 61 76 65 20 74 6f 20 73 63 61 6e 20 74 68 72  have to scan thr
1620: 6f 75 67 68 0a 20 20 2a 2a 20 74 68 65 20 74 61  ough.  ** the ta
1630: 62 6c 65 20 61 6e 20 70 69 63 6b 20 77 68 69 63  ble an pick whic
1640: 68 20 72 65 63 6f 72 64 73 20 74 6f 20 64 65 6c  h records to del
1650: 65 74 65 2e 0a 20 20 2a 2f 0a 20 20 65 6c 73 65  ete..  */.  else
1660: 7b 0a 20 20 20 20 2f 2a 20 42 65 67 69 6e 20 74  {.    /* Begin t
1670: 68 65 20 64 61 74 61 62 61 73 65 20 73 63 61 6e  he database scan
1680: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70 57 49 6e  .    */.    pWIn
1690: 66 6f 20 3d 20 73 71 6c 69 74 65 57 68 65 72 65  fo = sqliteWhere
16a0: 42 65 67 69 6e 28 70 50 61 72 73 65 2c 20 62 61  Begin(pParse, ba
16b0: 73 65 2c 20 70 54 61 62 4c 69 73 74 2c 20 70 57  se, pTabList, pW
16c0: 68 65 72 65 2c 20 31 2c 20 30 29 3b 0a 20 20 20  here, 1, 0);.   
16d0: 20 69 66 28 20 70 57 49 6e 66 6f 3d 3d 30 20 29   if( pWInfo==0 )
16e0: 20 67 6f 74 6f 20 64 65 6c 65 74 65 5f 66 72 6f   goto delete_fro
16f0: 6d 5f 63 6c 65 61 6e 75 70 3b 0a 0a 20 20 20 20  m_cleanup;..    
1700: 2f 2a 20 52 65 6d 65 6d 62 65 72 20 74 68 65 20  /* Remember the 
1710: 6b 65 79 20 6f 66 20 65 76 65 72 79 20 69 74 65  key of every ite
1720: 6d 20 74 6f 20 62 65 20 64 65 6c 65 74 65 64 2e  m to be deleted.
1730: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69  .    */.    sqli
1740: 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f  teVdbeAddOp(v, O
1750: 50 5f 4c 69 73 74 57 72 69 74 65 2c 20 30 2c 20  P_ListWrite, 0, 
1760: 30 29 3b 0a 20 20 20 20 69 66 28 20 64 62 2d 3e  0);.    if( db->
1770: 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 43  flags & SQLITE_C
1780: 6f 75 6e 74 52 6f 77 73 20 29 7b 0a 20 20 20 20  ountRows ){.    
1790: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
17a0: 70 28 76 2c 20 4f 50 5f 41 64 64 49 6d 6d 2c 20  p(v, OP_AddImm, 
17b0: 31 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  1, 0);.    }..  
17c0: 20 20 2f 2a 20 45 6e 64 20 74 68 65 20 64 61 74    /* End the dat
17d0: 61 62 61 73 65 20 73 63 61 6e 20 6c 6f 6f 70 2e  abase scan loop.
17e0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69  .    */.    sqli
17f0: 74 65 57 68 65 72 65 45 6e 64 28 70 57 49 6e 66  teWhereEnd(pWInf
1800: 6f 29 3b 0a 0a 20 20 20 20 2f 2a 20 44 65 6c 65  o);..    /* Dele
1810: 74 65 20 65 76 65 72 79 20 69 74 65 6d 20 77 68  te every item wh
1820: 6f 73 65 20 6b 65 79 20 77 61 73 20 77 72 69 74  ose key was writ
1830: 74 65 6e 20 74 6f 20 74 68 65 20 6c 69 73 74 20  ten to the list 
1840: 64 75 72 69 6e 67 20 74 68 65 0a 20 20 20 20 2a  during the.    *
1850: 2a 20 64 61 74 61 62 61 73 65 20 73 63 61 6e 2e  * database scan.
1860: 20 20 57 65 20 68 61 76 65 20 74 6f 20 64 65 6c    We have to del
1870: 65 74 65 20 69 74 65 6d 73 20 61 66 74 65 72 20  ete items after 
1880: 74 68 65 20 73 63 61 6e 20 69 73 20 63 6f 6d 70  the scan is comp
1890: 6c 65 74 65 0a 20 20 20 20 2a 2a 20 62 65 63 61  lete.    ** beca
18a0: 75 73 65 20 64 65 6c 65 74 69 6e 67 20 61 6e 20  use deleting an 
18b0: 69 74 65 6d 20 63 61 6e 20 63 68 61 6e 67 65 20  item can change 
18c0: 74 68 65 20 73 63 61 6e 20 6f 72 64 65 72 2e 0a  the scan order..
18d0: 20 20 20 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74      */.    sqlit
18e0: 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50  eVdbeAddOp(v, OP
18f0: 5f 4c 69 73 74 52 65 77 69 6e 64 2c 20 30 2c 20  _ListRewind, 0, 
1900: 30 29 3b 0a 20 20 20 20 65 6e 64 20 3d 20 73 71  0);.    end = sq
1910: 6c 69 74 65 56 64 62 65 4d 61 6b 65 4c 61 62 65  liteVdbeMakeLabe
1920: 6c 28 76 29 3b 0a 0a 20 20 20 20 2f 2a 20 54 68  l(v);..    /* Th
1930: 69 73 20 69 73 20 74 68 65 20 62 65 67 69 6e 6e  is is the beginn
1940: 69 6e 67 20 6f 66 20 74 68 65 20 64 65 6c 65 74  ing of the delet
1950: 65 20 6c 6f 6f 70 20 77 68 65 6e 20 74 68 65 72  e loop when ther
1960: 65 20 61 72 65 0a 20 20 20 20 2a 2a 20 72 6f 77  e are.    ** row
1970: 20 74 72 69 67 67 65 72 73 2e 0a 20 20 20 20 2a   triggers..    *
1980: 2f 0a 20 20 20 20 69 66 28 20 72 6f 77 5f 74 72  /.    if( row_tr
1990: 69 67 67 65 72 73 5f 65 78 69 73 74 20 29 7b 0a  iggers_exist ){.
19a0: 20 20 20 20 20 20 61 64 64 72 20 3d 20 73 71 6c        addr = sql
19b0: 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20  iteVdbeAddOp(v, 
19c0: 4f 50 5f 4c 69 73 74 52 65 61 64 2c 20 30 2c 20  OP_ListRead, 0, 
19d0: 65 6e 64 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  end);.      sqli
19e0: 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f  teVdbeAddOp(v, O
19f0: 50 5f 44 75 70 2c 20 30 2c 20 30 29 3b 0a 20 20  P_Dup, 0, 0);.  
1a00: 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64      sqliteVdbeAd
1a10: 64 4f 70 28 76 2c 20 4f 50 5f 49 6e 74 65 67 65  dOp(v, OP_Intege
1a20: 72 2c 20 70 54 61 62 2d 3e 69 44 62 2c 20 30 29  r, pTab->iDb, 0)
1a30: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 56 64  ;.      sqliteVd
1a40: 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 4f 70  beAddOp(v, OP_Op
1a50: 65 6e 52 65 61 64 2c 20 62 61 73 65 2c 20 70 54  enRead, base, pT
1a60: 61 62 2d 3e 74 6e 75 6d 29 3b 0a 20 20 20 20 20  ab->tnum);.     
1a70: 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f 70   sqliteVdbeAddOp
1a80: 28 76 2c 20 4f 50 5f 4d 6f 76 65 54 6f 2c 20 62  (v, OP_MoveTo, b
1a90: 61 73 65 2c 20 30 29 3b 0a 20 20 20 20 20 20 73  ase, 0);.      s
1aa0: 71 6c 69 74 65 56 64 62 65 41 64 64 4f 70 28 76  qliteVdbeAddOp(v
1ab0: 2c 20 4f 50 5f 4f 70 65 6e 54 65 6d 70 2c 20 6f  , OP_OpenTemp, o
1ac0: 6c 64 49 64 78 2c 20 30 29 3b 0a 0a 20 20 20 20  ldIdx, 0);..    
1ad0: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
1ae0: 70 28 76 2c 20 4f 50 5f 49 6e 74 65 67 65 72 2c  p(v, OP_Integer,
1af0: 20 31 33 2c 20 30 29 3b 0a 20 20 20 20 20 20 66   13, 0);.      f
1b00: 6f 72 28 69 20 3d 20 30 3b 20 69 3c 70 54 61 62  or(i = 0; i<pTab
1b10: 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->nCol; i++){.  
1b20: 20 20 20 20 20 20 69 66 28 20 69 3d 3d 70 54 61        if( i==pTa
1b30: 62 2d 3e 69 50 4b 65 79 20 29 7b 20 0a 20 20 20  b->iPKey ){ .   
1b40: 20 20 20 20 20 20 20 73 71 6c 69 74 65 56 64 62         sqliteVdb
1b50: 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 52 65 63  eAddOp(v, OP_Rec
1b60: 6e 6f 2c 20 62 61 73 65 2c 20 30 29 3b 0a 09 7d  no, base, 0);..}
1b70: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
1b80: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
1b90: 70 28 76 2c 20 4f 50 5f 43 6f 6c 75 6d 6e 2c 20  p(v, OP_Column, 
1ba0: 62 61 73 65 2c 20 69 29 3b 0a 09 7d 0a 20 20 20  base, i);..}.   
1bb0: 20 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 74     }.      sqlit
1bc0: 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50  eVdbeAddOp(v, OP
1bd0: 5f 4d 61 6b 65 52 65 63 6f 72 64 2c 20 70 54 61  _MakeRecord, pTa
1be0: 62 2d 3e 6e 43 6f 6c 2c 20 30 29 3b 0a 20 20 20  b->nCol, 0);.   
1bf0: 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64     sqliteVdbeAdd
1c00: 4f 70 28 76 2c 20 4f 50 5f 50 75 74 49 6e 74 4b  Op(v, OP_PutIntK
1c10: 65 79 2c 20 6f 6c 64 49 64 78 2c 20 30 29 3b 0a  ey, oldIdx, 0);.
1c20: 20 20 20 20 20 20 73 71 6c 69 74 65 56 64 62 65        sqliteVdbe
1c30: 41 64 64 4f 70 28 76 2c 20 4f 50 5f 43 6c 6f 73  AddOp(v, OP_Clos
1c40: 65 2c 20 62 61 73 65 2c 20 30 29 3b 0a 20 20 20  e, base, 0);.   
1c50: 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64     sqliteVdbeAdd
1c60: 4f 70 28 76 2c 20 4f 50 5f 52 65 77 69 6e 64 2c  Op(v, OP_Rewind,
1c70: 20 6f 6c 64 49 64 78 2c 20 30 29 3b 0a 0a 20 20   oldIdx, 0);..  
1c80: 20 20 20 20 73 71 6c 69 74 65 43 6f 64 65 52 6f      sqliteCodeRo
1c90: 77 54 72 69 67 67 65 72 28 70 50 61 72 73 65 2c  wTrigger(pParse,
1ca0: 20 54 4b 5f 44 45 4c 45 54 45 2c 20 30 2c 20 54   TK_DELETE, 0, T
1cb0: 4b 5f 42 45 46 4f 52 45 2c 20 70 54 61 62 2c 20  K_BEFORE, pTab, 
1cc0: 2d 31 2c 20 0a 20 20 20 20 20 20 20 20 20 20 6f  -1, .          o
1cd0: 6c 64 49 64 78 2c 20 28 70 50 61 72 73 65 2d 3e  ldIdx, (pParse->
1ce0: 74 72 69 67 53 74 61 63 6b 29 3f 70 50 61 72 73  trigStack)?pPars
1cf0: 65 2d 3e 74 72 69 67 53 74 61 63 6b 2d 3e 6f 72  e->trigStack->or
1d00: 63 6f 6e 66 3a 4f 45 5f 44 65 66 61 75 6c 74 2c  conf:OE_Default,
1d10: 0a 09 20 20 61 64 64 72 29 3b 0a 20 20 20 20 7d  ..  addr);.    }
1d20: 0a 0a 20 20 20 20 2f 2a 20 4f 70 65 6e 20 63 75  ..    /* Open cu
1d30: 72 73 6f 72 73 20 66 6f 72 20 74 68 65 20 74 61  rsors for the ta
1d40: 62 6c 65 20 77 65 20 61 72 65 20 64 65 6c 65 74  ble we are delet
1d50: 69 6e 67 20 66 72 6f 6d 20 61 6e 64 20 61 6c 6c  ing from and all
1d60: 20 69 74 73 0a 20 20 20 20 2a 2a 20 69 6e 64 69   its.    ** indi
1d70: 63 65 73 2e 20 20 49 66 20 74 68 65 72 65 20 61  ces.  If there a
1d80: 72 65 20 72 6f 77 20 74 72 69 67 67 65 72 73 2c  re row triggers,
1d90: 20 74 68 69 73 20 68 61 70 70 65 6e 73 20 69 6e   this happens in
1da0: 73 69 64 65 20 74 68 65 0a 20 20 20 20 2a 2a 20  side the.    ** 
1db0: 4f 50 5f 4c 69 73 74 52 65 61 64 20 6c 6f 6f 70  OP_ListRead loop
1dc0: 20 62 65 63 61 75 73 65 20 74 68 65 20 63 75 72   because the cur
1dd0: 73 6f 72 20 68 61 76 65 20 74 6f 20 61 6c 6c 20  sor have to all 
1de0: 62 65 20 63 6c 6f 73 65 64 0a 20 20 20 20 2a 2a  be closed.    **
1df0: 20 62 65 66 6f 72 65 20 74 68 65 20 74 72 69 67   before the trig
1e00: 67 65 72 20 66 69 72 65 73 2e 20 20 49 66 20 74  ger fires.  If t
1e10: 68 65 72 65 20 61 72 65 20 6e 6f 20 72 6f 77 20  here are no row 
1e20: 74 72 69 67 67 65 72 73 2c 20 74 68 65 0a 20 20  triggers, the.  
1e30: 20 20 2a 2a 20 63 75 72 73 6f 72 73 20 61 72 65    ** cursors are
1e40: 20 6f 70 65 6e 65 64 20 6f 6e 6c 79 20 6f 6e 63   opened only onc
1e50: 65 20 6f 6e 20 74 68 65 20 6f 75 74 73 69 64 65  e on the outside
1e60: 20 74 68 65 20 6c 6f 6f 70 2e 0a 20 20 20 20 2a   the loop..    *
1e70: 2f 0a 20 20 20 20 70 50 61 72 73 65 2d 3e 6e 54  /.    pParse->nT
1e80: 61 62 20 3d 20 62 61 73 65 20 2b 20 31 3b 0a 20  ab = base + 1;. 
1e90: 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64     sqliteVdbeAdd
1ea0: 4f 70 28 76 2c 20 4f 50 5f 49 6e 74 65 67 65 72  Op(v, OP_Integer
1eb0: 2c 20 70 54 61 62 2d 3e 69 44 62 2c 20 30 29 3b  , pTab->iDb, 0);
1ec0: 0a 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41  .    sqliteVdbeA
1ed0: 64 64 4f 70 28 76 2c 20 4f 50 5f 4f 70 65 6e 57  ddOp(v, OP_OpenW
1ee0: 72 69 74 65 2c 20 62 61 73 65 2c 20 70 54 61 62  rite, base, pTab
1ef0: 2d 3e 74 6e 75 6d 29 3b 0a 20 20 20 20 66 6f 72  ->tnum);.    for
1f00: 28 69 3d 31 2c 20 70 49 64 78 3d 70 54 61 62 2d  (i=1, pIdx=pTab-
1f10: 3e 70 49 6e 64 65 78 3b 20 70 49 64 78 3b 20 69  >pIndex; pIdx; i
1f20: 2b 2b 2c 20 70 49 64 78 3d 70 49 64 78 2d 3e 70  ++, pIdx=pIdx->p
1f30: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 73 71 6c  Next){.      sql
1f40: 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20  iteVdbeAddOp(v, 
1f50: 4f 50 5f 49 6e 74 65 67 65 72 2c 20 70 49 64 78  OP_Integer, pIdx
1f60: 2d 3e 69 44 62 2c 20 30 29 3b 0a 20 20 20 20 20  ->iDb, 0);.     
1f70: 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f 70   sqliteVdbeAddOp
1f80: 28 76 2c 20 4f 50 5f 4f 70 65 6e 57 72 69 74 65  (v, OP_OpenWrite
1f90: 2c 20 70 50 61 72 73 65 2d 3e 6e 54 61 62 2b 2b  , pParse->nTab++
1fa0: 2c 20 70 49 64 78 2d 3e 74 6e 75 6d 29 3b 0a 20  , pIdx->tnum);. 
1fb0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 54 68 69     }..    /* Thi
1fc0: 73 20 69 73 20 74 68 65 20 62 65 67 69 6e 6e 69  s is the beginni
1fd0: 6e 67 20 6f 66 20 74 68 65 20 64 65 6c 65 74 65  ng of the delete
1fe0: 20 6c 6f 6f 70 20 77 68 65 6e 20 74 68 65 72 65   loop when there
1ff0: 20 61 72 65 20 6e 6f 0a 20 20 20 20 2a 2a 20 72   are no.    ** r
2000: 6f 77 20 74 72 69 67 67 65 72 73 20 2a 2f 0a 20  ow triggers */. 
2010: 20 20 20 69 66 28 20 21 72 6f 77 5f 74 72 69 67     if( !row_trig
2020: 67 65 72 73 5f 65 78 69 73 74 20 29 7b 20 0a 20  gers_exist ){ . 
2030: 20 20 20 20 20 61 64 64 72 20 3d 20 73 71 6c 69       addr = sqli
2040: 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f  teVdbeAddOp(v, O
2050: 50 5f 4c 69 73 74 52 65 61 64 2c 20 30 2c 20 65  P_ListRead, 0, e
2060: 6e 64 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  nd);.    }..    
2070: 2f 2a 20 44 65 6c 65 74 65 20 74 68 65 20 72 6f  /* Delete the ro
2080: 77 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 47  w */.    sqliteG
2090: 65 6e 65 72 61 74 65 52 6f 77 44 65 6c 65 74 65  enerateRowDelete
20a0: 28 64 62 2c 20 76 2c 20 70 54 61 62 2c 20 62 61  (db, v, pTab, ba
20b0: 73 65 2c 20 70 50 61 72 73 65 2d 3e 74 72 69 67  se, pParse->trig
20c0: 53 74 61 63 6b 3d 3d 30 29 3b 0a 0a 20 20 20 20  Stack==0);..    
20d0: 2f 2a 20 49 66 20 74 68 65 72 65 20 61 72 65 20  /* If there are 
20e0: 72 6f 77 20 74 72 69 67 67 65 72 73 2c 20 63 6c  row triggers, cl
20f0: 6f 73 65 20 61 6c 6c 20 63 75 72 73 6f 72 73 20  ose all cursors 
2100: 74 68 65 6e 20 69 6e 76 6f 6b 65 0a 20 20 20 20  then invoke.    
2110: 2a 2a 20 74 68 65 20 41 46 54 45 52 20 74 72 69  ** the AFTER tri
2120: 67 67 65 72 73 0a 20 20 20 20 2a 2f 0a 20 20 20  ggers.    */.   
2130: 20 69 66 28 20 72 6f 77 5f 74 72 69 67 67 65 72   if( row_trigger
2140: 73 5f 65 78 69 73 74 20 29 7b 0a 20 20 20 20 20  s_exist ){.     
2150: 20 66 6f 72 28 69 3d 31 2c 20 70 49 64 78 3d 70   for(i=1, pIdx=p
2160: 54 61 62 2d 3e 70 49 6e 64 65 78 3b 20 70 49 64  Tab->pIndex; pId
2170: 78 3b 20 69 2b 2b 2c 20 70 49 64 78 3d 70 49 64  x; i++, pIdx=pId
2180: 78 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20  x->pNext){.     
2190: 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64     sqliteVdbeAdd
21a0: 4f 70 28 76 2c 20 4f 50 5f 43 6c 6f 73 65 2c 20  Op(v, OP_Close, 
21b0: 62 61 73 65 20 2b 20 69 2c 20 70 49 64 78 2d 3e  base + i, pIdx->
21c0: 74 6e 75 6d 29 3b 0a 20 20 20 20 20 20 7d 0a 20  tnum);.      }. 
21d0: 20 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41       sqliteVdbeA
21e0: 64 64 4f 70 28 76 2c 20 4f 50 5f 43 6c 6f 73 65  ddOp(v, OP_Close
21f0: 2c 20 62 61 73 65 2c 20 30 29 3b 0a 20 20 20 20  , base, 0);.    
2200: 20 20 73 71 6c 69 74 65 43 6f 64 65 52 6f 77 54    sqliteCodeRowT
2210: 72 69 67 67 65 72 28 70 50 61 72 73 65 2c 20 54  rigger(pParse, T
2220: 4b 5f 44 45 4c 45 54 45 2c 20 30 2c 20 54 4b 5f  K_DELETE, 0, TK_
2230: 41 46 54 45 52 2c 20 70 54 61 62 2c 20 2d 31 2c  AFTER, pTab, -1,
2240: 20 0a 20 20 20 20 20 20 20 20 20 20 6f 6c 64 49   .          oldI
2250: 64 78 2c 20 28 70 50 61 72 73 65 2d 3e 74 72 69  dx, (pParse->tri
2260: 67 53 74 61 63 6b 29 3f 70 50 61 72 73 65 2d 3e  gStack)?pParse->
2270: 74 72 69 67 53 74 61 63 6b 2d 3e 6f 72 63 6f 6e  trigStack->orcon
2280: 66 3a 4f 45 5f 44 65 66 61 75 6c 74 2c 0a 09 20  f:OE_Default,.. 
2290: 20 61 64 64 72 29 3b 0a 20 20 20 20 7d 0a 0a 20   addr);.    }.. 
22a0: 20 20 20 2f 2a 20 45 6e 64 20 6f 66 20 74 68 65     /* End of the
22b0: 20 64 65 6c 65 74 65 20 6c 6f 6f 70 20 2a 2f 0a   delete loop */.
22c0: 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41 64      sqliteVdbeAd
22d0: 64 4f 70 28 76 2c 20 4f 50 5f 47 6f 74 6f 2c 20  dOp(v, OP_Goto, 
22e0: 30 2c 20 61 64 64 72 29 3b 0a 20 20 20 20 73 71  0, addr);.    sq
22f0: 6c 69 74 65 56 64 62 65 52 65 73 6f 6c 76 65 4c  liteVdbeResolveL
2300: 61 62 65 6c 28 76 2c 20 65 6e 64 29 3b 0a 20 20  abel(v, end);.  
2310: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
2320: 70 28 76 2c 20 4f 50 5f 4c 69 73 74 52 65 73 65  p(v, OP_ListRese
2330: 74 2c 20 30 2c 20 30 29 3b 0a 0a 20 20 20 20 2f  t, 0, 0);..    /
2340: 2a 20 43 6c 6f 73 65 20 74 68 65 20 63 75 72 73  * Close the curs
2350: 6f 72 73 20 61 66 74 65 72 20 74 68 65 20 6c 6f  ors after the lo
2360: 6f 70 20 69 66 20 74 68 65 72 65 20 61 72 65 20  op if there are 
2370: 6e 6f 20 72 6f 77 20 74 72 69 67 67 65 72 73 20  no row triggers 
2380: 2a 2f 0a 20 20 20 20 69 66 28 20 21 72 6f 77 5f  */.    if( !row_
2390: 74 72 69 67 67 65 72 73 5f 65 78 69 73 74 20 29  triggers_exist )
23a0: 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 2c  {.      for(i=1,
23b0: 20 70 49 64 78 3d 70 54 61 62 2d 3e 70 49 6e 64   pIdx=pTab->pInd
23c0: 65 78 3b 20 70 49 64 78 3b 20 69 2b 2b 2c 20 70  ex; pIdx; i++, p
23d0: 49 64 78 3d 70 49 64 78 2d 3e 70 4e 65 78 74 29  Idx=pIdx->pNext)
23e0: 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
23f0: 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f  VdbeAddOp(v, OP_
2400: 43 6c 6f 73 65 2c 20 62 61 73 65 20 2b 20 69 2c  Close, base + i,
2410: 20 70 49 64 78 2d 3e 74 6e 75 6d 29 3b 0a 20 20   pIdx->tnum);.  
2420: 20 20 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69      }.      sqli
2430: 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f  teVdbeAddOp(v, O
2440: 50 5f 43 6c 6f 73 65 2c 20 62 61 73 65 2c 20 30  P_Close, base, 0
2450: 29 3b 0a 20 20 20 20 20 20 70 50 61 72 73 65 2d  );.      pParse-
2460: 3e 6e 54 61 62 20 3d 20 62 61 73 65 3b 0a 20 20  >nTab = base;.  
2470: 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65    }.  }.  sqlite
2480: 45 6e 64 57 72 69 74 65 4f 70 65 72 61 74 69 6f  EndWriteOperatio
2490: 6e 28 70 50 61 72 73 65 29 3b 0a 0a 20 20 2f 2a  n(pParse);..  /*
24a0: 0a 20 20 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  .  ** Return the
24b0: 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20   number of rows 
24c0: 74 68 61 74 20 77 65 72 65 20 64 65 6c 65 74 65  that were delete
24d0: 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 64 62  d..  */.  if( db
24e0: 2d 3e 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45  ->flags & SQLITE
24f0: 5f 43 6f 75 6e 74 52 6f 77 73 20 29 7b 0a 20 20  _CountRows ){.  
2500: 20 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f    sqliteVdbeAddO
2510: 70 28 76 2c 20 4f 50 5f 43 6f 6c 75 6d 6e 4e 61  p(v, OP_ColumnNa
2520: 6d 65 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73  me, 0, 0);.    s
2530: 71 6c 69 74 65 56 64 62 65 43 68 61 6e 67 65 50  qliteVdbeChangeP
2540: 33 28 76 2c 20 2d 31 2c 20 22 72 6f 77 73 20 64  3(v, -1, "rows d
2550: 65 6c 65 74 65 64 22 2c 20 50 33 5f 53 54 41 54  eleted", P3_STAT
2560: 49 43 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 56  IC);.    sqliteV
2570: 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 43  dbeAddOp(v, OP_C
2580: 61 6c 6c 62 61 63 6b 2c 20 31 2c 20 30 29 3b 0a  allback, 1, 0);.
2590: 20 20 7d 0a 0a 64 65 6c 65 74 65 5f 66 72 6f 6d    }..delete_from
25a0: 5f 63 6c 65 61 6e 75 70 3a 0a 20 20 73 71 6c 69  _cleanup:.  sqli
25b0: 74 65 53 72 63 4c 69 73 74 44 65 6c 65 74 65 28  teSrcListDelete(
25c0: 70 54 61 62 4c 69 73 74 29 3b 0a 20 20 73 71 6c  pTabList);.  sql
25d0: 69 74 65 45 78 70 72 44 65 6c 65 74 65 28 70 57  iteExprDelete(pW
25e0: 68 65 72 65 29 3b 0a 20 20 72 65 74 75 72 6e 3b  here);.  return;
25f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72  .}../*.** This r
2600: 6f 75 74 69 6e 65 20 67 65 6e 65 72 61 74 65 73  outine generates
2610: 20 56 44 42 45 20 63 6f 64 65 20 74 68 61 74 20   VDBE code that 
2620: 63 61 75 73 65 73 20 61 20 73 69 6e 67 6c 65 20  causes a single 
2630: 72 6f 77 20 6f 66 20 61 0a 2a 2a 20 73 69 6e 67  row of a.** sing
2640: 6c 65 20 74 61 62 6c 65 20 74 6f 20 62 65 20 64  le table to be d
2650: 65 6c 65 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  eleted..**.** Th
2660: 65 20 56 44 42 45 20 6d 75 73 74 20 62 65 20 69  e VDBE must be i
2670: 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 73  n a particular s
2680: 74 61 74 65 20 77 68 65 6e 20 74 68 69 73 20 72  tate when this r
2690: 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64  outine is called
26a0: 2e 0a 2a 2a 20 54 68 65 73 65 20 61 72 65 20 74  ..** These are t
26b0: 68 65 20 72 65 71 75 69 72 65 6d 65 6e 74 73 3a  he requirements:
26c0: 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 20 41 20 72  .**.**   1.  A r
26d0: 65 61 64 2f 77 72 69 74 65 20 63 75 72 73 6f 72  ead/write cursor
26e0: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 70 54 61   pointing to pTa
26f0: 62 2c 20 74 68 65 20 74 61 62 6c 65 20 63 6f 6e  b, the table con
2700: 74 61 69 6e 69 6e 67 20 74 68 65 20 72 6f 77 0a  taining the row.
2710: 2a 2a 20 20 20 20 20 20 20 74 6f 20 62 65 20 64  **       to be d
2720: 65 6c 65 74 65 64 2c 20 6d 75 73 74 20 62 65 20  eleted, must be 
2730: 6f 70 65 6e 65 64 20 61 73 20 63 75 72 73 6f 72  opened as cursor
2740: 20 6e 75 6d 62 65 72 20 22 62 61 73 65 22 2e 0a   number "base"..
2750: 2a 2a 0a 2a 2a 20 20 20 32 2e 20 20 52 65 61 64  **.**   2.  Read
2760: 2f 77 72 69 74 65 20 63 75 72 73 6f 72 73 20 66  /write cursors f
2770: 6f 72 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f  or all indices o
2780: 66 20 70 54 61 62 20 6d 75 73 74 20 62 65 20 6f  f pTab must be o
2790: 70 65 6e 20 61 73 0a 2a 2a 20 20 20 20 20 20 20  pen as.**       
27a0: 63 75 72 73 6f 72 20 6e 75 6d 62 65 72 20 62 61  cursor number ba
27b0: 73 65 2b 69 20 66 6f 72 20 74 68 65 20 69 2d 74  se+i for the i-t
27c0: 68 20 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 20  h index..**.**  
27d0: 20 33 2e 20 20 54 68 65 20 72 65 63 6f 72 64 20   3.  The record 
27e0: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 72 6f  number of the ro
27f0: 77 20 74 6f 20 62 65 20 64 65 6c 65 74 65 64 20  w to be deleted 
2800: 6d 75 73 74 20 62 65 20 6f 6e 20 74 68 65 20 74  must be on the t
2810: 6f 70 0a 2a 2a 20 20 20 20 20 20 20 6f 66 20 74  op.**       of t
2820: 68 65 20 73 74 61 63 6b 2e 0a 2a 2a 0a 2a 2a 20  he stack..**.** 
2830: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 70 6f 70  This routine pop
2840: 73 20 74 68 65 20 74 6f 70 20 6f 66 20 74 68 65  s the top of the
2850: 20 73 74 61 63 6b 20 74 6f 20 72 65 6d 6f 76 65   stack to remove
2860: 20 74 68 65 20 72 65 63 6f 72 64 20 6e 75 6d 62   the record numb
2870: 65 72 0a 2a 2a 20 61 6e 64 20 74 68 65 6e 20 67  er.** and then g
2880: 65 6e 65 72 61 74 65 73 20 63 6f 64 65 20 74 6f  enerates code to
2890: 20 72 65 6d 6f 76 65 20 62 6f 74 68 20 74 68 65   remove both the
28a0: 20 74 61 62 6c 65 20 72 65 63 6f 72 64 20 61 6e   table record an
28b0: 64 20 61 6c 6c 20 69 6e 64 65 78 0a 2a 2a 20 65  d all index.** e
28c0: 6e 74 72 69 65 73 20 74 68 61 74 20 70 6f 69 6e  ntries that poin
28d0: 74 20 74 6f 20 74 68 61 74 20 72 65 63 6f 72 64  t to that record
28e0: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
28f0: 47 65 6e 65 72 61 74 65 52 6f 77 44 65 6c 65 74  GenerateRowDelet
2900: 65 28 0a 20 20 73 71 6c 69 74 65 20 2a 64 62 2c  e(.  sqlite *db,
2910: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 64          /* The d
2920: 61 74 61 62 61 73 65 20 63 6f 6e 74 61 69 6e 69  atabase containi
2930: 6e 67 20 74 68 65 20 69 6e 64 65 78 20 2a 2f 0a  ng the index */.
2940: 20 20 56 64 62 65 20 2a 76 2c 20 20 20 20 20 20    Vdbe *v,      
2950: 20 20 20 20 20 2f 2a 20 47 65 6e 65 72 61 74 65       /* Generate
2960: 20 63 6f 64 65 20 69 6e 74 6f 20 74 68 69 73 20   code into this 
2970: 56 44 42 45 20 2a 2f 0a 20 20 54 61 62 6c 65 20  VDBE */.  Table 
2980: 2a 70 54 61 62 2c 20 20 20 20 20 20 20 2f 2a 20  *pTab,       /* 
2990: 54 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67  Table containing
29a0: 20 74 68 65 20 72 6f 77 20 74 6f 20 62 65 20 64   the row to be d
29b0: 65 6c 65 74 65 64 20 2a 2f 0a 20 20 69 6e 74 20  eleted */.  int 
29c0: 62 61 73 65 2c 20 20 20 20 20 20 20 20 20 20 2f  base,          /
29d0: 2a 20 43 75 72 73 6f 72 20 6e 75 6d 62 65 72 20  * Cursor number 
29e0: 66 6f 72 20 74 68 65 20 74 61 62 6c 65 20 2a 2f  for the table */
29f0: 0a 20 20 69 6e 74 20 63 6f 75 6e 74 20 20 20 20  .  int count    
2a00: 20 20 20 20 20 20 2f 2a 20 49 6e 63 72 65 6d 65        /* Increme
2a10: 6e 74 20 74 68 65 20 72 6f 77 20 63 68 61 6e 67  nt the row chang
2a20: 65 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 29 7b 0a  e counter */.){.
2a30: 20 20 69 6e 74 20 61 64 64 72 3b 0a 20 20 61 64    int addr;.  ad
2a40: 64 72 20 3d 20 73 71 6c 69 74 65 56 64 62 65 41  dr = sqliteVdbeA
2a50: 64 64 4f 70 28 76 2c 20 4f 50 5f 4e 6f 74 45 78  ddOp(v, OP_NotEx
2a60: 69 73 74 73 2c 20 62 61 73 65 2c 20 30 29 3b 0a  ists, base, 0);.
2a70: 20 20 73 71 6c 69 74 65 47 65 6e 65 72 61 74 65    sqliteGenerate
2a80: 52 6f 77 49 6e 64 65 78 44 65 6c 65 74 65 28 64  RowIndexDelete(d
2a90: 62 2c 20 76 2c 20 70 54 61 62 2c 20 62 61 73 65  b, v, pTab, base
2aa0: 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 56 64  , 0);.  sqliteVd
2ab0: 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f 44 65  beAddOp(v, OP_De
2ac0: 6c 65 74 65 2c 20 62 61 73 65 2c 20 63 6f 75 6e  lete, base, coun
2ad0: 74 29 3b 0a 20 20 73 71 6c 69 74 65 56 64 62 65  t);.  sqliteVdbe
2ae0: 43 68 61 6e 67 65 50 32 28 76 2c 20 61 64 64 72  ChangeP2(v, addr
2af0: 2c 20 73 71 6c 69 74 65 56 64 62 65 43 75 72 72  , sqliteVdbeCurr
2b00: 65 6e 74 41 64 64 72 28 76 29 29 3b 0a 7d 0a 0a  entAddr(v));.}..
2b10: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
2b20: 6e 65 20 67 65 6e 65 72 61 74 65 73 20 56 44 42  ne generates VDB
2b30: 45 20 63 6f 64 65 20 74 68 61 74 20 63 61 75 73  E code that caus
2b40: 65 73 20 74 68 65 20 64 65 6c 65 74 69 6f 6e 20  es the deletion 
2b50: 6f 66 20 61 6c 6c 0a 2a 2a 20 69 6e 64 65 78 20  of all.** index 
2b60: 65 6e 74 72 69 65 73 20 61 73 73 6f 63 69 61 74  entries associat
2b70: 65 64 20 77 69 74 68 20 61 20 73 69 6e 67 6c 65  ed with a single
2b80: 20 72 6f 77 20 6f 66 20 61 20 73 69 6e 67 6c 65   row of a single
2b90: 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68   table..**.** Th
2ba0: 65 20 56 44 42 45 20 6d 75 73 74 20 62 65 20 69  e VDBE must be i
2bb0: 6e 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 73  n a particular s
2bc0: 74 61 74 65 20 77 68 65 6e 20 74 68 69 73 20 72  tate when this r
2bd0: 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64  outine is called
2be0: 2e 0a 2a 2a 20 54 68 65 73 65 20 61 72 65 20 74  ..** These are t
2bf0: 68 65 20 72 65 71 75 69 72 65 6d 65 6e 74 73 3a  he requirements:
2c00: 0a 2a 2a 0a 2a 2a 20 20 20 31 2e 20 20 41 20 72  .**.**   1.  A r
2c10: 65 61 64 2f 77 72 69 74 65 20 63 75 72 73 6f 72  ead/write cursor
2c20: 20 70 6f 69 6e 74 69 6e 67 20 74 6f 20 70 54 61   pointing to pTa
2c30: 62 2c 20 74 68 65 20 74 61 62 6c 65 20 63 6f 6e  b, the table con
2c40: 74 61 69 6e 69 6e 67 20 74 68 65 20 72 6f 77 0a  taining the row.
2c50: 2a 2a 20 20 20 20 20 20 20 74 6f 20 62 65 20 64  **       to be d
2c60: 65 6c 65 74 65 64 2c 20 6d 75 73 74 20 62 65 20  eleted, must be 
2c70: 6f 70 65 6e 65 64 20 61 73 20 63 75 72 73 6f 72  opened as cursor
2c80: 20 6e 75 6d 62 65 72 20 22 62 61 73 65 22 2e 0a   number "base"..
2c90: 2a 2a 0a 2a 2a 20 20 20 32 2e 20 20 52 65 61 64  **.**   2.  Read
2ca0: 2f 77 72 69 74 65 20 63 75 72 73 6f 72 73 20 66  /write cursors f
2cb0: 6f 72 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f  or all indices o
2cc0: 66 20 70 54 61 62 20 6d 75 73 74 20 62 65 20 6f  f pTab must be o
2cd0: 70 65 6e 20 61 73 0a 2a 2a 20 20 20 20 20 20 20  pen as.**       
2ce0: 63 75 72 73 6f 72 20 6e 75 6d 62 65 72 20 62 61  cursor number ba
2cf0: 73 65 2b 69 20 66 6f 72 20 74 68 65 20 69 2d 74  se+i for the i-t
2d00: 68 20 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 20  h index..**.**  
2d10: 20 33 2e 20 20 54 68 65 20 22 62 61 73 65 22 20   3.  The "base" 
2d20: 63 75 72 73 6f 72 20 6d 75 73 74 20 62 65 20 70  cursor must be p
2d30: 6f 69 6e 74 69 6e 67 20 74 6f 20 74 68 65 20 72  ointing to the r
2d40: 6f 77 20 74 68 61 74 20 69 73 20 74 6f 20 62 65  ow that is to be
2d50: 0a 2a 2a 20 20 20 20 20 20 20 64 65 6c 65 74 65  .**       delete
2d60: 64 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  d..*/.void sqlit
2d70: 65 47 65 6e 65 72 61 74 65 52 6f 77 49 6e 64 65  eGenerateRowInde
2d80: 78 44 65 6c 65 74 65 28 0a 20 20 73 71 6c 69 74  xDelete(.  sqlit
2d90: 65 20 2a 64 62 2c 20 20 20 20 20 20 20 20 2f 2a  e *db,        /*
2da0: 20 54 68 65 20 64 61 74 61 62 61 73 65 20 63 6f   The database co
2db0: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 69 6e 64  ntaining the ind
2dc0: 65 78 20 2a 2f 0a 20 20 56 64 62 65 20 2a 76 2c  ex */.  Vdbe *v,
2dd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 47 65             /* Ge
2de0: 6e 65 72 61 74 65 20 63 6f 64 65 20 69 6e 74 6f  nerate code into
2df0: 20 74 68 69 73 20 56 44 42 45 20 2a 2f 0a 20 20   this VDBE */.  
2e00: 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 20 20 20  Table *pTab,    
2e10: 20 20 20 2f 2a 20 54 61 62 6c 65 20 63 6f 6e 74     /* Table cont
2e20: 61 69 6e 69 6e 67 20 74 68 65 20 72 6f 77 20 74  aining the row t
2e30: 6f 20 62 65 20 64 65 6c 65 74 65 64 20 2a 2f 0a  o be deleted */.
2e40: 20 20 69 6e 74 20 62 61 73 65 2c 20 20 20 20 20    int base,     
2e50: 20 20 20 20 20 2f 2a 20 43 75 72 73 6f 72 20 6e       /* Cursor n
2e60: 75 6d 62 65 72 20 66 6f 72 20 74 68 65 20 74 61  umber for the ta
2e70: 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61  ble */.  char *a
2e80: 49 64 78 55 73 65 64 20 20 20 20 20 2f 2a 20 4f  IdxUsed     /* O
2e90: 6e 6c 79 20 64 65 6c 65 74 65 20 69 66 20 61 49  nly delete if aI
2ea0: 64 78 55 73 65 64 21 3d 30 20 26 26 20 61 49 64  dxUsed!=0 && aId
2eb0: 78 55 73 65 64 5b 69 5d 21 3d 30 20 2a 2f 0a 29  xUsed[i]!=0 */.)
2ec0: 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 49 6e 64  {.  int i;.  Ind
2ed0: 65 78 20 2a 70 49 64 78 3b 0a 0a 20 20 66 6f 72  ex *pIdx;..  for
2ee0: 28 69 3d 31 2c 20 70 49 64 78 3d 70 54 61 62 2d  (i=1, pIdx=pTab-
2ef0: 3e 70 49 6e 64 65 78 3b 20 70 49 64 78 3b 20 69  >pIndex; pIdx; i
2f00: 2b 2b 2c 20 70 49 64 78 3d 70 49 64 78 2d 3e 70  ++, pIdx=pIdx->p
2f10: 4e 65 78 74 29 7b 0a 20 20 20 20 69 6e 74 20 6a  Next){.    int j
2f20: 3b 0a 20 20 20 20 69 66 28 20 61 49 64 78 55 73  ;.    if( aIdxUs
2f30: 65 64 21 3d 30 20 26 26 20 61 49 64 78 55 73 65  ed!=0 && aIdxUse
2f40: 64 5b 69 2d 31 5d 3d 3d 30 20 29 20 63 6f 6e 74  d[i-1]==0 ) cont
2f50: 69 6e 75 65 3b 0a 20 20 20 20 73 71 6c 69 74 65  inue;.    sqlite
2f60: 56 64 62 65 41 64 64 4f 70 28 76 2c 20 4f 50 5f  VdbeAddOp(v, OP_
2f70: 52 65 63 6e 6f 2c 20 62 61 73 65 2c 20 30 29 3b  Recno, base, 0);
2f80: 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c  .    for(j=0; j<
2f90: 70 49 64 78 2d 3e 6e 43 6f 6c 75 6d 6e 3b 20 6a  pIdx->nColumn; j
2fa0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  ++){.      int i
2fb0: 64 78 20 3d 20 70 49 64 78 2d 3e 61 69 43 6f 6c  dx = pIdx->aiCol
2fc0: 75 6d 6e 5b 6a 5d 3b 0a 20 20 20 20 20 20 69 66  umn[j];.      if
2fd0: 28 20 69 64 78 3d 3d 70 54 61 62 2d 3e 69 50 4b  ( idx==pTab->iPK
2fe0: 65 79 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71  ey ){.        sq
2ff0: 6c 69 74 65 56 64 62 65 41 64 64 4f 70 28 76 2c  liteVdbeAddOp(v,
3000: 20 4f 50 5f 44 75 70 2c 20 6a 2c 20 30 29 3b 0a   OP_Dup, j, 0);.
3010: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
3020: 20 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41       sqliteVdbeA
3030: 64 64 4f 70 28 76 2c 20 4f 50 5f 43 6f 6c 75 6d  ddOp(v, OP_Colum
3040: 6e 2c 20 62 61 73 65 2c 20 69 64 78 29 3b 0a 20  n, base, idx);. 
3050: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
3060: 20 73 71 6c 69 74 65 56 64 62 65 41 64 64 4f 70   sqliteVdbeAddOp
3070: 28 76 2c 20 4f 50 5f 4d 61 6b 65 49 64 78 4b 65  (v, OP_MakeIdxKe
3080: 79 2c 20 70 49 64 78 2d 3e 6e 43 6f 6c 75 6d 6e  y, pIdx->nColumn
3090: 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 64 62  , 0);.    if( db
30a0: 2d 3e 66 69 6c 65 5f 66 6f 72 6d 61 74 3e 3d 34  ->file_format>=4
30b0: 20 29 20 73 71 6c 69 74 65 41 64 64 49 64 78 4b   ) sqliteAddIdxK
30c0: 65 79 54 79 70 65 28 76 2c 20 70 49 64 78 29 3b  eyType(v, pIdx);
30d0: 0a 20 20 20 20 73 71 6c 69 74 65 56 64 62 65 41  .    sqliteVdbeA
30e0: 64 64 4f 70 28 76 2c 20 4f 50 5f 49 64 78 44 65  ddOp(v, OP_IdxDe
30f0: 6c 65 74 65 2c 20 62 61 73 65 2b 69 2c 20 30 29  lete, base+i, 0)
3100: 3b 0a 20 20 7d 0a 7d 0a                          ;.  }.}.