/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact e1b9c93da828db10c1109c7b4fa611aec8adc407:


0000: 2f 2a 0a 2a 2a 20 32 30 30 38 20 4f 63 74 6f 62  /*.** 2008 Octob
0010: 65 72 20 31 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20  er 10.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u 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 0a 2a 2a 20 54 68 69 73 20 66 69 6c  ****.** This fil
0180: 65 20 63 6f 6e 74 61 69 6e 73 20 43 20 63 6f 64  e contains C cod
0190: 65 20 66 6f 72 20 27 67 65 6e 66 6b 65 79 27 2c  e for 'genfkey',
01a0: 20 61 20 70 72 6f 67 72 61 6d 20 74 6f 20 67 65   a program to ge
01b0: 6e 65 72 61 74 65 20 74 72 69 67 67 65 72 0a 2a  nerate trigger.*
01c0: 2a 20 64 65 66 69 6e 69 74 69 6f 6e 73 20 74 68  * definitions th
01d0: 61 74 20 65 6d 75 6c 61 74 65 20 66 6f 72 65 69  at emulate forei
01e0: 67 6e 20 6b 65 79 73 2e 20 53 65 65 20 67 65 6e  gn keys. See gen
01f0: 66 6b 65 79 2e 52 45 41 44 4d 45 20 66 6f 72 20  fkey.README for 
0200: 64 65 74 61 69 6c 73 2e 0a 2a 2a 0a 2a 2a 20 24  details..**.** $
0210: 49 64 3a 20 67 65 6e 66 6b 65 79 2e 63 2c 76 20  Id: genfkey.c,v 
0220: 31 2e 32 20 32 30 30 38 2f 31 30 2f 31 33 20 31  1.2 2008/10/13 1
0230: 30 3a 35 36 3a 34 38 20 64 61 6e 69 65 6c 6b 31  0:56:48 danielk1
0240: 39 37 37 20 45 78 70 20 24 0a 2a 2f 0a 0a 23 69  977 Exp $.*/..#i
0250: 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 2e  nclude "sqlite3.
0260: 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h".#include <std
0270: 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  io.h>.#include <
0280: 61 73 73 65 72 74 2e 68 3e 0a 23 69 6e 63 6c 75  assert.h>.#inclu
0290: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69  de <stdlib.h>.#i
02a0: 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68  nclude <string.h
02b0: 3e 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  >../************
02c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
02f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a  **************.*
0300: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 53 74  **********.** St
0350: 61 72 74 20 6f 66 20 76 69 72 74 75 61 6c 20 74  art of virtual t
0360: 61 62 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74  able implementat
0370: 69 6f 6e 73 2e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ions..**********
0380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
03c0: 2f 0a 0a 2f 2a 20 54 68 65 20 63 6f 64 65 20 69  /../* The code i
03d0: 6e 20 74 68 69 73 20 66 69 6c 65 20 64 65 66 69  n this file defi
03e0: 6e 65 73 20 61 20 73 71 6c 69 74 65 33 20 76 69  nes a sqlite3 vi
03f0: 72 74 75 61 6c 2d 74 61 62 6c 65 20 6d 6f 64 75  rtual-table modu
0400: 6c 65 20 74 68 61 74 0a 2a 2a 20 70 72 6f 76 69  le that.** provi
0410: 64 65 73 20 61 20 72 65 61 64 2d 6f 6e 6c 79 20  des a read-only 
0420: 76 69 65 77 20 6f 66 20 74 68 65 20 63 75 72 72  view of the curr
0430: 65 6e 74 20 64 61 74 61 62 61 73 65 20 73 63 68  ent database sch
0440: 65 6d 61 2e 20 54 68 65 72 65 20 69 73 20 6f 6e  ema. There is on
0450: 65 0a 2a 2a 20 72 6f 77 20 69 6e 20 74 68 65 20  e.** row in the 
0460: 73 63 68 65 6d 61 20 74 61 62 6c 65 20 66 6f 72  schema table for
0470: 20 65 61 63 68 20 63 6f 6c 75 6d 6e 20 69 6e 20   each column in 
0480: 74 68 65 20 64 61 74 61 62 61 73 65 20 73 63 68  the database sch
0490: 65 6d 61 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ema..*/.#define 
04a0: 53 43 48 45 4d 41 20 5c 0a 22 43 52 45 41 54 45  SCHEMA \."CREATE
04b0: 20 54 41 42 4c 45 20 78 28 22 20 20 20 20 20 20   TABLE x("      
04c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
04f0: 20 20 20 20 20 20 5c 0a 20 20 22 64 61 74 61 62        \.  "datab
0500: 61 73 65 2c 22 20 20 20 20 20 20 20 20 20 20 2f  ase,"          /
0510: 2a 20 4e 61 6d 65 20 6f 66 20 64 61 74 61 62 61  * Name of databa
0520: 73 65 20 28 69 2e 65 2e 20 6d 61 69 6e 2c 20 74  se (i.e. main, t
0530: 65 6d 70 20 65 74 63 2e 29 20 2a 2f 20 20 20 20  emp etc.) */    
0540: 20 20 20 20 20 5c 0a 20 20 22 74 61 62 6c 65 6e       \.  "tablen
0550: 61 6d 65 2c 22 20 20 20 20 20 20 20 20 20 2f 2a  ame,"         /*
0560: 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65 20 2a   Name of table *
0570: 2f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  /               
0580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0590: 20 20 20 20 5c 0a 20 20 22 63 69 64 2c 22 20 20      \.  "cid,"  
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
05b0: 43 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 28 66  Column number (f
05c0: 72 6f 6d 20 6c 65 66 74 2d 74 6f 2d 72 69 67 68  rom left-to-righ
05d0: 74 2c 20 30 20 75 70 77 61 72 64 29 20 2a 2f 20  t, 0 upward) */ 
05e0: 20 20 20 5c 0a 20 20 22 6e 61 6d 65 2c 22 20 20     \.  "name,"  
05f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
0600: 6f 6c 75 6d 6e 20 6e 61 6d 65 20 2a 2f 20 20 20  olumn name */   
0610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0630: 20 20 5c 0a 20 20 22 74 79 70 65 2c 22 20 20 20    \.  "type,"   
0640: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 70             /* Sp
0650: 65 63 69 66 69 65 64 20 74 79 70 65 20 28 69 2e  ecified type (i.
0660: 65 2e 20 56 41 52 43 48 41 52 28 33 32 29 29 20  e. VARCHAR(32)) 
0670: 2a 2f 20 20 20 20 20 20 20 20 20 20 20 20 20 20  */              
0680: 20 5c 0a 20 20 22 6e 6f 74 5f 6e 75 6c 6c 2c 22   \.  "not_null,"
0690: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 6f 6f            /* Boo
06a0: 6c 65 61 6e 2e 20 54 72 75 65 20 69 66 20 4e 4f  lean. True if NO
06b0: 54 20 4e 55 4c 4c 20 77 61 73 20 73 70 65 63 69  T NULL was speci
06c0: 66 69 65 64 20 2a 2f 20 20 20 20 20 20 20 20 20  fied */         
06d0: 5c 0a 20 20 22 64 66 6c 74 5f 76 61 6c 75 65 2c  \.  "dflt_value,
06e0: 22 20 20 20 20 20 20 20 20 2f 2a 20 44 65 66 61  "        /* Defa
06f0: 75 6c 74 20 76 61 6c 75 65 20 66 6f 72 20 74 68  ult value for th
0700: 69 73 20 63 6f 6c 75 6d 6e 20 2a 2f 20 20 20 20  is column */    
0710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
0720: 0a 20 20 22 70 6b 22 20 20 20 20 20 20 20 20 20  .  "pk"         
0730: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
0740: 69 66 20 74 68 69 73 20 63 6f 6c 75 6d 6e 20 69  if this column i
0750: 73 20 70 61 72 74 20 6f 66 20 74 68 65 20 70 72  s part of the pr
0760: 69 6d 61 72 79 20 6b 65 79 20 2a 2f 20 20 5c 0a  imary key */  \.
0770: 22 29 22 0a 0a 23 64 65 66 69 6e 65 20 53 43 48  ")"..#define SCH
0780: 45 4d 41 32 20 5c 0a 22 43 52 45 41 54 45 20 54  EMA2 \."CREATE T
0790: 41 42 4c 45 20 78 28 22 20 20 20 20 20 20 20 20  ABLE x("        
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
07d0: 20 20 20 20 5c 0a 20 20 22 64 61 74 61 62 61 73      \.  "databas
07e0: 65 2c 22 20 20 20 20 20 20 20 20 20 20 2f 2a 20  e,"          /* 
07f0: 4e 61 6d 65 20 6f 66 20 64 61 74 61 62 61 73 65  Name of database
0800: 20 28 69 2e 65 2e 20 6d 61 69 6e 2c 20 74 65 6d   (i.e. main, tem
0810: 70 20 65 74 63 2e 29 20 2a 2f 20 20 20 20 20 20  p etc.) */      
0820: 20 20 20 5c 0a 20 20 22 66 72 6f 6d 5f 74 62 6c     \.  "from_tbl
0830: 2c 22 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ,"          /* N
0840: 61 6d 65 20 6f 66 20 74 61 62 6c 65 20 2a 2f 20  ame of table */ 
0850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0870: 20 20 5c 0a 20 20 22 66 6b 69 64 2c 22 20 20 20    \.  "fkid,"   
0880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08c0: 20 5c 0a 20 20 22 73 65 71 2c 22 20 20 20 20 20   \.  "seq,"     
08d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
08f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0910: 5c 0a 20 20 22 74 6f 5f 74 62 6c 2c 22 20 20 20  \.  "to_tbl,"   
0920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
0960: 0a 20 20 22 66 72 6f 6d 5f 63 6f 6c 2c 22 20 20  .  "from_col,"  
0970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
09b0: 20 20 22 74 6f 5f 63 6f 6c 2c 22 20 20 20 20 20    "to_col,"     
09c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
0a00: 20 22 6f 6e 5f 75 70 64 61 74 65 2c 22 20 20 20   "on_update,"   
0a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a40: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
0a50: 22 6f 6e 5f 64 65 6c 65 74 65 2c 22 20 20 20 20  "on_delete,"    
0a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0a90: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 22             \.  "
0aa0: 6d 61 74 63 68 22 20 20 20 20 20 20 20 20 20 20  match"          
0ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ae0: 20 20 20 20 20 20 20 20 20 20 5c 0a 22 29 22 0a            \.")".
0af0: 0a 23 64 65 66 69 6e 65 20 53 43 48 45 4d 41 33  .#define SCHEMA3
0b00: 20 5c 0a 22 43 52 45 41 54 45 20 54 41 42 4c 45   \."CREATE TABLE
0b10: 20 78 28 22 20 20 20 20 20 20 20 20 20 20 20 20   x("            
0b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b50: 5c 0a 20 20 22 64 61 74 61 62 61 73 65 2c 22 20  \.  "database," 
0b60: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
0b70: 20 6f 66 20 64 61 74 61 62 61 73 65 20 28 69 2e   of database (i.
0b80: 65 2e 20 6d 61 69 6e 2c 20 74 65 6d 70 20 65 74  e. main, temp et
0b90: 63 2e 29 20 2a 2f 20 20 20 20 20 20 20 20 20 5c  c.) */         \
0ba0: 0a 20 20 22 74 61 62 6c 65 6e 61 6d 65 2c 22 20  .  "tablename," 
0bb0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
0bc0: 6f 66 20 74 61 62 6c 65 20 2a 2f 20 20 20 20 20  of table */     
0bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
0bf0: 20 20 22 73 65 71 2c 22 20 20 20 20 20 20 20 20    "seq,"        
0c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
0c40: 20 22 6e 61 6d 65 2c 22 20 20 20 20 20 20 20 20   "name,"        
0c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c80: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20              \.  
0c90: 22 69 73 75 6e 69 71 75 65 22 20 20 20 20 20 20  "isunique"      
0ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0cd0: 20 20 20 20 20 20 20 20 20 20 20 5c 0a 22 29 22             \.")"
0ce0: 0a 0a 23 64 65 66 69 6e 65 20 53 43 48 45 4d 41  ..#define SCHEMA
0cf0: 34 20 5c 0a 22 43 52 45 41 54 45 20 54 41 42 4c  4 \."CREATE TABL
0d00: 45 20 78 28 22 20 20 20 20 20 20 20 20 20 20 20  E x("           
0d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d40: 20 5c 0a 20 20 22 64 61 74 61 62 61 73 65 2c 22   \.  "database,"
0d50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d            /* Nam
0d60: 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 28 69  e of database (i
0d70: 2e 65 2e 20 6d 61 69 6e 2c 20 74 65 6d 70 20 65  .e. main, temp e
0d80: 74 63 2e 29 20 2a 2f 20 20 20 20 20 20 20 20 20  tc.) */         
0d90: 5c 0a 20 20 22 69 6e 64 65 78 6e 61 6d 65 2c 22  \.  "indexname,"
0da0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
0db0: 20 6f 66 20 74 61 62 6c 65 20 2a 2f 20 20 20 20   of table */    
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
0de0: 0a 20 20 22 73 65 71 6e 6f 2c 22 20 20 20 20 20  .  "seqno,"     
0df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
0e30: 20 20 22 63 69 64 2c 22 20 20 20 20 20 20 20 20    "cid,"        
0e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
0e80: 20 22 6e 61 6d 65 22 20 20 20 20 20 20 20 20 20   "name"         
0e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 22 29              \.")
0ed0: 22 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  "..typedef struc
0ee0: 74 20 53 63 68 65 6d 61 54 61 62 6c 65 20 53 63  t SchemaTable Sc
0ef0: 68 65 6d 61 54 61 62 6c 65 3b 0a 73 74 72 75 63  hemaTable;.struc
0f00: 74 20 53 63 68 65 6d 61 54 61 62 6c 65 20 7b 0a  t SchemaTable {.
0f10: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
0f20: 61 6d 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  ame;.  const cha
0f30: 72 20 2a 7a 4f 62 6a 65 63 74 3b 0a 20 20 63 6f  r *zObject;.  co
0f40: 6e 73 74 20 63 68 61 72 20 2a 7a 50 72 61 67 6d  nst char *zPragm
0f50: 61 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  a;.  const char 
0f60: 2a 7a 53 63 68 65 6d 61 3b 0a 7d 20 61 53 63 68  *zSchema;.} aSch
0f70: 65 6d 61 54 61 62 6c 65 5b 5d 20 3d 20 7b 0a 20  emaTable[] = {. 
0f80: 20 7b 20 22 74 61 62 6c 65 5f 69 6e 66 6f 22 2c   { "table_info",
0f90: 20 20 20 20 20 20 20 22 74 61 62 6c 65 22 2c 20         "table", 
0fa0: 22 50 52 41 47 4d 41 20 25 51 2e 74 61 62 6c 65  "PRAGMA %Q.table
0fb0: 5f 69 6e 66 6f 28 25 51 29 22 2c 20 20 20 20 20  _info(%Q)",     
0fc0: 20 20 53 43 48 45 4d 41 20 7d 2c 0a 20 20 7b 20    SCHEMA },.  { 
0fd0: 22 66 6f 72 65 69 67 6e 5f 6b 65 79 5f 6c 69 73  "foreign_key_lis
0fe0: 74 22 2c 20 22 74 61 62 6c 65 22 2c 20 22 50 52  t", "table", "PR
0ff0: 41 47 4d 41 20 25 51 2e 66 6f 72 65 69 67 6e 5f  AGMA %Q.foreign_
1000: 6b 65 79 5f 6c 69 73 74 28 25 51 29 22 2c 20 53  key_list(%Q)", S
1010: 43 48 45 4d 41 32 20 7d 2c 0a 20 20 7b 20 22 69  CHEMA2 },.  { "i
1020: 6e 64 65 78 5f 6c 69 73 74 22 2c 20 20 20 20 20  ndex_list",     
1030: 20 20 22 74 61 62 6c 65 22 2c 20 22 50 52 41 47    "table", "PRAG
1040: 4d 41 20 25 51 2e 69 6e 64 65 78 5f 6c 69 73 74  MA %Q.index_list
1050: 28 25 51 29 22 2c 20 20 20 20 20 20 20 53 43 48  (%Q)",       SCH
1060: 45 4d 41 33 20 7d 2c 0a 20 20 7b 20 22 69 6e 64  EMA3 },.  { "ind
1070: 65 78 5f 69 6e 66 6f 22 2c 20 20 20 20 20 20 20  ex_info",       
1080: 22 69 6e 64 65 78 22 2c 20 22 50 52 41 47 4d 41  "index", "PRAGMA
1090: 20 25 51 2e 69 6e 64 65 78 5f 69 6e 66 6f 28 25   %Q.index_info(%
10a0: 51 29 22 2c 20 20 20 20 20 20 20 53 43 48 45 4d  Q)",       SCHEM
10b0: 41 34 20 7d 2c 0a 20 20 7b 20 30 2c 20 30 2c 20  A4 },.  { 0, 0, 
10c0: 30 2c 20 30 20 7d 0a 7d 3b 0a 0a 74 79 70 65 64  0, 0 }.};..typed
10d0: 65 66 20 73 74 72 75 63 74 20 73 63 68 65 6d 61  ef struct schema
10e0: 5f 76 74 61 62 20 73 63 68 65 6d 61 5f 76 74 61  _vtab schema_vta
10f0: 62 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  b;.typedef struc
1100: 74 20 73 63 68 65 6d 61 5f 63 75 72 73 6f 72 20  t schema_cursor 
1110: 73 63 68 65 6d 61 5f 63 75 72 73 6f 72 3b 0a 0a  schema_cursor;..
1120: 2f 2a 20 41 20 73 63 68 65 6d 61 20 74 61 62 6c  /* A schema tabl
1130: 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 73 74 72 75  e object */.stru
1140: 63 74 20 73 63 68 65 6d 61 5f 76 74 61 62 20 7b  ct schema_vtab {
1150: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
1160: 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 20  base;.  sqlite3 
1170: 2a 64 62 3b 0a 20 20 53 63 68 65 6d 61 54 61 62  *db;.  SchemaTab
1180: 6c 65 20 2a 70 54 79 70 65 3b 0a 7d 3b 0a 0a 2f  le *pType;.};../
1190: 2a 20 41 20 73 63 68 65 6d 61 20 74 61 62 6c 65  * A schema table
11a0: 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 20 2a   cursor object *
11b0: 2f 0a 73 74 72 75 63 74 20 73 63 68 65 6d 61 5f  /.struct schema_
11c0: 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74  cursor {.  sqlit
11d0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 62  e3_vtab_cursor b
11e0: 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  ase;.  sqlite3_s
11f0: 74 6d 74 20 2a 70 44 62 4c 69 73 74 3b 0a 20 20  tmt *pDbList;.  
1200: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 54  sqlite3_stmt *pT
1210: 61 62 6c 65 4c 69 73 74 3b 0a 20 20 73 71 6c 69  ableList;.  sqli
1220: 74 65 33 5f 73 74 6d 74 20 2a 70 43 6f 6c 75 6d  te3_stmt *pColum
1230: 6e 4c 69 73 74 3b 0a 20 20 69 6e 74 20 72 6f 77  nList;.  int row
1240: 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 61  id;.};../*.** Ta
1250: 62 6c 65 20 64 65 73 74 72 75 63 74 6f 72 20 66  ble destructor f
1260: 6f 72 20 74 68 65 20 73 63 68 65 6d 61 20 6d 6f  or the schema mo
1270: 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  dule..*/.static 
1280: 69 6e 74 20 73 63 68 65 6d 61 44 65 73 74 72 6f  int schemaDestro
1290: 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  y(sqlite3_vtab *
12a0: 70 56 74 61 62 29 7b 0a 20 20 73 71 6c 69 74 65  pVtab){.  sqlite
12b0: 33 5f 66 72 65 65 28 70 56 74 61 62 29 3b 0a 20  3_free(pVtab);. 
12c0: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a   return 0;.}../*
12d0: 0a 2a 2a 20 54 61 62 6c 65 20 63 6f 6e 73 74 72  .** Table constr
12e0: 75 63 74 6f 72 20 66 6f 72 20 74 68 65 20 73 63  uctor for the sc
12f0: 68 65 6d 61 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a  hema module..*/.
1300: 73 74 61 74 69 63 20 69 6e 74 20 73 63 68 65 6d  static int schem
1310: 61 43 72 65 61 74 65 28 0a 20 20 73 71 6c 69 74  aCreate(.  sqlit
1320: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
1330: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
1340: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  , const char *co
1350: 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69  nst*argv,.  sqli
1360: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
1370: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  b,.  char **pzEr
1380: 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  r.){.  int rc = 
1390: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
13a0: 73 63 68 65 6d 61 5f 76 74 61 62 20 2a 70 56 74  schema_vtab *pVt
13b0: 61 62 3b 0a 20 20 53 63 68 65 6d 61 54 61 62 6c  ab;.  SchemaTabl
13c0: 65 20 2a 70 54 79 70 65 20 3d 20 26 61 53 63 68  e *pType = &aSch
13d0: 65 6d 61 54 61 62 6c 65 5b 30 5d 3b 0a 0a 20 20  emaTable[0];..  
13e0: 69 66 28 20 61 72 67 63 3e 33 20 29 7b 0a 20 20  if( argc>3 ){.  
13f0: 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 70 54 79    int i;.    pTy
1400: 70 65 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  pe = 0;.    for(
1410: 69 3d 30 3b 20 61 53 63 68 65 6d 61 54 61 62 6c  i=0; aSchemaTabl
1420: 65 5b 69 5d 2e 7a 4e 61 6d 65 3b 20 69 2b 2b 29  e[i].zName; i++)
1430: 7b 20 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d  { .      if( 0==
1440: 73 74 72 63 6d 70 28 61 72 67 76 5b 33 5d 2c 20  strcmp(argv[3], 
1450: 61 53 63 68 65 6d 61 54 61 62 6c 65 5b 69 5d 2e  aSchemaTable[i].
1460: 7a 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20  zName) ){.      
1470: 20 20 70 54 79 70 65 20 3d 20 26 61 53 63 68 65    pType = &aSche
1480: 6d 61 54 61 62 6c 65 5b 69 5d 3b 0a 20 20 20 20  maTable[i];.    
1490: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
14a0: 28 20 21 70 54 79 70 65 20 29 7b 0a 20 20 20 20  ( !pType ){.    
14b0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
14c0: 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d  ERROR;.    }.  }
14d0: 0a 0a 20 20 70 56 74 61 62 20 3d 20 73 71 6c 69  ..  pVtab = sqli
14e0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
14f0: 66 28 73 63 68 65 6d 61 5f 76 74 61 62 29 29 3b  f(schema_vtab));
1500: 0a 20 20 69 66 28 20 70 56 74 61 62 20 29 7b 0a  .  if( pVtab ){.
1510: 20 20 20 20 6d 65 6d 73 65 74 28 70 56 74 61 62      memset(pVtab
1520: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 63 68 65  , 0, sizeof(sche
1530: 6d 61 5f 76 74 61 62 29 29 3b 0a 20 20 20 20 70  ma_vtab));.    p
1540: 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a 20  Vtab->db = db;. 
1550: 20 20 20 70 56 74 61 62 2d 3e 70 54 79 70 65 20     pVtab->pType 
1560: 3d 20 70 54 79 70 65 3b 0a 20 20 20 20 72 63 20  = pType;.    rc 
1570: 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  = sqlite3_declar
1580: 65 5f 76 74 61 62 28 64 62 2c 20 70 54 79 70 65  e_vtab(db, pType
1590: 2d 3e 7a 53 63 68 65 6d 61 29 3b 0a 20 20 7d 0a  ->zSchema);.  }.
15a0: 20 20 2a 70 70 56 74 61 62 20 3d 20 28 73 71 6c    *ppVtab = (sql
15b0: 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61  ite3_vtab *)pVta
15c0: 62 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  b;.  return rc;.
15d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20  }../*.** Open a 
15e0: 6e 65 77 20 63 75 72 73 6f 72 20 6f 6e 20 74 68  new cursor on th
15f0: 65 20 73 63 68 65 6d 61 20 74 61 62 6c 65 2e 0a  e schema table..
1600: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 63  */.static int sc
1610: 68 65 6d 61 4f 70 65 6e 28 73 71 6c 69 74 65 33  hemaOpen(sqlite3
1620: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71  _vtab *pVTab, sq
1630: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1640: 72 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20  r **ppCursor){. 
1650: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
1660: 5f 4e 4f 4d 45 4d 3b 0a 20 20 73 63 68 65 6d 61  _NOMEM;.  schema
1670: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20  _cursor *pCur;. 
1680: 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33 5f   pCur = sqlite3_
1690: 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73 63  malloc(sizeof(sc
16a0: 68 65 6d 61 5f 63 75 72 73 6f 72 29 29 3b 0a 20  hema_cursor));. 
16b0: 20 69 66 28 20 70 43 75 72 20 29 7b 0a 20 20 20   if( pCur ){.   
16c0: 20 6d 65 6d 73 65 74 28 70 43 75 72 2c 20 30 2c   memset(pCur, 0,
16d0: 20 73 69 7a 65 6f 66 28 73 63 68 65 6d 61 5f 63   sizeof(schema_c
16e0: 75 72 73 6f 72 29 29 3b 0a 20 20 20 20 2a 70 70  ursor));.    *pp
16f0: 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74 65  Cursor = (sqlite
1700: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 29  3_vtab_cursor *)
1710: 70 43 75 72 3b 0a 20 20 20 20 72 63 20 3d 20 53  pCur;.    rc = S
1720: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20  QLITE_OK;.  }.  
1730: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1740: 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 73 63 68 65  .** Close a sche
1750: 6d 61 20 74 61 62 6c 65 20 63 75 72 73 6f 72 2e  ma table cursor.
1760: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73  .*/.static int s
1770: 63 68 65 6d 61 43 6c 6f 73 65 28 73 71 6c 69 74  chemaClose(sqlit
1780: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
1790: 63 75 72 29 7b 0a 20 20 73 63 68 65 6d 61 5f 63  cur){.  schema_c
17a0: 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 73  ursor *pCur = (s
17b0: 63 68 65 6d 61 5f 63 75 72 73 6f 72 20 2a 29 63  chema_cursor *)c
17c0: 75 72 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  ur;.  sqlite3_fi
17d0: 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 44 62  nalize(pCur->pDb
17e0: 4c 69 73 74 29 3b 0a 20 20 73 71 6c 69 74 65 33  List);.  sqlite3
17f0: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e  _finalize(pCur->
1800: 70 54 61 62 6c 65 4c 69 73 74 29 3b 0a 20 20 73  pTableList);.  s
1810: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
1820: 70 43 75 72 2d 3e 70 43 6f 6c 75 6d 6e 4c 69 73  pCur->pColumnLis
1830: 74 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  t);.  sqlite3_fr
1840: 65 65 28 70 43 75 72 29 3b 0a 20 20 72 65 74 75  ee(pCur);.  retu
1850: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
1860: 0a 2f 2a 0a 2a 2a 20 52 65 74 72 69 65 76 65 20  ./*.** Retrieve 
1870: 61 20 63 6f 6c 75 6d 6e 20 6f 66 20 64 61 74 61  a column of data
1880: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1890: 73 63 68 65 6d 61 43 6f 6c 75 6d 6e 28 73 71 6c  schemaColumn(sql
18a0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
18b0: 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 33 5f 63   *cur, sqlite3_c
18c0: 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20 69 6e 74  ontext *ctx, int
18d0: 20 69 29 7b 0a 20 20 73 63 68 65 6d 61 5f 63 75   i){.  schema_cu
18e0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 73 63  rsor *pCur = (sc
18f0: 68 65 6d 61 5f 63 75 72 73 6f 72 20 2a 29 63 75  hema_cursor *)cu
1900: 72 3b 0a 20 20 73 77 69 74 63 68 28 20 69 20 29  r;.  switch( i )
1910: 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 0a 20 20  {.    case 0:.  
1920: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
1930: 6c 74 5f 76 61 6c 75 65 28 63 74 78 2c 20 73 71  lt_value(ctx, sq
1940: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c  lite3_column_val
1950: 75 65 28 70 43 75 72 2d 3e 70 44 62 4c 69 73 74  ue(pCur->pDbList
1960: 2c 20 31 29 29 3b 0a 20 20 20 20 20 20 62 72 65  , 1));.      bre
1970: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 31 3a 0a  ak;.    case 1:.
1980: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
1990: 73 75 6c 74 5f 76 61 6c 75 65 28 63 74 78 2c 20  sult_value(ctx, 
19a0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
19b0: 61 6c 75 65 28 70 43 75 72 2d 3e 70 54 61 62 6c  alue(pCur->pTabl
19c0: 65 4c 69 73 74 2c 20 30 29 29 3b 0a 20 20 20 20  eList, 0));.    
19d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 64 65 66    break;.    def
19e0: 61 75 6c 74 3a 0a 20 20 20 20 20 20 73 71 6c 69  ault:.      sqli
19f0: 74 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65  te3_result_value
1a00: 28 63 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f  (ctx, sqlite3_co
1a10: 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43 75 72 2d  lumn_value(pCur-
1a20: 3e 70 43 6f 6c 75 6d 6e 4c 69 73 74 2c 20 69 2d  >pColumnList, i-
1a30: 32 29 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  2));.      break
1a40: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
1a50: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
1a60: 2a 2a 20 52 65 74 72 69 65 76 65 20 74 68 65 20  ** Retrieve the 
1a70: 63 75 72 72 65 6e 74 20 72 6f 77 69 64 2e 0a 2a  current rowid..*
1a80: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 63 68  /.static int sch
1a90: 65 6d 61 52 6f 77 69 64 28 73 71 6c 69 74 65 33  emaRowid(sqlite3
1aa0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
1ab0: 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  r, sqlite_int64 
1ac0: 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 63 68 65  *pRowid){.  sche
1ad0: 6d 61 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20  ma_cursor *pCur 
1ae0: 3d 20 28 73 63 68 65 6d 61 5f 63 75 72 73 6f 72  = (schema_cursor
1af0: 20 2a 29 63 75 72 3b 0a 20 20 2a 70 52 6f 77 69   *)cur;.  *pRowi
1b00: 64 20 3d 20 70 43 75 72 2d 3e 72 6f 77 69 64 3b  d = pCur->rowid;
1b10: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
1b20: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  _OK;.}..static i
1b30: 6e 74 20 66 69 6e 61 6c 69 7a 65 28 73 71 6c 69  nt finalize(sqli
1b40: 74 65 33 5f 73 74 6d 74 20 2a 2a 70 70 53 74 6d  te3_stmt **ppStm
1b50: 74 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73  t){.  int rc = s
1b60: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
1b70: 2a 70 70 53 74 6d 74 29 3b 0a 20 20 2a 70 70 53  *ppStmt);.  *ppS
1b80: 74 6d 74 20 3d 20 30 3b 0a 20 20 72 65 74 75 72  tmt = 0;.  retur
1b90: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
1ba0: 69 6e 74 20 73 63 68 65 6d 61 45 6f 66 28 73 71  int schemaEof(sq
1bb0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1bc0: 72 20 2a 63 75 72 29 7b 0a 20 20 73 63 68 65 6d  r *cur){.  schem
1bd0: 61 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  a_cursor *pCur =
1be0: 20 28 73 63 68 65 6d 61 5f 63 75 72 73 6f 72 20   (schema_cursor 
1bf0: 2a 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e 20  *)cur;.  return 
1c00: 28 70 43 75 72 2d 3e 70 44 62 4c 69 73 74 20 3f  (pCur->pDbList ?
1c10: 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a   0 : 1);.}../*.*
1c20: 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 63 75  * Advance the cu
1c30: 72 73 6f 72 20 74 6f 20 74 68 65 20 6e 65 78 74  rsor to the next
1c40: 20 72 6f 77 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   row..*/.static 
1c50: 69 6e 74 20 73 63 68 65 6d 61 4e 65 78 74 28 73  int schemaNext(s
1c60: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
1c70: 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20  or *cur){.  int 
1c80: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
1c90: 20 20 73 63 68 65 6d 61 5f 63 75 72 73 6f 72 20    schema_cursor 
1ca0: 2a 70 43 75 72 20 3d 20 28 73 63 68 65 6d 61 5f  *pCur = (schema_
1cb0: 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20  cursor *)cur;.  
1cc0: 73 63 68 65 6d 61 5f 76 74 61 62 20 2a 70 56 74  schema_vtab *pVt
1cd0: 61 62 20 3d 20 28 73 63 68 65 6d 61 5f 76 74 61  ab = (schema_vta
1ce0: 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61 62 29  b *)(cur->pVtab)
1cf0: 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d  ;.  char *zSql =
1d00: 20 30 3b 0a 0a 20 20 77 68 69 6c 65 28 20 21 70   0;..  while( !p
1d10: 43 75 72 2d 3e 70 43 6f 6c 75 6d 6e 4c 69 73 74  Cur->pColumnList
1d20: 20 7c 7c 20 53 51 4c 49 54 45 5f 52 4f 57 21 3d   || SQLITE_ROW!=
1d30: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 43 75  sqlite3_step(pCu
1d40: 72 2d 3e 70 43 6f 6c 75 6d 6e 4c 69 73 74 29 20  r->pColumnList) 
1d50: 29 7b 0a 20 20 20 20 69 66 28 20 53 51 4c 49 54  ){.    if( SQLIT
1d60: 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 66 69 6e 61  E_OK!=(rc = fina
1d70: 6c 69 7a 65 28 26 70 43 75 72 2d 3e 70 43 6f 6c  lize(&pCur->pCol
1d80: 75 6d 6e 4c 69 73 74 29 29 20 29 20 67 6f 74 6f  umnList)) ) goto
1d90: 20 6e 65 78 74 5f 65 78 69 74 3b 0a 0a 20 20 20   next_exit;..   
1da0: 20 77 68 69 6c 65 28 20 21 70 43 75 72 2d 3e 70   while( !pCur->p
1db0: 54 61 62 6c 65 4c 69 73 74 20 7c 7c 20 53 51 4c  TableList || SQL
1dc0: 49 54 45 5f 52 4f 57 21 3d 73 71 6c 69 74 65 33  ITE_ROW!=sqlite3
1dd0: 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 54 61 62  _step(pCur->pTab
1de0: 6c 65 4c 69 73 74 29 20 29 7b 0a 20 20 20 20 20  leList) ){.     
1df0: 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d   if( SQLITE_OK!=
1e00: 28 72 63 20 3d 20 66 69 6e 61 6c 69 7a 65 28 26  (rc = finalize(&
1e10: 70 43 75 72 2d 3e 70 54 61 62 6c 65 4c 69 73 74  pCur->pTableList
1e20: 29 29 20 29 20 67 6f 74 6f 20 6e 65 78 74 5f 65  )) ) goto next_e
1e30: 78 69 74 3b 0a 0a 20 20 20 20 20 20 61 73 73 65  xit;..      asse
1e40: 72 74 28 70 43 75 72 2d 3e 70 44 62 4c 69 73 74  rt(pCur->pDbList
1e50: 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  );.      while( 
1e60: 53 51 4c 49 54 45 5f 52 4f 57 21 3d 73 71 6c 69  SQLITE_ROW!=sqli
1e70: 74 65 33 5f 73 74 65 70 28 70 43 75 72 2d 3e 70  te3_step(pCur->p
1e80: 44 62 4c 69 73 74 29 20 29 7b 0a 20 20 20 20 20  DbList) ){.     
1e90: 20 20 20 72 63 20 3d 20 66 69 6e 61 6c 69 7a 65     rc = finalize
1ea0: 28 26 70 43 75 72 2d 3e 70 44 62 4c 69 73 74 29  (&pCur->pDbList)
1eb0: 3b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6e  ;.        goto n
1ec0: 65 78 74 5f 65 78 69 74 3b 0a 20 20 20 20 20 20  ext_exit;.      
1ed0: 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 53 65 74 20  }..      /* Set 
1ee0: 7a 53 71 6c 20 74 6f 20 74 68 65 20 53 51 4c 20  zSql to the SQL 
1ef0: 74 6f 20 70 75 6c 6c 20 74 68 65 20 6c 69 73 74  to pull the list
1f00: 20 6f 66 20 74 61 62 6c 65 73 20 66 72 6f 6d 20   of tables from 
1f10: 74 68 65 20 0a 20 20 20 20 20 20 2a 2a 20 73 71  the .      ** sq
1f20: 6c 69 74 65 5f 6d 61 73 74 65 72 20 28 6f 72 20  lite_master (or 
1f30: 73 71 6c 69 74 65 5f 74 65 6d 70 5f 6d 61 73 74  sqlite_temp_mast
1f40: 65 72 29 20 74 61 62 6c 65 20 6f 66 20 74 68 65  er) table of the
1f50: 20 64 61 74 61 62 61 73 65 0a 20 20 20 20 20 20   database.      
1f60: 2a 2a 20 69 64 65 6e 74 66 69 65 64 20 62 79 20  ** identfied by 
1f70: 74 68 65 20 72 6f 77 20 70 6f 69 6e 74 65 64 20  the row pointed 
1f80: 74 6f 20 62 79 20 74 68 65 20 53 51 4c 20 73 74  to by the SQL st
1f90: 61 74 65 6d 65 6e 74 20 70 43 75 72 2d 3e 70 44  atement pCur->pD
1fa0: 62 4c 69 73 74 0a 20 20 20 20 20 20 2a 2a 20 28  bList.      ** (
1fb0: 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67  iterating throug
1fc0: 68 20 61 20 22 50 52 41 47 4d 41 20 64 61 74 61  h a "PRAGMA data
1fd0: 62 61 73 65 5f 6c 69 73 74 3b 22 20 73 74 61 74  base_list;" stat
1fe0: 65 6d 65 6e 74 29 2e 0a 20 20 20 20 20 20 2a 2f  ement)..      */
1ff0: 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74  .      if( sqlit
2000: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 43  e3_column_int(pC
2010: 75 72 2d 3e 70 44 62 4c 69 73 74 2c 20 30 29 3d  ur->pDbList, 0)=
2020: 3d 31 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 53  =1 ){.        zS
2030: 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ql = sqlite3_mpr
2040: 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20  intf(.          
2050: 20 20 22 53 45 4c 45 43 54 20 6e 61 6d 65 20 46    "SELECT name F
2060: 52 4f 4d 20 73 71 6c 69 74 65 5f 74 65 6d 70 5f  ROM sqlite_temp_
2070: 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79 70  master WHERE typ
2080: 65 3d 25 51 22 2c 0a 20 20 20 20 20 20 20 20 20  e=%Q",.         
2090: 20 20 20 70 56 74 61 62 2d 3e 70 54 79 70 65 2d     pVtab->pType-
20a0: 3e 7a 4f 62 6a 65 63 74 0a 20 20 20 20 20 20 20  >zObject.       
20b0: 20 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   );.      }else{
20c0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
20d0: 5f 73 74 6d 74 20 2a 70 44 62 4c 69 73 74 20 3d  _stmt *pDbList =
20e0: 20 70 43 75 72 2d 3e 70 44 62 4c 69 73 74 3b 0a   pCur->pDbList;.
20f0: 20 20 20 20 20 20 20 20 7a 53 71 6c 20 3d 20 73          zSql = s
2100: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a  qlite3_mprintf(.
2110: 20 20 20 20 20 20 20 20 20 20 20 20 22 53 45 4c              "SEL
2120: 45 43 54 20 6e 61 6d 65 20 46 52 4f 4d 20 25 51  ECT name FROM %Q
2130: 2e 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57  .sqlite_master W
2140: 48 45 52 45 20 74 79 70 65 3d 25 51 22 2c 0a 20  HERE type=%Q",. 
2150: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
2160: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
2170: 70 44 62 4c 69 73 74 2c 20 31 29 2c 20 70 56 74  pDbList, 1), pVt
2180: 61 62 2d 3e 70 54 79 70 65 2d 3e 7a 4f 62 6a 65  ab->pType->zObje
2190: 63 74 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  ct.        );.  
21a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
21b0: 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 20 20 20  !zSql ){.       
21c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
21d0: 45 4d 3b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f  EM;.        goto
21e0: 20 6e 65 78 74 5f 65 78 69 74 3b 0a 20 20 20 20   next_exit;.    
21f0: 20 20 7d 0a 0a 20 20 20 20 20 20 72 63 20 3d 20    }..      rc = 
2200: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28  sqlite3_prepare(
2210: 70 56 74 61 62 2d 3e 64 62 2c 20 7a 53 71 6c 2c  pVtab->db, zSql,
2220: 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70 54 61 62   -1, &pCur->pTab
2230: 6c 65 4c 69 73 74 2c 20 30 29 3b 0a 20 20 20 20  leList, 0);.    
2240: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
2250: 53 71 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20  Sql);.      if( 
2260: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
2270: 67 6f 74 6f 20 6e 65 78 74 5f 65 78 69 74 3b 0a  goto next_exit;.
2280: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 53 65      }..    /* Se
2290: 74 20 7a 53 71 6c 20 74 6f 20 74 68 65 20 53 51  t zSql to the SQ
22a0: 4c 20 74 6f 20 74 68 65 20 74 61 62 6c 65 5f 69  L to the table_i
22b0: 6e 66 6f 20 70 72 61 67 6d 61 20 66 6f 72 20 74  nfo pragma for t
22c0: 68 65 20 74 61 62 6c 65 20 63 75 72 72 65 6e 74  he table current
22d0: 6c 79 0a 20 20 20 20 2a 2a 20 69 64 65 6e 74 69  ly.    ** identi
22e0: 66 69 65 64 20 62 79 20 74 68 65 20 72 6f 77 73  fied by the rows
22f0: 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 73   pointed to by s
2300: 74 61 74 65 6d 65 6e 74 73 20 70 43 75 72 2d 3e  tatements pCur->
2310: 70 44 62 4c 69 73 74 20 61 6e 64 0a 20 20 20 20  pDbList and.    
2320: 2a 2a 20 70 43 75 72 2d 3e 70 54 61 62 6c 65 4c  ** pCur->pTableL
2330: 69 73 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ist..    */.    
2340: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zSql = sqlite3_m
2350: 70 72 69 6e 74 66 28 70 56 74 61 62 2d 3e 70 54  printf(pVtab->pT
2360: 79 70 65 2d 3e 7a 50 72 61 67 6d 61 2c 0a 20 20  ype->zPragma,.  
2370: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 63 6f        sqlite3_co
2380: 6c 75 6d 6e 5f 74 65 78 74 28 70 43 75 72 2d 3e  lumn_text(pCur->
2390: 70 44 62 4c 69 73 74 2c 20 31 29 2c 0a 20 20 20  pDbList, 1),.   
23a0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 63 6f 6c       sqlite3_col
23b0: 75 6d 6e 5f 74 65 78 74 28 70 43 75 72 2d 3e 70  umn_text(pCur->p
23c0: 54 61 62 6c 65 4c 69 73 74 2c 20 30 29 0a 20 20  TableList, 0).  
23d0: 20 20 29 3b 0a 0a 20 20 20 20 69 66 28 20 21 7a    );..    if( !z
23e0: 53 71 6c 20 29 7b 0a 20 20 20 20 20 20 72 63 20  Sql ){.      rc 
23f0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
2400: 20 20 20 20 20 20 67 6f 74 6f 20 6e 65 78 74 5f        goto next_
2410: 65 78 69 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20  exit;.    }.    
2420: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
2430: 70 61 72 65 28 70 56 74 61 62 2d 3e 64 62 2c 20  pare(pVtab->db, 
2440: 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 43 75 72 2d  zSql, -1, &pCur-
2450: 3e 70 43 6f 6c 75 6d 6e 4c 69 73 74 2c 20 30 29  >pColumnList, 0)
2460: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
2470: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66  ee(zSql);.    if
2480: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
2490: 29 20 67 6f 74 6f 20 6e 65 78 74 5f 65 78 69 74  ) goto next_exit
24a0: 3b 0a 20 20 7d 0a 20 20 70 43 75 72 2d 3e 72 6f  ;.  }.  pCur->ro
24b0: 77 69 64 2b 2b 3b 0a 0a 6e 65 78 74 5f 65 78 69  wid++;..next_exi
24c0: 74 3a 0a 20 20 2f 2a 20 54 4f 44 4f 3a 20 48 61  t:.  /* TODO: Ha
24d0: 6e 64 6c 65 20 72 63 20 2a 2f 0a 20 20 72 65 74  ndle rc */.  ret
24e0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
24f0: 20 52 65 73 65 74 20 61 20 73 63 68 65 6d 61 20   Reset a schema 
2500: 74 61 62 6c 65 20 63 75 72 73 6f 72 2e 0a 2a 2f  table cursor..*/
2510: 0a 73 74 61 74 69 63 20 69 6e 74 20 73 63 68 65  .static int sche
2520: 6d 61 46 69 6c 74 65 72 28 0a 20 20 73 71 6c 69  maFilter(.  sqli
2530: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
2540: 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20 0a 20  *pVtabCursor, . 
2550: 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e   int idxNum, con
2560: 73 74 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c  st char *idxStr,
2570: 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c  .  int argc, sql
2580: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67  ite3_value **arg
2590: 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  v.){.  int rc;. 
25a0: 20 73 63 68 65 6d 61 5f 76 74 61 62 20 2a 70 56   schema_vtab *pV
25b0: 74 61 62 20 3d 20 28 73 63 68 65 6d 61 5f 76 74  tab = (schema_vt
25c0: 61 62 20 2a 29 28 70 56 74 61 62 43 75 72 73 6f  ab *)(pVtabCurso
25d0: 72 2d 3e 70 56 74 61 62 29 3b 0a 20 20 73 63 68  r->pVtab);.  sch
25e0: 65 6d 61 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  ema_cursor *pCur
25f0: 20 3d 20 28 73 63 68 65 6d 61 5f 63 75 72 73 6f   = (schema_curso
2600: 72 20 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b  r *)pVtabCursor;
2610: 0a 20 20 70 43 75 72 2d 3e 72 6f 77 69 64 20 3d  .  pCur->rowid =
2620: 20 30 3b 0a 20 20 66 69 6e 61 6c 69 7a 65 28 26   0;.  finalize(&
2630: 70 43 75 72 2d 3e 70 54 61 62 6c 65 4c 69 73 74  pCur->pTableList
2640: 29 3b 0a 20 20 66 69 6e 61 6c 69 7a 65 28 26 70  );.  finalize(&p
2650: 43 75 72 2d 3e 70 43 6f 6c 75 6d 6e 4c 69 73 74  Cur->pColumnList
2660: 29 3b 0a 20 20 66 69 6e 61 6c 69 7a 65 28 26 70  );.  finalize(&p
2670: 43 75 72 2d 3e 70 44 62 4c 69 73 74 29 3b 0a 20  Cur->pDbList);. 
2680: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
2690: 65 70 61 72 65 28 70 56 74 61 62 2d 3e 64 62 2c  epare(pVtab->db,
26a0: 22 53 45 4c 45 43 54 20 30 2c 20 27 6d 61 69 6e  "SELECT 0, 'main
26b0: 27 22 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70  '", -1, &pCur->p
26c0: 44 62 4c 69 73 74 2c 20 30 29 3b 0a 20 20 72 65  DbList, 0);.  re
26d0: 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45  turn (rc==SQLITE
26e0: 5f 4f 4b 20 3f 20 73 63 68 65 6d 61 4e 65 78 74  _OK ? schemaNext
26f0: 28 70 56 74 61 62 43 75 72 73 6f 72 29 20 3a 20  (pVtabCursor) : 
2700: 72 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6e  rc);.}../*.** An
2710: 61 6c 79 73 65 20 74 68 65 20 57 48 45 52 45 20  alyse the WHERE 
2720: 63 6f 6e 64 69 74 69 6f 6e 2e 0a 2a 2f 0a 73 74  condition..*/.st
2730: 61 74 69 63 20 69 6e 74 20 73 63 68 65 6d 61 42  atic int schemaB
2740: 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65 33  estIndex(sqlite3
2750: 5f 76 74 61 62 20 2a 74 61 62 2c 20 73 71 6c 69  _vtab *tab, sqli
2760: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a  te3_index_info *
2770: 70 49 64 78 49 6e 66 6f 29 7b 0a 20 20 72 65 74  pIdxInfo){.  ret
2780: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2790: 0a 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61  ../*.** A virtua
27a0: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74  l table module t
27b0: 68 61 74 20 6d 65 72 65 6c 79 20 65 63 68 6f 73  hat merely echos
27c0: 20 6d 65 74 68 6f 64 20 63 61 6c 6c 73 20 69 6e   method calls in
27d0: 74 6f 20 54 43 4c 0a 2a 2a 20 76 61 72 69 61 62  to TCL.** variab
27e0: 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  les..*/.static s
27f0: 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 73 63  qlite3_module sc
2800: 68 65 6d 61 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20  hemaModule = {. 
2810: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
2820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2830: 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 73   iVersion */.  s
2840: 63 68 65 6d 61 43 72 65 61 74 65 2c 0a 20 20 73  chemaCreate,.  s
2850: 63 68 65 6d 61 43 72 65 61 74 65 2c 0a 20 20 73  chemaCreate,.  s
2860: 63 68 65 6d 61 42 65 73 74 49 6e 64 65 78 2c 0a  chemaBestIndex,.
2870: 20 20 73 63 68 65 6d 61 44 65 73 74 72 6f 79 2c    schemaDestroy,
2880: 0a 20 20 73 63 68 65 6d 61 44 65 73 74 72 6f 79  .  schemaDestroy
2890: 2c 0a 20 20 73 63 68 65 6d 61 4f 70 65 6e 2c 20  ,.  schemaOpen, 
28a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28b0: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
28c0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 73   a cursor */.  s
28d0: 63 68 65 6d 61 43 6c 6f 73 65 2c 20 20 20 20 20  chemaClose,     
28e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
28f0: 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20  Close - close a 
2900: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 73 63 68 65  cursor */.  sche
2910: 6d 61 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20  maFilter,       
2920: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c           /* xFil
2930: 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20  ter - configure 
2940: 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73  scan constraints
2950: 20 2a 2f 0a 20 20 73 63 68 65 6d 61 4e 65 78 74   */.  schemaNext
2960: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2970: 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64     /* xNext - ad
2980: 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a  vance a cursor *
2990: 2f 0a 20 20 73 63 68 65 6d 61 45 6f 66 2c 20 20  /.  schemaEof,  
29a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
29b0: 20 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 73 63   /* xEof */.  sc
29c0: 68 65 6d 61 43 6f 6c 75 6d 6e 2c 20 20 20 20 20  hemaColumn,     
29d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
29e0: 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74  olumn - read dat
29f0: 61 20 2a 2f 0a 20 20 73 63 68 65 6d 61 52 6f 77  a */.  schemaRow
2a00: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  id,             
2a10: 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20      /* xRowid - 
2a20: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 30  read data */.  0
2a30: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2a40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2a50: 55 70 64 61 74 65 20 2a 2f 0a 20 20 30 2c 20 20  Update */.  0,  
2a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2a70: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
2a80: 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  in */.  0,      
2a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2aa0: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f       /* xSync */
2ab0: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
2ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ad0: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20  /* xCommit */.  
2ae0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
2af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2b00: 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 30  xRollback */.  0
2b10: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
2b20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2b30: 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20 20  FindMethod */.  
2b40: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
2b50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2b60: 78 52 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a 2f  xRename */.};../
2b70: 2a 0a 2a 2a 20 45 78 74 65 6e 73 69 6f 6e 20 6c  *.** Extension l
2b80: 6f 61 64 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f  oad function..*/
2b90: 0a 73 74 61 74 69 63 20 69 6e 74 20 69 6e 73 74  .static int inst
2ba0: 61 6c 6c 53 63 68 65 6d 61 4d 6f 64 75 6c 65 28  allSchemaModule(
2bb0: 73 71 6c 69 74 65 33 20 2a 64 62 29 7b 0a 20 20  sqlite3 *db){.  
2bc0: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d  sqlite3_create_m
2bd0: 6f 64 75 6c 65 28 64 62 2c 20 22 73 63 68 65 6d  odule(db, "schem
2be0: 61 22 2c 20 26 73 63 68 65 6d 61 4d 6f 64 75 6c  a", &schemaModul
2bf0: 65 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20  e, 0);.  return 
2c00: 30 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  0;.}../*********
2c10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c50: 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  *.**************
2c60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2c90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a  *************.**
2ca0: 20 45 6e 64 20 6f 66 20 76 69 72 74 75 61 6c 20   End of virtual 
2cb0: 74 61 62 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 61  table implementa
2cc0: 74 69 6f 6e 73 2e 0a 2a 2a 20 53 74 61 72 74 20  tions..** Start 
2cd0: 6f 66 20 53 51 4c 20 75 73 65 72 20 66 75 6e 63  of SQL user func
2ce0: 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74  tion implementat
2cf0: 69 6f 6e 73 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  ions..*/../*.** 
2d00: 20 20 73 6a 28 7a 56 61 6c 75 65 2c 20 7a 4a 6f    sj(zValue, zJo
2d10: 69 6e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f  in).**.** The fo
2d20: 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 63 6f  llowing block co
2d30: 6e 74 61 69 6e 73 20 74 68 65 20 69 6d 70 6c 65  ntains the imple
2d40: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 6e 20  mentation of an 
2d50: 61 67 67 72 65 67 61 74 65 20 0a 2a 2a 20 66 75  aggregate .** fu
2d60: 6e 63 74 69 6f 6e 20 74 68 61 74 20 72 65 74 75  nction that retu
2d70: 72 6e 73 20 61 20 73 74 72 69 6e 67 2e 20 45 61  rns a string. Ea
2d80: 63 68 20 74 69 6d 65 20 74 68 65 20 66 75 6e 63  ch time the func
2d90: 74 69 6f 6e 20 69 73 20 73 74 65 70 70 65 64 2c  tion is stepped,
2da0: 20 0a 2a 2a 20 69 74 20 61 70 70 65 6e 64 73 20   .** it appends 
2db0: 64 61 74 61 20 74 6f 20 61 6e 20 69 6e 74 65 72  data to an inter
2dc0: 6e 61 6c 20 62 75 66 66 65 72 2e 20 57 68 65 6e  nal buffer. When
2dd0: 20 74 68 65 20 61 67 67 72 65 67 61 74 65 20 69   the aggregate i
2de0: 73 20 66 69 6e 61 6c 69 7a 65 64 2c 0a 2a 2a 20  s finalized,.** 
2df0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
2e00: 74 68 65 20 62 75 66 66 65 72 20 61 72 65 20 72  the buffer are r
2e10: 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  eturned..**.** T
2e20: 68 65 20 66 69 72 73 74 20 74 69 6d 65 20 74 68  he first time th
2e30: 65 20 61 67 67 72 65 67 61 74 65 20 69 73 20 73  e aggregate is s
2e40: 74 65 70 70 65 64 20 74 68 65 20 62 75 66 66 65  tepped the buffe
2e50: 72 20 69 73 20 73 65 74 20 74 6f 20 61 20 63 6f  r is set to a co
2e60: 70 79 0a 2a 2a 20 6f 66 20 74 68 65 20 66 69 72  py.** of the fir
2e70: 73 74 20 61 72 67 75 6d 65 6e 74 2e 20 54 68 65  st argument. The
2e80: 20 73 65 63 6f 6e 64 20 74 69 6d 65 20 61 6e 64   second time and
2e90: 20 73 75 62 73 65 71 75 65 6e 74 20 74 69 6d 65   subsequent time
2ea0: 73 20 69 74 20 69 73 0a 2a 2a 20 73 74 65 70 70  s it is.** stepp
2eb0: 65 64 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65  ed a copy of the
2ec0: 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
2ed0: 20 69 73 20 61 70 70 65 6e 64 65 64 20 74 6f 20   is appended to 
2ee0: 74 68 65 20 62 75 66 66 65 72 2c 20 74 68 65 6e  the buffer, then
2ef0: 0a 2a 2a 20 61 20 63 6f 70 79 20 6f 66 20 74 68  .** a copy of th
2f00: 65 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 45  e first..**.** E
2f10: 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  xample:.**.**   
2f20: 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31 28 61  INSERT INTO t1(a
2f30: 29 20 56 41 4c 55 45 53 28 27 31 27 29 3b 0a 2a  ) VALUES('1');.*
2f40: 2a 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20  *   INSERT INTO 
2f50: 74 31 28 61 29 20 56 41 4c 55 45 53 28 27 32 27  t1(a) VALUES('2'
2f60: 29 3b 0a 2a 2a 20 20 20 49 4e 53 45 52 54 20 49  );.**   INSERT I
2f70: 4e 54 4f 20 74 31 28 61 29 20 56 41 4c 55 45 53  NTO t1(a) VALUES
2f80: 28 27 33 27 29 3b 0a 2a 2a 20 20 20 53 45 4c 45  ('3');.**   SELE
2f90: 43 54 20 73 6a 28 61 2c 20 27 2c 20 27 29 20 46  CT sj(a, ', ') F
2fa0: 52 4f 4d 20 74 31 3b 0a 2a 2a 0a 2a 2a 20 20 20  ROM t1;.**.**   
2fb0: 20 20 3d 3e 20 20 22 31 2c 20 32 2c 20 33 22 0a    =>  "1, 2, 3".
2fc0: 2a 2a 0a 2a 2f 0a 73 74 72 75 63 74 20 53 74 72  **.*/.struct Str
2fd0: 42 75 66 66 65 72 20 7b 0a 20 20 63 68 61 72 20  Buffer {.  char 
2fe0: 2a 7a 42 75 66 3b 0a 7d 3b 0a 74 79 70 65 64 65  *zBuf;.};.typede
2ff0: 66 20 73 74 72 75 63 74 20 53 74 72 42 75 66 66  f struct StrBuff
3000: 65 72 20 53 74 72 42 75 66 66 65 72 3b 0a 73 74  er StrBuffer;.st
3010: 61 74 69 63 20 76 6f 69 64 20 6a 6f 69 6e 46 69  atic void joinFi
3020: 6e 61 6c 69 7a 65 28 73 71 6c 69 74 65 33 5f 63  nalize(sqlite3_c
3030: 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 29  ontext *context)
3040: 7b 0a 20 20 53 74 72 42 75 66 66 65 72 20 2a 70  {.  StrBuffer *p
3050: 3b 0a 20 20 70 20 3d 20 28 53 74 72 42 75 66 66  ;.  p = (StrBuff
3060: 65 72 20 2a 29 73 71 6c 69 74 65 33 5f 61 67 67  er *)sqlite3_agg
3070: 72 65 67 61 74 65 5f 63 6f 6e 74 65 78 74 28 63  regate_context(c
3080: 6f 6e 74 65 78 74 2c 20 73 69 7a 65 6f 66 28 53  ontext, sizeof(S
3090: 74 72 42 75 66 66 65 72 29 29 3b 0a 20 20 73 71  trBuffer));.  sq
30a0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
30b0: 74 28 63 6f 6e 74 65 78 74 2c 20 70 2d 3e 7a 42  t(context, p->zB
30c0: 75 66 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54  uf, -1, SQLITE_T
30d0: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 73 71 6c  RANSIENT);.  sql
30e0: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 42 75  ite3_free(p->zBu
30f0: 66 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  f);.}.static voi
3100: 64 20 6a 6f 69 6e 53 74 65 70 28 0a 20 20 73 71  d joinStep(.  sq
3110: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
3120: 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72  ontext,.  int ar
3130: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  gc,.  sqlite3_va
3140: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20  lue **argv.){.  
3150: 53 74 72 42 75 66 66 65 72 20 2a 70 3b 0a 20 20  StrBuffer *p;.  
3160: 70 20 3d 20 28 53 74 72 42 75 66 66 65 72 20 2a  p = (StrBuffer *
3170: 29 73 71 6c 69 74 65 33 5f 61 67 67 72 65 67 61  )sqlite3_aggrega
3180: 74 65 5f 63 6f 6e 74 65 78 74 28 63 6f 6e 74 65  te_context(conte
3190: 78 74 2c 20 73 69 7a 65 6f 66 28 53 74 72 42 75  xt, sizeof(StrBu
31a0: 66 66 65 72 29 29 3b 0a 20 20 69 66 28 20 70 2d  ffer));.  if( p-
31b0: 3e 7a 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20  >zBuf==0 ){.    
31c0: 70 2d 3e 7a 42 75 66 20 3d 20 73 71 6c 69 74 65  p->zBuf = sqlite
31d0: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20  3_mprintf("%s", 
31e0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
31f0: 78 74 28 61 72 67 76 5b 30 5d 29 29 3b 0a 20 20  xt(argv[0]));.  
3200: 7d 65 6c 73 65 7b 0a 20 20 20 20 63 68 61 72 20  }else{.    char 
3210: 2a 7a 54 6d 70 20 3d 20 70 2d 3e 7a 42 75 66 3b  *zTmp = p->zBuf;
3220: 0a 20 20 20 20 70 2d 3e 7a 42 75 66 20 3d 20 73  .    p->zBuf = s
3230: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
3240: 25 73 25 73 25 73 22 2c 20 0a 20 20 20 20 20 20  %s%s%s", .      
3250: 20 20 7a 54 6d 70 2c 20 73 71 6c 69 74 65 33 5f    zTmp, sqlite3_
3260: 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b  value_text(argv[
3270: 31 5d 29 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  1]), sqlite3_val
3280: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29  ue_text(argv[0])
3290: 0a 20 20 20 20 29 3b 0a 20 20 20 20 73 71 6c 69  .    );.    sqli
32a0: 74 65 33 5f 66 72 65 65 28 7a 54 6d 70 29 3b 0a  te3_free(zTmp);.
32b0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 20 20 64    }.}../*.**   d
32c0: 71 28 7a 53 74 72 69 6e 67 29 0a 2a 2a 0a 2a 2a  q(zString).**.**
32d0: 20 54 68 69 73 20 73 63 61 6c 61 72 20 66 75 6e   This scalar fun
32e0: 63 74 69 6f 6e 20 61 63 63 65 70 74 73 20 61 20  ction accepts a 
32f0: 73 69 6e 67 6c 65 20 61 72 67 75 6d 65 6e 74 20  single argument 
3300: 61 6e 64 20 69 6e 74 65 72 70 72 65 74 73 20 69  and interprets i
3310: 74 20 61 73 0a 2a 2a 20 61 20 74 65 78 74 20 76  t as.** a text v
3320: 61 6c 75 65 2e 20 54 68 65 20 72 65 74 75 72 6e  alue. The return
3330: 20 76 61 6c 75 65 20 69 73 20 74 68 65 20 61 72   value is the ar
3340: 67 75 6d 65 6e 74 20 65 6e 63 6c 6f 73 65 64 20  gument enclosed 
3350: 69 6e 20 64 6f 75 62 6c 65 0a 2a 2a 20 71 75 6f  in double.** quo
3360: 74 65 73 2e 20 49 66 20 61 6e 79 20 64 6f 75 62  tes. If any doub
3370: 6c 65 20 71 75 6f 74 65 20 63 68 61 72 61 63 74  le quote charact
3380: 65 72 73 20 61 72 65 20 70 72 65 73 65 6e 74 20  ers are present 
3390: 69 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 2c  in the argument,
33a0: 20 0a 2a 2a 20 74 68 65 73 65 20 61 72 65 20 65   .** these are e
33b0: 73 63 61 70 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  scaped..**.**   
33c0: 64 71 28 27 74 68 65 20 72 61 76 65 6e 20 22 4e  dq('the raven "N
33d0: 65 76 65 72 6d 6f 72 65 2e 22 27 29 20 3d 3d 20  evermore."') == 
33e0: 27 22 74 68 65 20 72 61 76 65 6e 20 22 22 4e 65  '"the raven ""Ne
33f0: 76 65 72 6d 6f 72 65 2e 22 22 22 27 0a 2a 2f 0a  vermore."""'.*/.
3400: 73 74 61 74 69 63 20 76 6f 69 64 20 64 6f 75 62  static void doub
3410: 6c 65 71 75 6f 74 65 28 0a 20 20 73 71 6c 69 74  lequote(.  sqlit
3420: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74  e3_context *cont
3430: 65 78 74 2c 20 0a 20 20 69 6e 74 20 61 72 67 63  ext, .  int argc
3440: 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  , .  sqlite3_val
3450: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69  ue **argv.){.  i
3460: 6e 74 20 69 69 3b 0a 20 20 63 68 61 72 20 2a 7a  nt ii;.  char *z
3470: 4f 75 74 3b 0a 20 20 63 68 61 72 20 2a 7a 43 73  Out;.  char *zCs
3480: 72 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  r;.  const char 
3490: 2a 7a 49 6e 20 3d 20 28 63 6f 6e 73 74 20 63 68  *zIn = (const ch
34a0: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  ar *)sqlite3_val
34b0: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29  ue_text(argv[0])
34c0: 3b 0a 20 20 69 6e 74 20 6e 49 6e 20 3d 20 73 71  ;.  int nIn = sq
34d0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65  lite3_value_byte
34e0: 73 28 61 72 67 76 5b 30 5d 29 3b 0a 0a 20 20 7a  s(argv[0]);..  z
34f0: 4f 75 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  Out = sqlite3_ma
3500: 6c 6c 6f 63 28 6e 49 6e 2a 32 2b 33 29 3b 0a 20  lloc(nIn*2+3);. 
3510: 20 7a 43 73 72 20 3d 20 7a 4f 75 74 3b 0a 20 20   zCsr = zOut;.  
3520: 2a 7a 43 73 72 2b 2b 20 3d 20 27 22 27 3b 0a 20  *zCsr++ = '"';. 
3530: 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 49   for(ii=0; ii<nI
3540: 6e 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 2a 7a  n; ii++){.    *z
3550: 43 73 72 2b 2b 20 3d 20 7a 49 6e 5b 69 69 5d 3b  Csr++ = zIn[ii];
3560: 0a 20 20 20 20 69 66 28 20 7a 49 6e 5b 69 69 5d  .    if( zIn[ii]
3570: 3d 3d 27 22 27 20 29 7b 0a 20 20 20 20 20 20 2a  =='"' ){.      *
3580: 7a 43 73 72 2b 2b 20 3d 20 27 22 27 3b 0a 20 20  zCsr++ = '"';.  
3590: 20 20 7d 0a 20 20 7d 0a 20 20 2a 7a 43 73 72 2b    }.  }.  *zCsr+
35a0: 2b 20 3d 20 27 22 27 3b 0a 20 20 2a 7a 43 73 72  + = '"';.  *zCsr
35b0: 2b 2b 20 3d 20 27 5c 30 27 3b 0a 0a 20 20 73 71  ++ = '\0';..  sq
35c0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
35d0: 74 28 63 6f 6e 74 65 78 74 2c 20 7a 4f 75 74 2c  t(context, zOut,
35e0: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e   -1, SQLITE_TRAN
35f0: 53 49 45 4e 54 29 3b 0a 20 20 73 71 6c 69 74 65  SIENT);.  sqlite
3600: 33 5f 66 72 65 65 28 7a 4f 75 74 29 3b 0a 7d 0a  3_free(zOut);.}.
3610: 0a 2f 2a 0a 2a 2a 20 20 20 6d 75 6c 74 69 72 65  ./*.**   multire
3620: 70 6c 61 63 65 28 7a 53 74 72 69 6e 67 2c 20 7a  place(zString, z
3630: 53 65 61 72 63 68 31 2c 20 7a 52 65 70 6c 61 63  Search1, zReplac
3640: 65 31 2c 20 2e 2e 2e 29 0a 2a 2f 0a 73 74 61 74  e1, ...).*/.stat
3650: 69 63 20 76 6f 69 64 20 6d 75 6c 74 69 72 65 70  ic void multirep
3660: 6c 61 63 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  lace(.  sqlite3_
3670: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74  context *context
3680: 2c 20 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 0a  , .  int argc, .
3690: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
36a0: 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20  **argv.){.  int 
36b0: 69 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a  i = 0;.  char *z
36c0: 4f 75 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e  Out = 0;.  int n
36d0: 4f 75 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e  Out = 0;.  int n
36e0: 4d 61 6c 6c 6f 63 20 3d 20 30 3b 0a 20 20 63 6f  Malloc = 0;.  co
36f0: 6e 73 74 20 63 68 61 72 20 2a 7a 49 6e 20 3d 20  nst char *zIn = 
3700: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71  (const char *)sq
3710: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
3720: 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 69 6e 74  (argv[0]);.  int
3730: 20 6e 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76   nIn = sqlite3_v
3740: 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b  alue_bytes(argv[
3750: 30 5d 29 3b 0a 0a 20 20 77 68 69 6c 65 28 20 69  0]);..  while( i
3760: 3c 6e 49 6e 20 29 7b 0a 20 20 20 20 63 6f 6e 73  <nIn ){.    cons
3770: 74 20 63 68 61 72 20 2a 7a 43 6f 70 79 20 3d 20  t char *zCopy = 
3780: 26 7a 49 6e 5b 69 5d 3b 0a 20 20 20 20 69 6e 74  &zIn[i];.    int
3790: 20 6e 43 6f 70 79 20 3d 20 31 3b 0a 20 20 20 20   nCopy = 1;.    
37a0: 69 6e 74 20 6e 52 65 70 6c 61 63 65 20 3d 20 31  int nReplace = 1
37b0: 3b 0a 20 20 20 20 69 6e 74 20 6a 3b 0a 20 20 20  ;.    int j;.   
37c0: 20 66 6f 72 28 6a 3d 31 3b 20 6a 3c 28 61 72 67   for(j=1; j<(arg
37d0: 63 2d 31 29 3b 20 6a 2b 3d 32 29 7b 0a 20 20 20  c-1); j+=2){.   
37e0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
37f0: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a   = (const char *
3800: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
3810: 65 78 74 28 61 72 67 76 5b 6a 5d 29 3b 0a 20 20  ext(argv[j]);.  
3820: 20 20 20 20 69 6e 74 20 6e 20 3d 20 73 71 6c 69      int n = sqli
3830: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
3840: 61 72 67 76 5b 6a 5d 29 3b 0a 20 20 20 20 20 20  argv[j]);.      
3850: 69 66 28 20 6e 3c 3d 28 6e 49 6e 2d 69 29 20 26  if( n<=(nIn-i) &
3860: 26 20 30 3d 3d 73 74 72 6e 63 6d 70 28 7a 2c 20  & 0==strncmp(z, 
3870: 7a 43 6f 70 79 2c 20 6e 29 20 29 7b 0a 20 20 20  zCopy, n) ){.   
3880: 20 20 20 20 20 7a 43 6f 70 79 20 3d 20 28 63 6f       zCopy = (co
3890: 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74  nst char *)sqlit
38a0: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72  e3_value_text(ar
38b0: 67 76 5b 6a 2b 31 5d 29 3b 0a 20 20 20 20 20 20  gv[j+1]);.      
38c0: 20 20 6e 43 6f 70 79 20 3d 20 73 71 6c 69 74 65    nCopy = sqlite
38d0: 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72  3_value_bytes(ar
38e0: 67 76 5b 6a 2b 31 5d 29 3b 0a 20 20 20 20 20 20  gv[j+1]);.      
38f0: 20 20 6e 52 65 70 6c 61 63 65 20 3d 20 6e 3b 0a    nReplace = n;.
3900: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
3910: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
3920: 20 69 66 28 20 28 6e 4f 75 74 2b 6e 43 6f 70 79   if( (nOut+nCopy
3930: 29 3e 6e 4d 61 6c 6c 6f 63 20 29 7b 0a 20 20 20  )>nMalloc ){.   
3940: 20 20 20 6e 4d 61 6c 6c 6f 63 20 2b 3d 20 28 6e     nMalloc += (n
3950: 4d 61 6c 6c 6f 63 20 2b 20 31 36 29 3b 0a 20 20  Malloc + 16);.  
3960: 20 20 20 20 7a 4f 75 74 20 3d 20 28 63 68 61 72      zOut = (char
3970: 20 2a 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c   *)sqlite3_reall
3980: 6f 63 28 7a 4f 75 74 2c 20 6e 4d 61 6c 6c 6f 63  oc(zOut, nMalloc
3990: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  );.    }.    mem
39a0: 63 70 79 28 26 7a 4f 75 74 5b 6e 4f 75 74 5d 2c  cpy(&zOut[nOut],
39b0: 20 7a 43 6f 70 79 2c 20 6e 43 6f 70 79 29 3b 0a   zCopy, nCopy);.
39c0: 20 20 20 20 69 20 2b 3d 20 6e 52 65 70 6c 61 63      i += nReplac
39d0: 65 3b 0a 20 20 20 20 6e 4f 75 74 20 2b 3d 20 6e  e;.    nOut += n
39e0: 43 6f 70 79 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c  Copy;.  }..  sql
39f0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
3a00: 28 63 6f 6e 74 65 78 74 2c 20 7a 4f 75 74 2c 20  (context, zOut, 
3a10: 6e 4f 75 74 2c 20 53 51 4c 49 54 45 5f 54 52 41  nOut, SQLITE_TRA
3a20: 4e 53 49 45 4e 54 29 3b 0a 20 20 73 71 6c 69 74  NSIENT);.  sqlit
3a30: 65 33 5f 66 72 65 65 28 7a 4f 75 74 29 3b 0a 7d  e3_free(zOut);.}
3a40: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
3a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a  *************.**
3a90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3aa0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ab0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ac0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3ad0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 45 6e 64  *********.** End
3ae0: 20 6f 66 20 53 51 4c 20 75 73 65 72 20 66 75 6e   of SQL user fun
3af0: 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61  ction implementa
3b00: 74 69 6f 6e 73 2e 0a 2a 2a 20 53 74 61 72 74 20  tions..** Start 
3b10: 6f 66 20 61 70 70 6c 69 63 61 74 69 6f 6e 20 69  of application i
3b20: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
3b30: 2f 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  /..typedef struc
3b40: 74 20 4f 70 74 69 6f 6e 73 20 4f 70 74 69 6f 6e  t Options Option
3b50: 73 3b 0a 73 74 72 75 63 74 20 4f 70 74 69 6f 6e  s;.struct Option
3b60: 73 20 7b 0a 20 20 63 68 61 72 20 2a 7a 44 62 3b  s {.  char *zDb;
3b70: 0a 20 20 69 6e 74 20 69 67 6e 6f 72 65 45 72 72  .  int ignoreErr
3b80: 6f 72 73 3b 0a 20 20 69 6e 74 20 6e 6f 44 72 6f  ors;.  int noDro
3b90: 70 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 50 72 69  p;.};../*.** Pri
3ba0: 6e 74 20 6f 75 74 20 61 20 75 73 61 67 65 20 6d  nt out a usage m
3bb0: 65 73 73 61 67 65 20 66 6f 72 20 74 68 65 20 63  essage for the c
3bc0: 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20 61 6e 64 20  ommand line and 
3bd0: 65 78 69 74 2e 20 54 68 69 73 20 69 73 0a 2a 2a  exit. This is.**
3be0: 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 70 72 6f   called from pro
3bf0: 63 65 73 73 43 6d 64 4c 69 6e 65 28 29 20 69 66  cessCmdLine() if
3c00: 20 74 68 65 20 70 72 6f 67 72 61 6d 20 69 73 20   the program is 
3c10: 69 6e 76 6f 6b 65 64 20 69 6e 63 6f 72 72 65 63  invoked incorrec
3c20: 74 6c 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  tly..*/.static i
3c30: 6e 74 20 75 73 61 67 65 28 63 68 61 72 20 2a 7a  nt usage(char *z
3c40: 50 72 6f 67 72 61 6d 29 7b 0a 20 20 66 70 72 69  Program){.  fpri
3c50: 6e 74 66 28 73 74 64 65 72 72 2c 20 0a 20 20 20  ntf(stderr, .   
3c60: 20 20 20 22 55 73 61 67 65 3a 20 25 73 20 3f 2d     "Usage: %s ?-
3c70: 2d 69 67 6e 6f 72 65 2d 65 72 72 6f 72 73 3f 20  -ignore-errors? 
3c80: 3f 2d 2d 6e 6f 2d 64 72 6f 70 3f 20 3c 64 61 74  ?--no-drop? <dat
3c90: 61 62 61 73 65 20 66 69 6c 65 3e 5c 6e 22 2c 20  abase file>\n", 
3ca0: 7a 50 72 6f 67 72 61 6d 0a 20 20 29 3b 0a 20 20  zProgram.  );.  
3cb0: 65 78 69 74 28 2d 31 29 3b 0a 7d 0a 0a 73 74 61  exit(-1);.}..sta
3cc0: 74 69 63 20 76 6f 69 64 20 70 72 6f 63 65 73 73  tic void process
3cd0: 43 6d 64 4c 69 6e 65 28 69 6e 74 20 6e 41 72 67  CmdLine(int nArg
3ce0: 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 2c 20  , char **azArg, 
3cf0: 4f 70 74 69 6f 6e 73 20 2a 70 29 7b 0a 20 20 69  Options *p){.  i
3d00: 6e 74 20 69 3b 0a 20 20 61 73 73 65 72 74 28 20  nt i;.  assert( 
3d10: 6e 41 72 67 3e 30 20 29 3b 0a 20 20 69 66 28 20  nArg>0 );.  if( 
3d20: 6e 41 72 67 3c 32 20 29 7b 0a 20 20 20 20 75 73  nArg<2 ){.    us
3d30: 61 67 65 28 61 7a 41 72 67 5b 30 5d 29 3b 0a 20  age(azArg[0]);. 
3d40: 20 7d 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c   }.  for(i=1; i<
3d50: 28 6e 41 72 67 2d 31 29 3b 20 69 2b 2b 29 7b 0a  (nArg-1); i++){.
3d60: 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a      char *z = az
3d70: 41 72 67 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20  Arg[i];.    if( 
3d80: 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 22 2d 2d  0==strcmp(z, "--
3d90: 69 67 6e 6f 72 65 2d 65 72 72 6f 72 73 22 29 20  ignore-errors") 
3da0: 29 7b 0a 20 20 20 20 20 20 70 2d 3e 69 67 6e 6f  ){.      p->igno
3db0: 72 65 45 72 72 6f 72 73 20 3d 20 31 3b 0a 20 20  reErrors = 1;.  
3dc0: 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
3dd0: 20 30 3d 3d 73 74 72 63 6d 70 28 7a 2c 20 22 2d   0==strcmp(z, "-
3de0: 2d 6e 6f 2d 64 72 6f 70 22 29 20 29 7b 0a 20 20  -no-drop") ){.  
3df0: 20 20 20 20 70 2d 3e 6e 6f 44 72 6f 70 20 3d 20      p->noDrop = 
3e00: 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73  1;.    }.    els
3e10: 65 20 75 73 61 67 65 28 61 7a 41 72 67 5b 30 5d  e usage(azArg[0]
3e20: 29 3b 0a 20 20 7d 0a 20 20 70 2d 3e 7a 44 62 20  );.  }.  p->zDb 
3e30: 3d 20 61 7a 41 72 67 5b 6e 41 72 67 2d 31 5d 3b  = azArg[nArg-1];
3e40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 61 6c 6c  .}../*.** A call
3e50: 62 61 63 6b 20 66 6f 72 20 73 71 6c 69 74 65 33  back for sqlite3
3e60: 5f 65 78 65 63 28 29 20 74 68 61 74 20 70 72 69  _exec() that pri
3e70: 6e 74 73 20 69 74 73 20 66 69 72 73 74 20 61 72  nts its first ar
3e80: 67 75 6d 65 6e 74 20 74 6f 0a 2a 2a 20 73 74 64  gument to.** std
3e90: 6f 75 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  out followed by 
3ea0: 61 20 6e 65 77 6c 69 6e 65 2e 0a 2a 2f 0a 73 74  a newline..*/.st
3eb0: 61 74 69 63 20 69 6e 74 20 70 72 69 6e 74 53 74  atic int printSt
3ec0: 72 69 6e 67 28 76 6f 69 64 20 2a 70 2c 20 69 6e  ring(void *p, in
3ed0: 74 20 6e 41 72 67 2c 20 63 68 61 72 20 2a 2a 61  t nArg, char **a
3ee0: 7a 41 72 67 2c 20 63 68 61 72 20 2a 2a 61 7a 43  zArg, char **azC
3ef0: 6f 6c 29 7b 0a 20 20 70 72 69 6e 74 66 28 22 25  ol){.  printf("%
3f00: 73 5c 6e 22 2c 20 61 7a 41 72 67 5b 30 5d 29 3b  s\n", azArg[0]);
3f10: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
3f20: 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74 20 64 65 74 65  _OK;.}..int dete
3f30: 63 74 53 63 68 65 6d 61 50 72 6f 62 6c 65 6d 28  ctSchemaProblem(
3f40: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f60: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f    /* Database co
3f70: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f  nnection */.  co
3f80: 6e 73 74 20 63 68 61 72 20 2a 7a 4d 65 73 73 61  nst char *zMessa
3f90: 67 65 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ge,          /* 
3fa0: 45 6e 67 6c 69 73 68 20 6c 61 6e 67 75 61 67 65  English language
3fb0: 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a   error message *
3fc0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
3fd0: 7a 53 71 6c 2c 20 20 20 20 20 20 20 20 20 20 20  zSql,           
3fe0: 20 20 20 2f 2a 20 53 51 4c 20 73 74 61 74 65 6d     /* SQL statem
3ff0: 65 6e 74 20 74 6f 20 72 75 6e 20 2a 2f 0a 20 20  ent to run */.  
4000: 69 6e 74 20 2a 70 48 61 73 45 72 72 6f 72 73 20  int *pHasErrors 
4010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4020: 2a 20 53 65 74 20 2a 70 48 61 73 45 72 72 6f 72  * Set *pHasError
4030: 73 3d 3d 31 20 69 66 20 65 72 72 6f 72 73 20 66  s==1 if errors f
4040: 6f 75 6e 64 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  ound */.){.  sql
4050: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
4060: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63  ;.  int rc;.  rc
4070: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
4080: 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  re(db, zSql, -1,
4090: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 69   &pStmt, 0);.  i
40a0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
40b0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
40c0: 63 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20  c;.  }.  while( 
40d0: 53 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69  SQLITE_ROW==sqli
40e0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 20  te3_step(pStmt) 
40f0: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 65  ){.    char *zDe
4100: 6c 3b 0a 20 20 20 20 69 6e 74 20 69 46 6b 20 3d  l;.    int iFk =
4110: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
4120: 69 6e 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20  int(pStmt, 0);. 
4130: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
4140: 54 61 62 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  Tab = (const cha
4150: 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  r *)sqlite3_colu
4160: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31  mn_text(pStmt, 1
4170: 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 73  );.    fprintf(s
4180: 74 64 65 72 72 2c 20 22 45 72 72 6f 72 20 69 6e  tderr, "Error in
4190: 20 74 61 62 6c 65 20 25 73 3a 20 25 73 5c 6e 22   table %s: %s\n"
41a0: 2c 20 7a 54 61 62 2c 20 7a 4d 65 73 73 61 67 65  , zTab, zMessage
41b0: 29 3b 0a 20 20 20 20 7a 44 65 6c 20 3d 20 73 71  );.    zDel = sq
41c0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20  lite3_mprintf(. 
41d0: 20 20 20 20 20 20 20 22 44 45 4c 45 54 45 20 46         "DELETE F
41e0: 52 4f 4d 20 74 65 6d 70 2e 66 6b 65 79 20 57 48  ROM temp.fkey WH
41f0: 45 52 45 20 66 72 6f 6d 5f 74 62 6c 20 3d 20 25  ERE from_tbl = %
4200: 51 20 41 4e 44 20 66 6b 69 64 20 3d 20 25 64 22  Q AND fkid = %d"
4210: 0a 20 20 20 20 20 20 20 20 2c 20 7a 54 61 62 2c  .        , zTab,
4220: 20 69 46 6b 0a 20 20 20 20 29 3b 0a 20 20 20 20   iFk.    );.    
4230: 73 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c  sqlite3_exec(db,
4240: 20 7a 44 65 6c 2c 20 30 2c 20 30 2c 20 30 29 3b   zDel, 0, 0, 0);
4250: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4260: 65 28 7a 44 65 6c 29 3b 0a 20 20 20 20 2a 70 48  e(zDel);.    *pH
4270: 61 73 45 72 72 6f 72 73 20 3d 20 31 3b 0a 20 20  asErrors = 1;.  
4280: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  }.  sqlite3_fina
4290: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72  lize(pStmt);.  r
42a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
42b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65  .}../*.** Create
42c0: 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 74 65   and populate te
42d0: 6d 70 6f 72 61 72 79 20 74 61 62 6c 65 20 22 66  mporary table "f
42e0: 6b 65 79 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  key"..*/.static 
42f0: 69 6e 74 20 70 6f 70 75 6c 61 74 65 54 65 6d 70  int populateTemp
4300: 54 61 62 6c 65 28 73 71 6c 69 74 65 33 20 2a 64  Table(sqlite3 *d
4310: 62 2c 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 2c  b, char **pzErr,
4320: 20 69 6e 74 20 2a 70 48 61 73 45 72 72 6f 72 73   int *pHasErrors
4330: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  ){.  int rc;..  
4340: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
4350: 63 28 64 62 2c 20 0a 20 20 20 20 20 20 22 43 52  c(db, .      "CR
4360: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42  EATE VIRTUAL TAB
4370: 4c 45 20 74 65 6d 70 2e 76 5f 66 6b 65 79 20 55  LE temp.v_fkey U
4380: 53 49 4e 47 20 73 63 68 65 6d 61 28 66 6f 72 65  SING schema(fore
4390: 69 67 6e 5f 6b 65 79 5f 6c 69 73 74 29 3b 22 0a  ign_key_list);".
43a0: 20 20 20 20 20 20 22 43 52 45 41 54 45 20 56 49        "CREATE VI
43b0: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 65 6d 70  RTUAL TABLE temp
43c0: 2e 76 5f 63 6f 6c 20 55 53 49 4e 47 20 73 63 68  .v_col USING sch
43d0: 65 6d 61 28 74 61 62 6c 65 5f 69 6e 66 6f 29 3b  ema(table_info);
43e0: 22 0a 20 20 20 20 20 20 22 43 52 45 41 54 45 20  ".      "CREATE 
43f0: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 65  VIRTUAL TABLE te
4400: 6d 70 2e 76 5f 69 64 78 6c 69 73 74 20 55 53 49  mp.v_idxlist USI
4410: 4e 47 20 73 63 68 65 6d 61 28 69 6e 64 65 78 5f  NG schema(index_
4420: 6c 69 73 74 29 3b 22 0a 20 20 20 20 20 20 22 43  list);".      "C
4430: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41  REATE VIRTUAL TA
4440: 42 4c 45 20 74 65 6d 70 2e 76 5f 69 64 78 69 6e  BLE temp.v_idxin
4450: 66 6f 20 55 53 49 4e 47 20 73 63 68 65 6d 61 28  fo USING schema(
4460: 69 6e 64 65 78 5f 69 6e 66 6f 29 3b 22 0a 0a 20  index_info);".. 
4470: 20 20 20 20 20 22 43 52 45 41 54 45 20 54 41 42       "CREATE TAB
4480: 4c 45 20 74 65 6d 70 2e 66 6b 65 79 20 41 53 20  LE temp.fkey AS 
4490: 22 0a 20 20 20 20 20 20 20 20 22 53 45 4c 45 43  ".        "SELEC
44a0: 54 20 66 72 6f 6d 5f 74 62 6c 2c 20 74 6f 5f 74  T from_tbl, to_t
44b0: 62 6c 2c 20 66 6b 69 64 2c 20 66 72 6f 6d 5f 63  bl, fkid, from_c
44c0: 6f 6c 2c 20 74 6f 5f 63 6f 6c 2c 20 6f 6e 5f 75  ol, to_col, on_u
44d0: 70 64 61 74 65 2c 20 6f 6e 5f 64 65 6c 65 74 65  pdate, on_delete
44e0: 20 22 0a 20 20 20 20 20 20 20 20 22 46 52 4f 4d   ".        "FROM
44f0: 20 74 65 6d 70 2e 76 5f 66 6b 65 79 20 57 48 45   temp.v_fkey WHE
4500: 52 45 20 64 61 74 61 62 61 73 65 20 3d 20 27 6d  RE database = 'm
4510: 61 69 6e 27 3b 22 0a 0a 20 20 20 20 20 20 2c 20  ain';"..      , 
4520: 30 2c 20 30 2c 20 70 7a 45 72 72 0a 20 20 29 3b  0, 0, pzErr.  );
4530: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
4540: 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63  E_OK ) return rc
4550: 3b 0a 0a 20 20 72 63 20 3d 20 64 65 74 65 63 74  ;..  rc = detect
4560: 53 63 68 65 6d 61 50 72 6f 62 6c 65 6d 28 64 62  SchemaProblem(db
4570: 2c 20 22 66 6f 72 65 69 67 6e 20 6b 65 79 20 63  , "foreign key c
4580: 6f 6c 75 6d 6e 73 20 64 6f 20 6e 6f 74 20 65 78  olumns do not ex
4590: 69 73 74 22 2c 0a 20 20 20 20 22 53 45 4c 45 43  ist",.    "SELEC
45a0: 54 20 66 6b 69 64 2c 20 66 72 6f 6d 5f 74 62 6c  T fkid, from_tbl
45b0: 20 22 0a 20 20 20 20 22 46 52 4f 4d 20 74 65 6d   ".    "FROM tem
45c0: 70 2e 66 6b 65 79 20 22 0a 20 20 20 20 22 57 48  p.fkey ".    "WH
45d0: 45 52 45 20 74 6f 5f 63 6f 6c 20 49 53 20 4e 4f  ERE to_col IS NO
45e0: 54 20 4e 55 4c 4c 20 41 4e 44 20 4e 4f 54 20 45  T NULL AND NOT E
45f0: 58 49 53 54 53 20 28 53 45 4c 45 43 54 20 31 20  XISTS (SELECT 1 
4600: 22 0a 20 20 20 20 20 20 20 20 22 46 52 4f 4d 20  ".        "FROM 
4610: 74 65 6d 70 2e 76 5f 63 6f 6c 20 57 48 45 52 45  temp.v_col WHERE
4620: 20 74 61 62 6c 65 6e 61 6d 65 3d 74 6f 5f 74 62   tablename=to_tb
4630: 6c 20 41 4e 44 20 6e 61 6d 65 3d 3d 74 6f 5f 63  l AND name==to_c
4640: 6f 6c 22 0a 20 20 20 20 22 29 22 2c 20 70 48 61  ol".    ")", pHa
4650: 73 45 72 72 6f 72 73 0a 20 20 29 3b 0a 20 20 69  sErrors.  );.  i
4660: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
4670: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
4680: 20 2f 2a 20 41 74 20 74 68 69 73 20 70 6f 69 6e   /* At this poin
4690: 74 20 74 68 65 20 74 65 6d 70 2e 66 6b 65 79 20  t the temp.fkey 
46a0: 74 61 62 6c 65 20 69 73 20 6d 6f 73 74 6c 79 20  table is mostly 
46b0: 70 6f 70 75 6c 61 74 65 64 2e 20 49 66 20 61 6e  populated. If an
46c0: 79 20 66 6f 72 65 69 67 6e 0a 20 20 2a 2a 20 6b  y foreign.  ** k
46d0: 65 79 73 20 77 65 72 65 20 73 70 65 63 69 66 69  eys were specifi
46e0: 65 64 20 73 6f 20 74 68 61 74 20 74 68 65 79 20  ed so that they 
46f0: 69 6d 70 6c 69 63 69 74 6c 79 20 72 65 66 65 72  implicitly refer
4700: 20 74 6f 20 74 68 65 79 20 70 72 69 6d 61 72 79   to they primary
4710: 0a 20 20 2a 2a 20 6b 65 79 20 6f 66 20 74 68 65  .  ** key of the
4720: 20 70 61 72 65 6e 74 20 74 61 62 6c 65 2c 20 74   parent table, t
4730: 68 65 20 22 74 6f 5f 63 6f 6c 22 20 76 61 6c 75  he "to_col" valu
4740: 65 73 20 6f 66 20 74 68 65 20 74 65 6d 70 2e 66  es of the temp.f
4750: 6b 65 79 20 72 6f 77 73 0a 20 20 2a 2a 20 61 72  key rows.  ** ar
4760: 65 20 73 74 69 6c 6c 20 73 65 74 20 74 6f 20 4e  e still set to N
4770: 55 4c 4c 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54  ULL..  **.  ** T
4780: 68 69 73 20 69 73 20 65 61 73 69 6c 79 20 66 69  his is easily fi
4790: 78 65 64 20 66 6f 72 20 73 69 6e 67 6c 65 20 63  xed for single c
47a0: 6f 6c 75 6d 6e 20 70 72 69 6d 61 72 79 20 6b 65  olumn primary ke
47b0: 79 73 2c 20 62 75 74 20 6e 6f 74 20 66 6f 72 0a  ys, but not for.
47c0: 20 20 2a 2a 20 63 6f 6d 70 6f 73 69 74 65 73 2e    ** composites.
47d0: 20 57 69 74 68 20 61 20 63 6f 6d 70 6f 73 69 74   With a composit
47e0: 65 20 70 72 69 6d 61 72 79 20 6b 65 79 2c 20 74  e primary key, t
47f0: 68 65 72 65 20 69 73 20 6e 6f 20 77 61 79 20 74  here is no way t
4800: 6f 20 72 65 6c 69 61 62 6c 79 0a 20 20 2a 2a 20  o reliably.  ** 
4810: 71 75 65 72 79 20 73 71 6c 69 74 65 20 66 6f 72  query sqlite for
4820: 20 74 68 65 20 6f 72 64 65 72 20 69 6e 20 77 68   the order in wh
4830: 69 63 68 20 74 68 65 20 63 6f 6c 75 6d 6e 73 20  ich the columns 
4840: 74 68 61 74 20 6d 61 6b 65 20 75 70 20 74 68 65  that make up the
4850: 0a 20 20 2a 2a 20 63 6f 6d 70 6f 73 69 74 65 20  .  ** composite 
4860: 6b 65 79 20 77 65 72 65 20 64 65 63 6c 61 72 65  key were declare
4870: 64 20 69 2e 65 2e 20 74 68 65 72 65 20 69 73 20  d i.e. there is 
4880: 6e 6f 20 77 61 79 20 74 6f 20 74 65 6c 6c 20 69  no way to tell i
4890: 66 20 74 68 65 0a 20 20 2a 2a 20 73 63 68 65 6d  f the.  ** schem
48a0: 61 20 61 63 74 75 61 6c 6c 79 20 63 6f 6e 74 61  a actually conta
48b0: 69 6e 73 20 22 50 52 49 4d 41 52 59 20 4b 45 59  ins "PRIMARY KEY
48c0: 28 61 2c 20 62 29 22 20 6f 72 20 22 50 52 49 4d  (a, b)" or "PRIM
48d0: 41 52 59 20 4b 45 59 28 62 2c 20 61 29 22 2e 0a  ARY KEY(b, a)"..
48e0: 20 20 2a 2a 20 54 68 65 72 65 66 6f 72 65 2c 20    ** Therefore, 
48f0: 74 68 69 73 20 63 61 73 65 20 69 73 20 6e 6f 74  this case is not
4900: 20 68 61 6e 64 6c 65 64 2e 20 54 68 65 20 66 6f   handled. The fo
4910: 6c 6c 6f 77 69 6e 67 20 66 75 6e 63 74 69 6f 6e  llowing function
4920: 20 63 61 6c 6c 0a 20 20 2a 2a 20 64 65 74 65 63   call.  ** detec
4930: 74 73 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20  ts instances of 
4940: 74 68 69 73 20 63 61 73 65 2e 0a 20 20 2a 2f 0a  this case..  */.
4950: 20 20 72 63 20 3d 20 64 65 74 65 63 74 53 63 68    rc = detectSch
4960: 65 6d 61 50 72 6f 62 6c 65 6d 28 64 62 2c 20 22  emaProblem(db, "
4970: 69 6d 70 6c 69 63 69 74 20 6d 61 70 70 69 6e 67  implicit mapping
4980: 20 74 6f 20 63 6f 6d 70 6f 73 69 74 65 20 70 72   to composite pr
4990: 69 6d 61 72 79 20 6b 65 79 22 2c 0a 20 20 20 20  imary key",.    
49a0: 22 53 45 4c 45 43 54 20 66 6b 69 64 2c 20 66 72  "SELECT fkid, fr
49b0: 6f 6d 5f 74 62 6c 20 22 0a 20 20 20 20 22 46 52  om_tbl ".    "FR
49c0: 4f 4d 20 74 65 6d 70 2e 66 6b 65 79 20 22 0a 20  OM temp.fkey ". 
49d0: 20 20 20 22 57 48 45 52 45 20 74 6f 5f 63 6f 6c     "WHERE to_col
49e0: 20 49 53 20 4e 55 4c 4c 20 22 0a 20 20 20 20 22   IS NULL ".    "
49f0: 47 52 4f 55 50 20 42 59 20 66 6b 69 64 2c 20 66  GROUP BY fkid, f
4a00: 72 6f 6d 5f 74 62 6c 20 48 41 56 49 4e 47 20 63  rom_tbl HAVING c
4a10: 6f 75 6e 74 28 2a 29 20 3e 20 31 22 2c 20 70 48  ount(*) > 1", pH
4a20: 61 73 45 72 72 6f 72 73 0a 20 20 29 3b 0a 20 20  asErrors.  );.  
4a30: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
4a40: 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a  K ) return rc;..
4a50: 20 20 2f 2a 20 44 65 74 65 63 74 20 61 74 74 65    /* Detect atte
4a60: 6d 70 74 73 20 74 6f 20 69 6d 70 6c 69 63 69 74  mpts to implicit
4a70: 6c 79 20 6d 61 70 20 74 6f 20 74 68 65 20 70 72  ly map to the pr
4a80: 69 6d 61 72 79 20 6b 65 79 20 6f 66 20 61 20 74  imary key of a t
4a90: 61 62 6c 65 20 0a 20 20 2a 2a 20 74 68 61 74 20  able .  ** that 
4aa0: 68 61 73 20 6e 6f 20 70 72 69 6d 61 72 79 20 6b  has no primary k
4ab0: 65 79 20 63 6f 6c 75 6d 6e 2e 0a 20 20 2a 2f 0a  ey column..  */.
4ac0: 20 20 72 63 20 3d 20 64 65 74 65 63 74 53 63 68    rc = detectSch
4ad0: 65 6d 61 50 72 6f 62 6c 65 6d 28 64 62 2c 20 22  emaProblem(db, "
4ae0: 69 6d 70 6c 69 63 69 74 20 6d 61 70 70 69 6e 67  implicit mapping
4af0: 20 74 6f 20 6e 6f 6e 2d 65 78 69 73 74 61 6e 74   to non-existant
4b00: 20 70 72 69 6d 61 72 79 20 6b 65 79 22 2c 0a 20   primary key",. 
4b10: 20 20 20 22 53 45 4c 45 43 54 20 66 6b 69 64 2c     "SELECT fkid,
4b20: 20 66 72 6f 6d 5f 74 62 6c 20 22 0a 20 20 20 20   from_tbl ".    
4b30: 22 46 52 4f 4d 20 74 65 6d 70 2e 66 6b 65 79 20  "FROM temp.fkey 
4b40: 22 0a 20 20 20 20 22 57 48 45 52 45 20 74 6f 5f  ".    "WHERE to_
4b50: 63 6f 6c 20 49 53 20 4e 55 4c 4c 20 41 4e 44 20  col IS NULL AND 
4b60: 4e 4f 54 20 45 58 49 53 54 53 20 22 0a 20 20 20  NOT EXISTS ".   
4b70: 20 20 20 22 28 53 45 4c 45 43 54 20 31 20 46 52     "(SELECT 1 FR
4b80: 4f 4d 20 74 65 6d 70 2e 76 5f 63 6f 6c 20 57 48  OM temp.v_col WH
4b90: 45 52 45 20 70 6b 20 41 4e 44 20 74 61 62 6c 65  ERE pk AND table
4ba0: 6e 61 6d 65 20 3d 20 74 65 6d 70 2e 66 6b 65 79  name = temp.fkey
4bb0: 2e 74 6f 5f 74 62 6c 29 22 0a 20 20 20 20 2c 20  .to_tbl)".    , 
4bc0: 70 48 61 73 45 72 72 6f 72 73 0a 20 20 29 3b 0a  pHasErrors.  );.
4bd0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
4be0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
4bf0: 0a 0a 20 20 2f 2a 20 46 69 78 20 61 6c 6c 20 74  ..  /* Fix all t
4c00: 68 65 20 69 6d 70 6c 69 63 69 74 20 70 72 69 6d  he implicit prim
4c10: 61 72 79 20 6b 65 79 20 6d 61 70 70 69 6e 67 73  ary key mappings
4c20: 20 69 6e 20 74 68 65 20 74 65 6d 70 2e 66 6b 65   in the temp.fke
4c30: 79 20 74 61 62 6c 65 2e 20 2a 2f 0a 20 20 72 63  y table. */.  rc
4c40: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
4c50: 64 62 2c 20 0a 20 20 20 20 22 55 50 44 41 54 45  db, .    "UPDATE
4c60: 20 74 65 6d 70 2e 66 6b 65 79 20 53 45 54 20 74   temp.fkey SET t
4c70: 6f 5f 63 6f 6c 20 3d 20 22 0a 20 20 20 20 20 20  o_col = ".      
4c80: 22 28 53 45 4c 45 43 54 20 6e 61 6d 65 20 46 52  "(SELECT name FR
4c90: 4f 4d 20 74 65 6d 70 2e 76 5f 63 6f 6c 20 57 48  OM temp.v_col WH
4ca0: 45 52 45 20 70 6b 20 41 4e 44 20 74 61 62 6c 65  ERE pk AND table
4cb0: 6e 61 6d 65 3d 74 65 6d 70 2e 66 6b 65 79 2e 74  name=temp.fkey.t
4cc0: 6f 5f 74 62 6c 29 22 0a 20 20 20 20 22 20 57 48  o_tbl)".    " WH
4cd0: 45 52 45 20 74 6f 5f 63 6f 6c 20 49 53 20 4e 55  ERE to_col IS NU
4ce0: 4c 4c 3b 22 0a 20 20 20 20 2c 20 30 2c 20 30 2c  LL;".    , 0, 0,
4cf0: 20 70 7a 45 72 72 0a 20 20 29 3b 0a 20 20 69 66   pzErr.  );.  if
4d00: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
4d10: 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20  ) return rc;..  
4d20: 2f 2a 20 4e 6f 77 20 63 68 65 63 6b 20 74 68 61  /* Now check tha
4d30: 74 20 61 6c 6c 20 61 6c 6c 20 70 61 72 65 6e 74  t all all parent
4d40: 20 6b 65 79 73 20 61 72 65 20 65 69 74 68 65 72   keys are either
4d50: 20 70 72 69 6d 61 72 79 20 6b 65 79 73 20 6f 72   primary keys or
4d60: 20 0a 20 20 2a 2a 20 73 75 62 6a 65 63 74 20 74   .  ** subject t
4d70: 6f 20 61 20 75 6e 69 71 75 65 20 63 6f 6e 73 74  o a unique const
4d80: 72 61 69 6e 74 2e 0a 20 20 2a 2f 0a 20 20 72 63  raint..  */.  rc
4d90: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
4da0: 64 62 2c 20 0a 20 20 20 20 22 43 52 45 41 54 45  db, .    "CREATE
4db0: 20 54 41 42 4c 45 20 74 65 6d 70 2e 69 64 78 32   TABLE temp.idx2
4dc0: 20 41 53 20 53 45 4c 45 43 54 20 22 0a 20 20 20   AS SELECT ".   
4dd0: 20 20 20 22 69 6c 2e 74 61 62 6c 65 6e 61 6d 65     "il.tablename
4de0: 20 41 53 20 74 61 62 6c 65 6e 61 6d 65 2c 22 0a   AS tablename,".
4df0: 20 20 20 20 20 20 22 69 69 2e 69 6e 64 65 78 6e        "ii.indexn
4e00: 61 6d 65 20 41 53 20 69 6e 64 65 78 6e 61 6d 65  ame AS indexname
4e10: 2c 22 0a 20 20 20 20 20 20 22 69 69 2e 6e 61 6d  ,".      "ii.nam
4e20: 65 20 41 53 20 63 6f 6c 20 22 0a 20 20 20 20 20  e AS col ".     
4e30: 20 22 46 52 4f 4d 20 74 65 6d 70 2e 76 5f 69 64   "FROM temp.v_id
4e40: 78 6c 69 73 74 20 41 53 20 69 6c 2c 20 74 65 6d  xlist AS il, tem
4e50: 70 2e 76 5f 69 64 78 69 6e 66 6f 20 41 53 20 69  p.v_idxinfo AS i
4e60: 69 20 22 0a 20 20 20 20 20 20 22 57 48 45 52 45  i ".      "WHERE
4e70: 20 69 6c 2e 69 73 75 6e 69 71 75 65 20 41 4e 44   il.isunique AND
4e80: 20 69 6c 2e 64 61 74 61 62 61 73 65 3d 27 6d 61   il.database='ma
4e90: 69 6e 27 20 41 4e 44 20 69 69 2e 69 6e 64 65 78  in' AND ii.index
4ea0: 6e 61 6d 65 20 3d 20 69 6c 2e 6e 61 6d 65 3b 22  name = il.name;"
4eb0: 0a 20 20 20 20 22 49 4e 53 45 52 54 20 49 4e 54  .    "INSERT INT
4ec0: 4f 20 74 65 6d 70 2e 69 64 78 32 20 22 0a 20 20  O temp.idx2 ".  
4ed0: 20 20 20 20 22 53 45 4c 45 43 54 20 74 61 62 6c      "SELECT tabl
4ee0: 65 6e 61 6d 65 2c 20 27 70 6b 27 2c 20 6e 61 6d  ename, 'pk', nam
4ef0: 65 20 46 52 4f 4d 20 74 65 6d 70 2e 76 5f 63 6f  e FROM temp.v_co
4f00: 6c 20 57 48 45 52 45 20 70 6b 3b 22 0a 0a 20 20  l WHERE pk;"..  
4f10: 20 20 22 43 52 45 41 54 45 20 54 41 42 4c 45 20    "CREATE TABLE 
4f20: 74 65 6d 70 2e 69 64 78 20 41 53 20 53 45 4c 45  temp.idx AS SELE
4f30: 43 54 20 22 0a 20 20 20 20 20 20 22 74 61 62 6c  CT ".      "tabl
4f40: 65 6e 61 6d 65 2c 20 69 6e 64 65 78 6e 61 6d 65  ename, indexname
4f50: 2c 20 73 6a 28 64 71 28 63 6f 6c 29 2c 27 2c 27  , sj(dq(col),','
4f60: 29 20 41 53 20 63 6f 6c 73 20 22 0a 20 20 20 20  ) AS cols ".    
4f70: 20 20 22 46 52 4f 4d 20 28 53 45 4c 45 43 54 20    "FROM (SELECT 
4f80: 2a 20 46 52 4f 4d 20 74 65 6d 70 2e 69 64 78 32  * FROM temp.idx2
4f90: 20 4f 52 44 45 52 20 42 59 20 63 6f 6c 29 20 22   ORDER BY col) "
4fa0: 20 0a 20 20 20 20 20 20 22 47 52 4f 55 50 20 42   .      "GROUP B
4fb0: 59 20 74 61 62 6c 65 6e 61 6d 65 2c 20 69 6e 64  Y tablename, ind
4fc0: 65 78 6e 61 6d 65 3b 22 0a 0a 20 20 20 20 22 43  exname;"..    "C
4fd0: 52 45 41 54 45 20 54 41 42 4c 45 20 74 65 6d 70  REATE TABLE temp
4fe0: 2e 66 6b 65 79 32 20 41 53 20 53 45 4c 45 43 54  .fkey2 AS SELECT
4ff0: 20 22 0a 20 20 20 20 20 20 20 20 22 66 6b 69 64   ".        "fkid
5000: 2c 20 66 72 6f 6d 5f 74 62 6c 2c 20 74 6f 5f 74  , from_tbl, to_t
5010: 62 6c 2c 20 73 6a 28 64 71 28 74 6f 5f 63 6f 6c  bl, sj(dq(to_col
5020: 29 2c 27 2c 27 29 20 41 53 20 63 6f 6c 73 20 22  ),',') AS cols "
5030: 0a 20 20 20 20 20 20 20 20 22 46 52 4f 4d 20 28  .        "FROM (
5040: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 74 65  SELECT * FROM te
5050: 6d 70 2e 66 6b 65 79 20 4f 52 44 45 52 20 42 59  mp.fkey ORDER BY
5060: 20 74 6f 5f 63 6f 6c 29 20 22 20 0a 20 20 20 20   to_col) " .    
5070: 20 20 20 20 22 47 52 4f 55 50 20 42 59 20 66 6b      "GROUP BY fk
5080: 69 64 2c 20 66 72 6f 6d 5f 74 62 6c 3b 22 0a 20  id, from_tbl;". 
5090: 20 20 20 2c 20 30 2c 20 30 2c 20 70 7a 45 72 72     , 0, 0, pzErr
50a0: 0a 20 20 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  .  );.  if( rc!=
50b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75  SQLITE_OK ) retu
50c0: 72 6e 20 72 63 3b 0a 20 20 72 63 20 3d 20 64 65  rn rc;.  rc = de
50d0: 74 65 63 74 53 63 68 65 6d 61 50 72 6f 62 6c 65  tectSchemaProble
50e0: 6d 28 64 62 2c 20 22 66 6f 72 65 69 67 6e 20 6b  m(db, "foreign k
50f0: 65 79 20 69 73 20 6e 6f 74 20 75 6e 69 71 75 65  ey is not unique
5100: 22 2c 0a 20 20 20 20 22 53 45 4c 45 43 54 20 66  ",.    "SELECT f
5110: 6b 69 64 2c 20 66 72 6f 6d 5f 74 62 6c 20 22 0a  kid, from_tbl ".
5120: 20 20 20 20 22 46 52 4f 4d 20 74 65 6d 70 2e 66      "FROM temp.f
5130: 6b 65 79 32 20 22 0a 20 20 20 20 22 57 48 45 52  key2 ".    "WHER
5140: 45 20 4e 4f 54 20 45 58 49 53 54 53 20 28 53 45  E NOT EXISTS (SE
5150: 4c 45 43 54 20 31 20 22 0a 20 20 20 20 20 20 20  LECT 1 ".       
5160: 20 22 46 52 4f 4d 20 74 65 6d 70 2e 69 64 78 20   "FROM temp.idx 
5170: 57 48 45 52 45 20 74 61 62 6c 65 6e 61 6d 65 3d  WHERE tablename=
5180: 74 6f 5f 74 62 6c 20 41 4e 44 20 66 6b 65 79 32  to_tbl AND fkey2
5190: 2e 63 6f 6c 73 3d 3d 69 64 78 2e 63 6f 6c 73 22  .cols==idx.cols"
51a0: 0a 20 20 20 20 22 29 22 2c 20 70 48 61 73 45 72  .    ")", pHasEr
51b0: 72 6f 72 73 0a 20 20 29 3b 0a 20 20 69 66 28 20  rors.  );.  if( 
51c0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
51d0: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 65  return rc;..  re
51e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20  turn rc;.}..int 
51f0: 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63  main(int argc, c
5200: 68 61 72 20 2a 2a 61 72 67 76 29 7b 0a 20 20 73  har **argv){.  s
5210: 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 4f 70  qlite3 *db;.  Op
5220: 74 69 6f 6e 73 20 6f 70 74 20 3d 20 7b 30 2c 20  tions opt = {0, 
5230: 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 72 63 3b  0, 0};.  int rc;
5240: 0a 20 20 69 6e 74 20 68 61 73 45 72 72 6f 72 73  .  int hasErrors
5250: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 45   = 0;.  char *zE
5260: 72 72 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  rr = 0;.  const 
5270: 69 6e 74 20 65 6e 63 20 3d 20 53 51 4c 49 54 45  int enc = SQLITE
5280: 5f 55 54 46 38 3b 0a 0a 20 20 63 6f 6e 73 74 20  _UTF8;..  const 
5290: 63 68 61 72 20 2a 7a 53 71 6c 20 3d 0a 20 20 20  char *zSql =.   
52a0: 20 22 53 45 4c 45 43 54 20 6d 75 6c 74 69 72 65   "SELECT multire
52b0: 70 6c 61 63 65 28 27 22 0a 0a 20 20 20 20 20 20  place('"..      
52c0: 22 2d 2d 20 54 72 69 67 67 65 72 73 20 66 6f 72  "-- Triggers for
52d0: 20 66 6f 72 65 69 67 6e 20 6b 65 79 20 6d 61 70   foreign key map
52e0: 70 69 6e 67 3a 5c 6e 22 0a 20 20 20 20 20 20 22  ping:\n".      "
52f0: 2d 2d 5c 6e 22 0a 20 20 20 20 20 20 22 2d 2d 20  --\n".      "-- 
5300: 20 20 20 20 2f 66 72 6f 6d 5f 72 65 61 64 61 62      /from_readab
5310: 6c 65 2f 20 52 45 46 45 52 45 4e 43 45 53 20 2f  le/ REFERENCES /
5320: 74 6f 5f 72 65 61 64 61 62 6c 65 2f 5c 6e 22 0a  to_readable/\n".
5330: 20 20 20 20 20 20 22 2d 2d 20 20 20 20 20 6f 6e        "--     on
5340: 20 64 65 6c 65 74 65 20 2f 6f 6e 5f 64 65 6c 65   delete /on_dele
5350: 74 65 2f 5c 6e 22 0a 20 20 20 20 20 20 22 2d 2d  te/\n".      "--
5360: 20 20 20 20 20 6f 6e 20 75 70 64 61 74 65 20 2f       on update /
5370: 6f 6e 5f 75 70 64 61 74 65 2f 5c 6e 22 0a 20 20  on_update/\n".  
5380: 20 20 20 20 22 2d 2d 5c 6e 22 0a 0a 20 20 20 20      "--\n"..    
5390: 20 20 2f 2a 20 54 68 65 20 22 42 45 46 4f 52 45    /* The "BEFORE
53a0: 20 49 4e 53 45 52 54 20 4f 4e 20 3c 72 65 66 65   INSERT ON <refe
53b0: 72 65 6e 63 69 6e 67 3e 22 20 74 72 69 67 67 65  rencing>" trigge
53c0: 72 2e 20 54 68 69 73 20 74 72 69 67 67 65 72 27  r. This trigger'
53d0: 73 20 6a 6f 62 20 69 73 20 74 6f 0a 20 20 20 20  s job is to.    
53e0: 20 20 2a 2a 20 74 68 72 6f 77 20 61 6e 20 65 78    ** throw an ex
53f0: 63 65 70 74 69 6f 6e 20 69 66 20 74 68 65 20 75  ception if the u
5400: 73 65 72 20 74 72 69 65 73 20 74 6f 20 69 6e 73  ser tries to ins
5410: 65 72 74 20 61 20 72 6f 77 20 69 6e 74 6f 20 74  ert a row into t
5420: 68 65 0a 20 20 20 20 20 20 2a 2a 20 72 65 66 65  he.      ** refe
5430: 72 65 6e 63 69 6e 67 20 74 61 62 6c 65 20 66 6f  rencing table fo
5440: 72 20 77 68 69 63 68 20 74 68 65 72 65 20 69 73  r which there is
5450: 20 6e 6f 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e   no correspondin
5460: 67 20 72 6f 77 20 69 6e 0a 20 20 20 20 20 20 2a  g row in.      *
5470: 2a 20 74 68 65 20 72 65 66 65 72 65 6e 63 65 64  * the referenced
5480: 20 74 61 62 6c 65 2e 0a 20 20 20 20 20 20 2a 2f   table..      */
5490: 0a 20 20 20 20 20 20 22 43 52 45 41 54 45 20 54  .      "CREATE T
54a0: 52 49 47 47 45 52 20 2f 6e 61 6d 65 2f 5f 69 6e  RIGGER /name/_in
54b0: 73 65 72 74 5f 72 65 66 65 72 65 6e 63 69 6e 67  sert_referencing
54c0: 20 42 45 46 4f 52 45 20 49 4e 53 45 52 54 20 4f   BEFORE INSERT O
54d0: 4e 20 2f 74 62 6c 2f 20 57 48 45 4e 20 5c 6e 22  N /tbl/ WHEN \n"
54e0: 0a 20 20 20 20 20 20 22 20 20 20 20 2f 6b 65 79  .      "    /key
54f0: 5f 6e 6f 74 6e 75 6c 6c 2f 20 41 4e 44 20 4e 4f  _notnull/ AND NO
5500: 54 20 45 58 49 53 54 53 20 28 53 45 4c 45 43 54  T EXISTS (SELECT
5510: 20 31 20 46 52 4f 4d 20 2f 72 65 66 2f 20 57 48   1 FROM /ref/ WH
5520: 45 52 45 20 2f 63 6f 6e 64 31 2f 29 5c 6e 22 20  ERE /cond1/)\n" 
5530: 0a 20 20 20 20 20 20 22 42 45 47 49 4e 5c 6e 22  .      "BEGIN\n"
5540: 0a 20 20 20 20 20 20 20 20 22 20 20 53 45 4c 45  .        "  SELE
5550: 43 54 20 52 41 49 53 45 28 41 42 4f 52 54 2c 20  CT RAISE(ABORT, 
5560: 27 27 63 6f 6e 73 74 72 61 69 6e 74 20 66 61 69  ''constraint fai
5570: 6c 65 64 27 27 29 3b 5c 6e 22 0a 20 20 20 20 20  led'');\n".     
5580: 20 22 45 4e 44 3b 5c 6e 22 0a 0a 20 20 20 20 20   "END;\n"..     
5590: 20 2f 2a 20 54 68 65 20 22 42 45 46 4f 52 45 20   /* The "BEFORE 
55a0: 55 50 44 41 54 45 20 4f 4e 20 3c 72 65 66 65 72  UPDATE ON <refer
55b0: 65 6e 63 69 6e 67 3e 22 20 74 72 69 67 67 65 72  encing>" trigger
55c0: 2e 20 54 68 69 73 20 74 72 69 67 67 65 72 27 73  . This trigger's
55d0: 20 6a 6f 62 20 0a 20 20 20 20 20 20 2a 2a 20 69   job .      ** i
55e0: 73 20 74 6f 20 74 68 72 6f 77 20 61 6e 20 65 78  s to throw an ex
55f0: 63 65 70 74 69 6f 6e 20 69 66 20 74 68 65 20 75  ception if the u
5600: 73 65 72 20 74 72 69 65 73 20 74 6f 20 75 70 64  ser tries to upd
5610: 61 74 65 20 61 20 72 6f 77 20 69 6e 20 74 68 65  ate a row in the
5620: 0a 20 20 20 20 20 20 2a 2a 20 72 65 66 65 72 65  .      ** refere
5630: 6e 63 69 6e 67 20 74 61 62 6c 65 20 63 61 75 73  ncing table caus
5640: 69 6e 67 20 69 74 20 74 6f 20 63 6f 72 72 65 73  ing it to corres
5650: 70 6f 6e 64 20 74 6f 20 6e 6f 20 72 6f 77 20 69  pond to no row i
5660: 6e 20 74 68 65 0a 20 20 20 20 20 20 2a 2a 20 72  n the.      ** r
5670: 65 66 65 72 65 6e 63 65 64 20 74 61 62 6c 65 2e  eferenced table.
5680: 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
5690: 22 43 52 45 41 54 45 20 54 52 49 47 47 45 52 20  "CREATE TRIGGER 
56a0: 2f 6e 61 6d 65 2f 5f 75 70 64 61 74 65 5f 72 65  /name/_update_re
56b0: 66 65 72 65 6e 63 69 6e 67 20 42 45 46 4f 52 45  ferencing BEFORE
56c0: 5c 6e 22 0a 20 20 20 20 20 20 22 20 20 20 20 55  \n".      "    U
56d0: 50 44 41 54 45 20 4f 46 20 2f 72 6b 65 79 5f 6c  PDATE OF /rkey_l
56e0: 69 73 74 2f 20 4f 4e 20 2f 74 62 6c 2f 20 57 48  ist/ ON /tbl/ WH
56f0: 45 4e 20 5c 6e 22 0a 20 20 20 20 20 20 22 20 20  EN \n".      "  
5700: 20 20 2f 6b 65 79 5f 6e 6f 74 6e 75 6c 6c 2f 20    /key_notnull/ 
5710: 41 4e 44 20 5c 6e 22 0a 20 20 20 20 20 20 22 20  AND \n".      " 
5720: 20 20 20 4e 4f 54 20 45 58 49 53 54 53 20 28 53     NOT EXISTS (S
5730: 45 4c 45 43 54 20 31 20 46 52 4f 4d 20 2f 72 65  ELECT 1 FROM /re
5740: 66 2f 20 57 48 45 52 45 20 2f 63 6f 6e 64 31 2f  f/ WHERE /cond1/
5750: 29 5c 6e 22 20 0a 20 20 20 20 20 20 22 42 45 47  )\n" .      "BEG
5760: 49 4e 5c 6e 22 0a 20 20 20 20 20 20 20 20 22 20  IN\n".        " 
5770: 20 53 45 4c 45 43 54 20 52 41 49 53 45 28 41 42   SELECT RAISE(AB
5780: 4f 52 54 2c 20 27 27 63 6f 6e 73 74 72 61 69 6e  ORT, ''constrain
5790: 74 20 66 61 69 6c 65 64 27 27 29 3b 5c 6e 22 0a  t failed'');\n".
57a0: 20 20 20 20 20 20 22 45 4e 44 3b 5c 6e 22 0a 0a        "END;\n"..
57b0: 0a 20 20 20 20 20 20 2f 2a 20 54 68 65 20 22 42  .      /* The "B
57c0: 45 46 4f 52 45 20 44 45 4c 45 54 45 20 4f 4e 20  EFORE DELETE ON 
57d0: 3c 72 65 66 65 72 65 6e 63 65 64 3e 22 20 74 72  <referenced>" tr
57e0: 69 67 67 65 72 2e 20 54 68 69 73 20 74 72 69 67  igger. This trig
57f0: 67 65 72 27 73 20 6a 6f 62 20 0a 20 20 20 20 20  ger's job .     
5800: 20 2a 2a 20 69 73 20 74 6f 20 64 65 74 65 63 74   ** is to detect
5810: 20 77 68 65 6e 20 61 20 72 6f 77 20 69 73 20 64   when a row is d
5820: 65 6c 65 74 65 64 20 66 72 6f 6d 20 74 68 65 20  eleted from the 
5830: 72 65 66 65 72 65 6e 63 65 64 20 74 61 62 6c 65  referenced table
5840: 20 74 6f 20 0a 20 20 20 20 20 20 2a 2a 20 77 68   to .      ** wh
5850: 69 63 68 20 72 6f 77 73 20 69 6e 20 74 68 65 20  ich rows in the 
5860: 72 65 66 65 72 65 6e 63 69 6e 67 20 74 61 62 6c  referencing tabl
5870: 65 20 63 6f 72 72 65 73 70 6f 6e 64 2e 20 54 68  e correspond. Th
5880: 65 20 61 63 74 69 6f 6e 20 74 61 6b 65 6e 0a 20  e action taken. 
5890: 20 20 20 20 20 2a 2a 20 64 65 70 65 6e 64 73 20       ** depends 
58a0: 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  on the value of 
58b0: 74 68 65 20 27 4f 4e 20 44 45 4c 45 54 45 27 20  the 'ON DELETE' 
58c0: 63 6c 61 75 73 65 2e 0a 20 20 20 20 20 20 2a 2f  clause..      */
58d0: 0a 20 20 20 20 20 20 22 43 52 45 41 54 45 20 54  .      "CREATE T
58e0: 52 49 47 47 45 52 20 2f 6e 61 6d 65 2f 5f 64 65  RIGGER /name/_de
58f0: 6c 65 74 65 5f 72 65 66 65 72 65 6e 63 65 64 20  lete_referenced 
5900: 42 45 46 4f 52 45 20 44 45 4c 45 54 45 20 4f 4e  BEFORE DELETE ON
5910: 20 2f 72 65 66 2f 20 57 48 45 4e 5c 6e 22 0a 20   /ref/ WHEN\n". 
5920: 20 20 20 20 20 22 20 20 20 20 45 58 49 53 54 53       "    EXISTS
5930: 20 28 53 45 4c 45 43 54 20 31 20 46 52 4f 4d 20   (SELECT 1 FROM 
5940: 2f 74 62 6c 2f 20 57 48 45 52 45 20 2f 63 6f 6e  /tbl/ WHERE /con
5950: 64 32 2f 29 5c 6e 22 0a 20 20 20 20 20 20 22 42  d2/)\n".      "B
5960: 45 47 49 4e 5c 6e 22 0a 20 20 20 20 20 20 22 20  EGIN\n".      " 
5970: 20 2f 64 65 6c 65 74 65 5f 61 63 74 69 6f 6e 2f   /delete_action/
5980: 5c 6e 22 0a 20 20 20 20 20 20 22 45 4e 44 3b 5c  \n".      "END;\
5990: 6e 22 0a 0a 20 20 20 20 20 20 2f 2a 20 54 68 65  n"..      /* The
59a0: 20 22 42 45 46 4f 52 45 20 44 45 4c 45 54 45 20   "BEFORE DELETE 
59b0: 4f 4e 20 3c 72 65 66 65 72 65 6e 63 65 64 3e 22  ON <referenced>"
59c0: 20 74 72 69 67 67 65 72 2e 20 54 68 69 73 20 74   trigger. This t
59d0: 72 69 67 67 65 72 27 73 20 6a 6f 62 20 0a 20 20  rigger's job .  
59e0: 20 20 20 20 2a 2a 20 69 73 20 74 6f 20 64 65 74      ** is to det
59f0: 65 63 74 20 77 68 65 6e 20 74 68 65 20 6b 65 79  ect when the key
5a00: 20 63 6f 6c 75 6d 6e 73 20 6f 66 20 61 20 72 6f   columns of a ro
5a10: 77 20 69 6e 20 74 68 65 20 72 65 66 65 72 65 6e  w in the referen
5a20: 63 65 64 20 74 61 62 6c 65 20 0a 20 20 20 20 20  ced table .     
5a30: 20 2a 2a 20 74 6f 20 77 68 69 63 68 20 6f 6e 65   ** to which one
5a40: 20 6f 72 20 6d 6f 72 65 20 72 6f 77 73 20 69 6e   or more rows in
5a50: 20 74 68 65 20 72 65 66 65 72 65 6e 63 69 6e 67   the referencing
5a60: 20 74 61 62 6c 65 20 63 6f 72 72 65 73 70 6f 6e   table correspon
5a70: 64 20 61 72 65 0a 20 20 20 20 20 20 2a 2a 20 75  d are.      ** u
5a80: 70 64 61 74 65 64 2e 20 54 68 65 20 61 63 74 69  pdated. The acti
5a90: 6f 6e 20 74 61 6b 65 6e 20 64 65 70 65 6e 64 73  on taken depends
5aa0: 20 6f 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66   on the value of
5ab0: 20 74 68 65 20 27 4f 4e 20 55 50 44 41 54 45 27   the 'ON UPDATE'
5ac0: 20 0a 20 20 20 20 20 20 2a 2a 20 63 6c 61 75 73   .      ** claus
5ad0: 65 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  e..      */.    
5ae0: 20 20 22 43 52 45 41 54 45 20 54 52 49 47 47 45    "CREATE TRIGGE
5af0: 52 20 2f 6e 61 6d 65 2f 5f 75 70 64 61 74 65 5f  R /name/_update_
5b00: 72 65 66 65 72 65 6e 63 65 64 20 41 46 54 45 52  referenced AFTER
5b10: 5c 6e 22 0a 20 20 20 20 20 20 22 20 20 20 20 55  \n".      "    U
5b20: 50 44 41 54 45 20 4f 46 20 2f 66 6b 65 79 5f 6c  PDATE OF /fkey_l
5b30: 69 73 74 2f 20 4f 4e 20 2f 72 65 66 2f 20 57 48  ist/ ON /ref/ WH
5b40: 45 4e 20 5c 6e 22 0a 20 20 20 20 20 20 22 20 20  EN \n".      "  
5b50: 20 20 45 58 49 53 54 53 20 28 53 45 4c 45 43 54    EXISTS (SELECT
5b60: 20 31 20 46 52 4f 4d 20 2f 74 62 6c 2f 20 57 48   1 FROM /tbl/ WH
5b70: 45 52 45 20 2f 63 6f 6e 64 32 2f 29 5c 6e 22 0a  ERE /cond2/)\n".
5b80: 20 20 20 20 20 20 22 42 45 47 49 4e 5c 6e 22 0a        "BEGIN\n".
5b90: 20 20 20 20 20 20 22 20 20 2f 75 70 64 61 74 65        "  /update
5ba0: 5f 61 63 74 69 6f 6e 2f 5c 6e 22 0a 20 20 20 20  _action/\n".    
5bb0: 20 20 22 45 4e 44 3b 5c 6e 22 0a 20 20 20 20 22    "END;\n".    "
5bc0: 27 22 0a 0a 20 20 20 20 2f 2a 20 54 68 65 73 65  '"..    /* These
5bd0: 20 61 72 65 20 75 73 65 64 20 69 6e 20 74 68 65   are used in the
5be0: 20 53 51 4c 20 63 6f 6d 6d 65 6e 74 20 77 72 69   SQL comment wri
5bf0: 74 74 65 6e 20 61 62 6f 76 65 20 65 61 63 68 20  tten above each 
5c00: 73 65 74 20 6f 66 20 74 72 69 67 67 65 72 73 20  set of triggers 
5c10: 2a 2f 0a 20 20 20 20 22 2c 20 27 2f 66 72 6f 6d  */.    ", '/from
5c20: 5f 72 65 61 64 61 62 6c 65 2f 27 2c 20 20 66 72  _readable/',  fr
5c30: 6f 6d 5f 74 62 6c 20 7c 7c 20 27 28 27 20 7c 7c  om_tbl || '(' ||
5c40: 20 73 6a 28 66 72 6f 6d 5f 63 6f 6c 2c 20 27 2c   sj(from_col, ',
5c50: 20 27 29 20 7c 7c 20 27 29 27 22 0a 20 20 20 20   ') || ')'".    
5c60: 22 2c 20 27 2f 74 6f 5f 72 65 61 64 61 62 6c 65  ", '/to_readable
5c70: 2f 27 2c 20 20 20 20 74 6f 5f 74 62 6c 20 7c 7c  /',    to_tbl ||
5c80: 20 27 28 27 20 7c 7c 20 73 6a 28 74 6f 5f 63 6f   '(' || sj(to_co
5c90: 6c 2c 20 27 2c 20 27 29 20 7c 7c 20 27 29 27 22  l, ', ') || ')'"
5ca0: 0a 20 20 20 20 22 2c 20 27 2f 6f 6e 5f 64 65 6c  .    ", '/on_del
5cb0: 65 74 65 2f 27 2c 20 6f 6e 5f 64 65 6c 65 74 65  ete/', on_delete
5cc0: 22 0a 20 20 20 20 22 2c 20 27 2f 6f 6e 5f 75 70  ".    ", '/on_up
5cd0: 64 61 74 65 2f 27 2c 20 6f 6e 5f 75 70 64 61 74  date/', on_updat
5ce0: 65 22 0a 0a 20 20 20 20 22 2c 20 27 2f 6e 61 6d  e"..    ", '/nam
5cf0: 65 2f 27 2c 20 20 20 27 67 65 6e 66 6b 65 79 27  e/',   'genfkey'
5d00: 20 7c 7c 20 6d 69 6e 28 72 6f 77 69 64 29 22 0a   || min(rowid)".
5d10: 20 20 20 20 22 2c 20 27 2f 74 62 6c 2f 27 2c 20      ", '/tbl/', 
5d20: 20 20 20 64 71 28 66 72 6f 6d 5f 74 62 6c 29 22     dq(from_tbl)"
5d30: 0a 20 20 20 20 22 2c 20 27 2f 72 65 66 2f 27 2c  .    ", '/ref/',
5d40: 20 20 20 20 64 71 28 74 6f 5f 74 62 6c 29 22 0a      dq(to_tbl)".
5d50: 20 20 20 20 22 2c 20 27 2f 6b 65 79 5f 6e 6f 74      ", '/key_not
5d60: 6e 75 6c 6c 2f 27 2c 20 73 6a 28 27 6e 65 77 2e  null/', sj('new.
5d70: 27 20 7c 7c 20 64 71 28 66 72 6f 6d 5f 63 6f 6c  ' || dq(from_col
5d80: 29 20 7c 7c 20 27 20 49 53 20 4e 4f 54 20 4e 55  ) || ' IS NOT NU
5d90: 4c 4c 27 2c 20 27 20 41 4e 44 20 27 29 22 0a 0a  LL', ' AND ')"..
5da0: 20 20 20 20 22 2c 20 27 2f 66 6b 65 79 5f 6c 69      ", '/fkey_li
5db0: 73 74 2f 27 2c 20 73 6a 28 74 6f 5f 63 6f 6c 2c  st/', sj(to_col,
5dc0: 20 27 2c 20 27 29 22 0a 20 20 20 20 22 2c 20 27   ', ')".    ", '
5dd0: 2f 72 6b 65 79 5f 6c 69 73 74 2f 27 2c 20 73 6a  /rkey_list/', sj
5de0: 28 66 72 6f 6d 5f 63 6f 6c 2c 20 27 2c 20 27 29  (from_col, ', ')
5df0: 22 0a 0a 20 20 20 20 22 2c 20 27 2f 63 6f 6e 64  "..    ", '/cond
5e00: 31 2f 27 2c 20 20 73 6a 28 6d 75 6c 74 69 72 65  1/',  sj(multire
5e10: 70 6c 61 63 65 28 27 6e 65 77 2e 2f 66 72 6f 6d  place('new./from
5e20: 2f 20 3d 3d 20 2f 74 6f 2f 27 22 0a 20 20 20 20  / == /to/'".    
5e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 22                 "
5e40: 2c 20 27 2f 66 72 6f 6d 2f 27 2c 20 64 71 28 66  , '/from/', dq(f
5e50: 72 6f 6d 5f 63 6f 6c 29 22 0a 20 20 20 20 20 20  rom_col)".      
5e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 2c 20               ", 
5e70: 27 2f 74 6f 2f 27 2c 20 20 20 64 71 28 74 6f 5f  '/to/',   dq(to_
5e80: 63 6f 6c 29 22 0a 20 20 20 20 20 20 20 20 20 20  col)".          
5e90: 20 20 20 20 20 20 20 20 20 22 29 2c 20 27 20 41           "), ' A
5ea0: 4e 44 20 27 29 22 0a 20 20 20 20 22 2c 20 27 2f  ND ')".    ", '/
5eb0: 63 6f 6e 64 32 2f 27 2c 20 20 73 6a 28 6d 75 6c  cond2/',  sj(mul
5ec0: 74 69 72 65 70 6c 61 63 65 28 27 6f 6c 64 2e 2f  tireplace('old./
5ed0: 74 6f 2f 20 3d 3d 20 2f 66 72 6f 6d 2f 27 22 0a  to/ == /from/'".
5ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ef0: 20 20 20 22 2c 20 27 2f 66 72 6f 6d 2f 27 2c 20     ", '/from/', 
5f00: 64 71 28 66 72 6f 6d 5f 63 6f 6c 29 22 0a 20 20  dq(from_col)".  
5f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f20: 20 22 2c 20 27 2f 74 6f 2f 27 2c 20 20 20 64 71   ", '/to/',   dq
5f30: 28 74 6f 5f 63 6f 6c 29 22 0a 20 20 20 20 20 20  (to_col)".      
5f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 22 29 2c               "),
5f50: 20 27 20 41 4e 44 20 27 29 22 0a 0a 20 20 20 20   ' AND ')"..    
5f60: 22 2c 20 27 2f 75 70 64 61 74 65 5f 61 63 74 69  ", '/update_acti
5f70: 6f 6e 2f 27 2c 20 43 41 53 45 20 6f 6e 5f 75 70  on/', CASE on_up
5f80: 64 61 74 65 20 22 0a 20 20 20 20 20 20 22 57 48  date ".      "WH
5f90: 45 4e 20 27 53 45 54 20 4e 55 4c 4c 27 20 54 48  EN 'SET NULL' TH
5fa0: 45 4e 20 22 0a 20 20 20 20 20 20 20 20 22 6d 75  EN ".        "mu
5fb0: 6c 74 69 72 65 70 6c 61 63 65 28 27 55 50 44 41  ltireplace('UPDA
5fc0: 54 45 20 2f 74 62 6c 2f 20 53 45 54 20 2f 73 65  TE /tbl/ SET /se
5fd0: 74 6c 69 73 74 2f 20 57 48 45 52 45 20 2f 77 68  tlist/ WHERE /wh
5fe0: 65 72 65 2f 3b 27 20 22 0a 20 20 20 20 20 20 20  ere/;' ".       
5ff0: 20 22 2c 20 27 2f 73 65 74 6c 69 73 74 2f 27 2c   ", '/setlist/',
6000: 20 73 6a 28 66 72 6f 6d 5f 63 6f 6c 7c 7c 27 20   sj(from_col||' 
6010: 3d 20 4e 55 4c 4c 27 2c 27 2c 20 27 29 22 0a 20  = NULL',', ')". 
6020: 20 20 20 20 20 20 20 22 2c 20 27 2f 74 62 6c 2f         ", '/tbl/
6030: 27 2c 20 20 20 20 20 64 71 28 66 72 6f 6d 5f 74  ',     dq(from_t
6040: 62 6c 29 22 0a 20 20 20 20 20 20 20 20 22 2c 20  bl)".        ", 
6050: 27 2f 77 68 65 72 65 2f 27 2c 20 20 20 73 6a 28  '/where/',   sj(
6060: 66 72 6f 6d 5f 63 6f 6c 7c 7c 27 20 3d 20 6f 6c  from_col||' = ol
6070: 64 2e 27 7c 7c 64 71 28 74 6f 5f 63 6f 6c 29 2c  d.'||dq(to_col),
6080: 27 20 41 4e 44 20 27 29 22 0a 20 20 20 20 20 20  ' AND ')".      
6090: 20 20 22 29 22 0a 20 20 20 20 20 20 22 57 48 45    ")".      "WHE
60a0: 4e 20 27 43 41 53 43 41 44 45 27 20 54 48 45 4e  N 'CASCADE' THEN
60b0: 20 22 0a 20 20 20 20 20 20 20 20 22 6d 75 6c 74   ".        "mult
60c0: 69 72 65 70 6c 61 63 65 28 27 55 50 44 41 54 45  ireplace('UPDATE
60d0: 20 2f 74 62 6c 2f 20 53 45 54 20 2f 73 65 74 6c   /tbl/ SET /setl
60e0: 69 73 74 2f 20 57 48 45 52 45 20 2f 77 68 65 72  ist/ WHERE /wher
60f0: 65 2f 3b 27 20 22 0a 20 20 20 20 20 20 20 20 22  e/;' ".        "
6100: 2c 20 27 2f 73 65 74 6c 69 73 74 2f 27 2c 20 73  , '/setlist/', s
6110: 6a 28 64 71 28 66 72 6f 6d 5f 63 6f 6c 29 7c 7c  j(dq(from_col)||
6120: 27 20 3d 20 6e 65 77 2e 27 7c 7c 64 71 28 74 6f  ' = new.'||dq(to
6130: 5f 63 6f 6c 29 2c 27 2c 20 27 29 22 0a 20 20 20  _col),', ')".   
6140: 20 20 20 20 20 22 2c 20 27 2f 74 62 6c 2f 27 2c       ", '/tbl/',
6150: 20 20 20 20 20 64 71 28 66 72 6f 6d 5f 74 62 6c       dq(from_tbl
6160: 29 22 0a 20 20 20 20 20 20 20 20 22 2c 20 27 2f  )".        ", '/
6170: 77 68 65 72 65 2f 27 2c 20 20 20 73 6a 28 64 71  where/',   sj(dq
6180: 28 66 72 6f 6d 5f 63 6f 6c 29 7c 7c 27 20 3d 20  (from_col)||' = 
6190: 6f 6c 64 2e 27 7c 7c 64 71 28 74 6f 5f 63 6f 6c  old.'||dq(to_col
61a0: 29 2c 27 20 41 4e 44 20 27 29 22 0a 20 20 20 20  ),' AND ')".    
61b0: 20 20 20 20 22 29 22 0a 20 20 20 20 20 20 22 45      ")".      "E
61c0: 4c 53 45 20 22 0a 20 20 20 20 20 20 22 20 20 27  LSE ".      "  '
61d0: 53 45 4c 45 43 54 20 52 41 49 53 45 28 41 42 4f  SELECT RAISE(ABO
61e0: 52 54 2c 20 27 27 63 6f 6e 73 74 72 61 69 6e 74  RT, ''constraint
61f0: 20 66 61 69 6c 65 64 27 27 29 3b 27 22 0a 20 20   failed'');'".  
6200: 20 20 20 20 22 45 4e 44 20 22 0a 0a 20 20 20 20      "END "..    
6210: 22 2c 20 27 2f 64 65 6c 65 74 65 5f 61 63 74 69  ", '/delete_acti
6220: 6f 6e 2f 27 2c 20 43 41 53 45 20 6f 6e 5f 64 65  on/', CASE on_de
6230: 6c 65 74 65 20 22 0a 20 20 20 20 20 20 22 57 48  lete ".      "WH
6240: 45 4e 20 27 53 45 54 20 4e 55 4c 4c 27 20 54 48  EN 'SET NULL' TH
6250: 45 4e 20 22 0a 20 20 20 20 20 20 20 20 22 6d 75  EN ".        "mu
6260: 6c 74 69 72 65 70 6c 61 63 65 28 27 55 50 44 41  ltireplace('UPDA
6270: 54 45 20 2f 74 62 6c 2f 20 53 45 54 20 2f 73 65  TE /tbl/ SET /se
6280: 74 6c 69 73 74 2f 20 57 48 45 52 45 20 2f 77 68  tlist/ WHERE /wh
6290: 65 72 65 2f 3b 27 20 22 0a 20 20 20 20 20 20 20  ere/;' ".       
62a0: 20 22 2c 20 27 2f 73 65 74 6c 69 73 74 2f 27 2c   ", '/setlist/',
62b0: 20 73 6a 28 66 72 6f 6d 5f 63 6f 6c 7c 7c 27 20   sj(from_col||' 
62c0: 3d 20 4e 55 4c 4c 27 2c 27 2c 20 27 29 22 0a 20  = NULL',', ')". 
62d0: 20 20 20 20 20 20 20 22 2c 20 27 2f 74 62 6c 2f         ", '/tbl/
62e0: 27 2c 20 20 20 20 20 64 71 28 66 72 6f 6d 5f 74  ',     dq(from_t
62f0: 62 6c 29 22 0a 20 20 20 20 20 20 20 20 22 2c 20  bl)".        ", 
6300: 27 2f 77 68 65 72 65 2f 27 2c 20 20 20 73 6a 28  '/where/',   sj(
6310: 66 72 6f 6d 5f 63 6f 6c 7c 7c 27 20 3d 20 6f 6c  from_col||' = ol
6320: 64 2e 27 7c 7c 64 71 28 74 6f 5f 63 6f 6c 29 2c  d.'||dq(to_col),
6330: 27 20 41 4e 44 20 27 29 22 0a 20 20 20 20 20 20  ' AND ')".      
6340: 20 20 22 29 22 0a 20 20 20 20 20 20 22 57 48 45    ")".      "WHE
6350: 4e 20 27 43 41 53 43 41 44 45 27 20 54 48 45 4e  N 'CASCADE' THEN
6360: 20 22 0a 20 20 20 20 20 20 20 20 22 6d 75 6c 74   ".        "mult
6370: 69 72 65 70 6c 61 63 65 28 27 44 45 4c 45 54 45  ireplace('DELETE
6380: 20 46 52 4f 4d 20 2f 74 62 6c 2f 20 57 48 45 52   FROM /tbl/ WHER
6390: 45 20 2f 77 68 65 72 65 2f 3b 27 20 22 0a 20 20  E /where/;' ".  
63a0: 20 20 20 20 20 20 22 2c 20 27 2f 74 62 6c 2f 27        ", '/tbl/'
63b0: 2c 20 20 20 20 20 64 71 28 66 72 6f 6d 5f 74 62  ,     dq(from_tb
63c0: 6c 29 22 0a 20 20 20 20 20 20 20 20 22 2c 20 27  l)".        ", '
63d0: 2f 77 68 65 72 65 2f 27 2c 20 20 20 73 6a 28 64  /where/',   sj(d
63e0: 71 28 66 72 6f 6d 5f 63 6f 6c 29 7c 7c 27 20 3d  q(from_col)||' =
63f0: 20 6f 6c 64 2e 27 7c 7c 64 71 28 74 6f 5f 63 6f   old.'||dq(to_co
6400: 6c 29 2c 27 20 41 4e 44 20 27 29 22 0a 20 20 20  l),' AND ')".   
6410: 20 20 20 20 20 22 29 22 0a 20 20 20 20 20 20 22       ")".      "
6420: 45 4c 53 45 20 22 0a 20 20 20 20 20 20 22 20 20  ELSE ".      "  
6430: 27 53 45 4c 45 43 54 20 52 41 49 53 45 28 41 42  'SELECT RAISE(AB
6440: 4f 52 54 2c 20 27 27 63 6f 6e 73 74 72 61 69 6e  ORT, ''constrain
6450: 74 20 66 61 69 6c 65 64 27 27 29 3b 27 22 0a 20  t failed'');'". 
6460: 20 20 20 20 20 22 45 4e 44 20 22 0a 0a 20 20 20       "END "..   
6470: 20 22 29 20 46 52 4f 4d 20 74 65 6d 70 2e 66 6b   ") FROM temp.fk
6480: 65 79 20 22 0a 20 20 20 20 22 47 52 4f 55 50 20  ey ".    "GROUP 
6490: 42 59 20 66 72 6f 6d 5f 74 62 6c 2c 20 66 6b 69  BY from_tbl, fki
64a0: 64 22 0a 20 20 3b 0a 0a 20 20 70 72 6f 63 65 73  d".  ;..  proces
64b0: 73 43 6d 64 4c 69 6e 65 28 61 72 67 63 2c 20 61  sCmdLine(argc, a
64c0: 72 67 76 2c 20 26 6f 70 74 29 3b 0a 0a 20 20 2f  rgv, &opt);..  /
64d0: 2a 20 4f 70 65 6e 20 74 68 65 20 64 61 74 61 62  * Open the datab
64e0: 61 73 65 20 68 61 6e 64 6c 65 2e 20 2a 2f 0a 20  ase handle. */. 
64f0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 6f 70   rc = sqlite3_op
6500: 65 6e 5f 76 32 28 6f 70 74 2e 7a 44 62 2c 20 26  en_v2(opt.zDb, &
6510: 64 62 2c 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  db, SQLITE_OPEN_
6520: 52 45 41 44 4f 4e 4c 59 2c 20 30 29 3b 0a 20 20  READONLY, 0);.  
6530: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
6540: 4b 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66  K ){.    fprintf
6550: 28 73 74 64 65 72 72 2c 20 22 45 72 72 6f 72 20  (stderr, "Error 
6560: 6f 70 65 6e 69 6e 67 20 64 61 74 61 62 61 73 65  opening database
6570: 20 66 69 6c 65 3a 20 25 73 5c 6e 22 2c 20 73 71   file: %s\n", sq
6580: 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29  lite3_errmsg(db)
6590: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 2d 31  );.    return -1
65a0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 72 65 61  ;.  }..  /* Crea
65b0: 74 65 20 74 68 65 20 73 70 65 63 69 61 6c 20 73  te the special s
65c0: 63 61 6c 61 72 20 61 6e 64 20 61 67 67 72 65 67  calar and aggreg
65d0: 61 74 65 20 66 75 6e 63 74 69 6f 6e 73 20 75 73  ate functions us
65e0: 65 64 20 62 79 20 74 68 69 73 20 70 72 6f 67 72  ed by this progr
65f0: 61 6d 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  am. */.  sqlite3
6600: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
6610: 28 64 62 2c 20 22 64 71 22 2c 20 31 2c 20 65 6e  (db, "dq", 1, en
6620: 63 2c 20 30 2c 20 64 6f 75 62 6c 65 71 75 6f 74  c, 0, doublequot
6630: 65 2c 20 30 2c 20 30 29 3b 0a 20 20 73 71 6c 69  e, 0, 0);.  sqli
6640: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
6650: 69 6f 6e 28 64 62 2c 20 22 6d 75 6c 74 69 72 65  ion(db, "multire
6660: 70 6c 61 63 65 22 2c 20 2d 31 2c 20 65 6e 63 2c  place", -1, enc,
6670: 20 64 62 2c 20 6d 75 6c 74 69 72 65 70 6c 61 63   db, multireplac
6680: 65 2c 20 30 2c 20 30 29 3b 0a 20 20 73 71 6c 69  e, 0, 0);.  sqli
6690: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
66a0: 69 6f 6e 28 64 62 2c 20 22 73 6a 22 2c 20 32 2c  ion(db, "sj", 2,
66b0: 20 65 6e 63 2c 20 30 2c 20 30 2c 20 6a 6f 69 6e   enc, 0, 0, join
66c0: 53 74 65 70 2c 20 6a 6f 69 6e 46 69 6e 61 6c 69  Step, joinFinali
66d0: 7a 65 29 3b 0a 0a 20 20 2f 2a 20 49 6e 73 74 61  ze);..  /* Insta
66e0: 6c 6c 20 74 68 65 20 22 73 63 68 65 6d 61 22 20  ll the "schema" 
66f0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
6700: 64 75 6c 65 20 2a 2f 0a 20 20 69 6e 73 74 61 6c  dule */.  instal
6710: 6c 53 63 68 65 6d 61 4d 6f 64 75 6c 65 28 64 62  lSchemaModule(db
6720: 29 3b 0a 0a 20 20 2f 2a 20 43 72 65 61 74 65 20  );..  /* Create 
6730: 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 61 20 74  and populate a t
6740: 65 6d 70 20 74 61 62 6c 65 20 77 69 74 68 20 74  emp table with t
6750: 68 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 72  he information r
6760: 65 71 75 69 72 65 64 20 74 6f 0a 20 20 2a 2a 20  equired to.  ** 
6770: 62 75 69 6c 64 20 74 68 65 20 66 6f 72 65 69 67  build the foreig
6780: 6e 20 6b 65 79 20 74 72 69 67 67 65 72 73 2e 20  n key triggers. 
6790: 53 65 65 20 66 75 6e 63 74 69 6f 6e 20 70 6f 70  See function pop
67a0: 75 6c 61 74 65 54 65 6d 70 54 61 62 6c 65 28 29  ulateTempTable()
67b0: 0a 20 20 2a 2a 20 66 6f 72 20 64 65 74 61 69 6c  .  ** for detail
67c0: 73 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 70  s..  */.  rc = p
67d0: 6f 70 75 6c 61 74 65 54 65 6d 70 54 61 62 6c 65  opulateTempTable
67e0: 28 64 62 2c 20 26 7a 45 72 72 2c 20 26 68 61 73  (db, &zErr, &has
67f0: 45 72 72 6f 72 73 29 3b 0a 20 20 69 66 28 20 72  Errors);.  if( r
6800: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
6810: 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65      fprintf(stde
6820: 72 72 2c 20 22 45 72 72 6f 72 20 72 65 61 64 69  rr, "Error readi
6830: 6e 67 20 64 61 74 61 62 61 73 65 3a 20 25 73 5c  ng database: %s\
6840: 6e 22 2c 20 7a 45 72 72 29 3b 0a 20 20 20 20 72  n", zErr);.    r
6850: 65 74 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20  eturn -1;.  }.  
6860: 69 66 28 20 68 61 73 45 72 72 6f 72 73 20 26 26  if( hasErrors &&
6870: 20 6f 70 74 2e 69 67 6e 6f 72 65 45 72 72 6f 72   opt.ignoreError
6880: 73 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  s==0 ){.    retu
6890: 72 6e 20 2d 31 3b 0a 20 20 7d 0a 0a 20 20 70 72  rn -1;.  }..  pr
68a0: 69 6e 74 66 28 22 42 45 47 49 4e 3b 5c 6e 22 29  intf("BEGIN;\n")
68b0: 3b 0a 0a 20 20 2f 2a 20 55 6e 6c 65 73 73 20 74  ;..  /* Unless t
68c0: 68 65 20 2d 2d 6e 6f 2d 64 72 6f 70 20 6f 70 74  he --no-drop opt
68d0: 69 6f 6e 20 77 61 73 20 73 70 65 63 69 66 69 65  ion was specifie
68e0: 64 2c 20 67 65 6e 65 72 61 74 65 20 44 52 4f 50  d, generate DROP
68f0: 20 54 52 49 47 47 45 52 0a 20 20 2a 2a 20 73 74   TRIGGER.  ** st
6900: 61 74 65 6d 65 6e 74 73 20 74 6f 20 64 72 6f 70  atements to drop
6910: 20 61 6e 79 20 74 72 69 67 67 65 72 73 20 69 6e   any triggers in
6920: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 67 65   the database ge
6930: 6e 65 72 61 74 65 64 20 62 79 20 61 0a 20 20 2a  nerated by a.  *
6940: 2a 20 70 72 65 76 69 6f 75 73 20 72 75 6e 20 6f  * previous run o
6950: 66 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a  f this program..
6960: 20 20 2a 2f 0a 20 20 69 66 28 20 6f 70 74 2e 6e    */.  if( opt.n
6970: 6f 44 72 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20  oDrop==0 ){.    
6980: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
6990: 63 28 64 62 2c 20 0a 20 20 20 20 20 20 22 53 45  c(db, .      "SE
69a0: 4c 45 43 54 20 27 44 52 4f 50 20 54 52 49 47 47  LECT 'DROP TRIGG
69b0: 45 52 27 20 7c 7c 20 27 20 27 20 7c 7c 20 64 71  ER' || ' ' || dq
69c0: 28 6e 61 6d 65 29 20 7c 7c 20 27 3b 27 22 0a 20  (name) || ';'". 
69d0: 20 20 20 20 20 22 46 52 4f 4d 20 73 71 6c 69 74       "FROM sqlit
69e0: 65 5f 6d 61 73 74 65 72 20 22 0a 20 20 20 20 20  e_master ".     
69f0: 20 22 57 48 45 52 45 20 74 79 70 65 3d 27 74 72   "WHERE type='tr
6a00: 69 67 67 65 72 27 20 41 4e 44 20 73 75 62 73 74  igger' AND subst
6a10: 72 28 6e 61 6d 65 2c 20 30 2c 20 37 29 20 3d 3d  r(name, 0, 7) ==
6a20: 20 27 67 65 6e 66 6b 65 79 27 22 0a 20 20 20 20   'genfkey'".    
6a30: 20 20 2c 20 70 72 69 6e 74 53 74 72 69 6e 67 2c    , printString,
6a40: 20 30 2c 20 30 0a 20 20 20 20 29 3b 0a 20 20 20   0, 0.    );.   
6a50: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
6a60: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73  OK ){.      cons
6a70: 74 20 63 68 61 72 20 2a 7a 4d 73 67 20 3d 20 73  t char *zMsg = s
6a80: 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62  qlite3_errmsg(db
6a90: 29 3b 0a 20 20 20 20 20 20 66 70 72 69 6e 74 66  );.      fprintf
6aa0: 28 73 74 64 65 72 72 2c 20 22 47 65 6e 65 72 61  (stderr, "Genera
6ab0: 74 69 6e 67 20 64 72 6f 70 20 74 72 69 67 67 65  ting drop trigge
6ac0: 72 73 20 66 61 69 6c 65 64 3a 20 25 73 5c 6e 22  rs failed: %s\n"
6ad0: 2c 20 7a 4d 73 67 29 3b 0a 20 20 20 20 20 20 72  , zMsg);.      r
6ae0: 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20 7d 0a  eturn -1;.    }.
6af0: 20 20 7d 0a 0a 20 20 2f 2a 20 52 75 6e 20 74 68    }..  /* Run th
6b00: 65 20 6d 61 69 6e 20 71 75 65 72 79 20 74 6f 20  e main query to 
6b10: 63 72 65 61 74 65 20 74 68 65 20 74 72 69 67 67  create the trigg
6b20: 65 72 20 64 65 66 69 6e 69 74 69 6f 6e 73 2e 20  er definitions. 
6b30: 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  */.  rc = sqlite
6b40: 33 5f 65 78 65 63 28 64 62 2c 20 7a 53 71 6c 2c  3_exec(db, zSql,
6b50: 20 70 72 69 6e 74 53 74 72 69 6e 67 2c 20 30 2c   printString, 0,
6b60: 20 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53   0);.  if( rc!=S
6b70: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6b80: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
6b90: 22 47 65 6e 65 72 61 74 69 6e 67 20 74 72 69 67  "Generating trig
6ba0: 67 65 72 73 20 66 61 69 6c 65 64 3a 20 25 73 5c  gers failed: %s\
6bb0: 6e 22 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d  n", sqlite3_errm
6bc0: 73 67 28 64 62 29 29 3b 0a 20 20 20 20 72 65 74  sg(db));.    ret
6bd0: 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 0a 20 20 70  urn -1;.  }..  p
6be0: 72 69 6e 74 66 28 22 43 4f 4d 4d 49 54 3b 5c 6e  rintf("COMMIT;\n
6bf0: 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a  ");.  return 0;.
6c00: 7d 0a 0a                                         }..