/ Hex Artifact Content
Login

Artifact 9c89a4f1ed6bb13af0ed805b8d782bd83fcd57e3:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4a 61 6e 75 61  /*.** 2006 Janua
0010: 72 79 20 30 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ry 09.**.** 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 43 6f 64 65 20 66 6f 72  ****.** Code for
0180: 20 74 65 73 74 69 6e 67 20 74 68 65 20 63 6c 69   testing the cli
0190: 65 6e 74 2f 73 65 72 76 65 72 20 76 65 72 73 69  ent/server versi
01a0: 6f 6e 20 6f 66 20 74 68 65 20 53 51 4c 69 74 65  on of the SQLite
01b0: 20 6c 69 62 72 61 72 79 2e 0a 2a 2a 20 44 65 72   library..** Der
01c0: 69 76 65 64 20 66 72 6f 6d 20 74 65 73 74 34 2e  ived from test4.
01d0: 63 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 22  c..*/.#include "
01e0: 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23 69 6e  sqliteInt.h".#in
01f0: 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a 0a 2f  clude "tcl.h"../
0200: 2a 0a 2a 2a 20 54 68 69 73 20 74 65 73 74 20 6f  *.** This test o
0210: 6e 6c 79 20 77 6f 72 6b 73 20 6f 6e 20 55 4e 49  nly works on UNI
0220: 58 20 77 69 74 68 20 61 20 53 51 4c 49 54 45 5f  X with a SQLITE_
0230: 54 48 52 45 41 44 53 41 46 45 20 62 75 69 6c 64  THREADSAFE build
0240: 20 74 68 61 74 20 69 6e 63 6c 75 64 65 73 0a 2a   that includes.*
0250: 2a 20 74 68 65 20 53 51 4c 49 54 45 5f 53 45 52  * the SQLITE_SER
0260: 56 45 52 20 6f 70 74 69 6f 6e 2e 0a 2a 2f 0a 23  VER option..*/.#
0270: 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  if defined(SQLIT
0280: 45 5f 53 45 52 56 45 52 29 20 26 26 20 21 64 65  E_SERVER) && !de
0290: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 4f 4d 49  fined(SQLITE_OMI
02a0: 54 5f 53 48 41 52 45 44 5f 43 41 43 48 45 29 20  T_SHARED_CACHE) 
02b0: 26 26 20 5c 0a 20 20 20 20 53 51 4c 49 54 45 5f  && \.    SQLITE_
02c0: 4f 53 5f 55 4e 49 58 20 26 26 20 53 51 4c 49 54  OS_UNIX && SQLIT
02d0: 45 5f 54 48 52 45 41 44 53 41 46 45 0a 0a 23 69  E_THREADSAFE..#i
02e0: 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68  nclude <stdlib.h
02f0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69  >.#include <stri
0300: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  ng.h>.#include <
0310: 70 74 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c  pthread.h>.#incl
0320: 75 64 65 20 3c 73 63 68 65 64 2e 68 3e 0a 23 69  ude <sched.h>.#i
0330: 6e 63 6c 75 64 65 20 3c 63 74 79 70 65 2e 68 3e  nclude <ctype.h>
0340: 0a 0a 2f 2a 0a 2a 2a 20 49 6e 74 65 72 66 61 63  ../*.** Interfac
0350: 65 73 20 64 65 66 69 6e 65 64 20 69 6e 20 73 65  es defined in se
0360: 72 76 65 72 2e 63 0a 2a 2f 0a 69 6e 74 20 73 71  rver.c.*/.int sq
0370: 6c 69 74 65 33 5f 63 6c 69 65 6e 74 5f 6f 70 65  lite3_client_ope
0380: 6e 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 73  n(const char*, s
0390: 71 6c 69 74 65 33 2a 2a 29 3b 0a 69 6e 74 20 73  qlite3**);.int s
03a0: 71 6c 69 74 65 33 5f 63 6c 69 65 6e 74 5f 70 72  qlite3_client_pr
03b0: 65 70 61 72 65 28 73 71 6c 69 74 65 33 2a 2c 63  epare(sqlite3*,c
03c0: 6f 6e 73 74 20 63 68 61 72 2a 2c 69 6e 74 2c 0a  onst char*,int,.
03d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
03e0: 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
03f0: 65 33 5f 73 74 6d 74 2a 2a 2c 63 6f 6e 73 74 20  e3_stmt**,const 
0400: 63 68 61 72 2a 2a 29 3b 0a 69 6e 74 20 73 71 6c  char**);.int sql
0410: 69 74 65 33 5f 63 6c 69 65 6e 74 5f 73 74 65 70  ite3_client_step
0420: 28 73 71 6c 69 74 65 33 5f 73 74 6d 74 2a 29 3b  (sqlite3_stmt*);
0430: 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 63 6c 69  .int sqlite3_cli
0440: 65 6e 74 5f 72 65 73 65 74 28 73 71 6c 69 74 65  ent_reset(sqlite
0450: 33 5f 73 74 6d 74 2a 29 3b 0a 69 6e 74 20 73 71  3_stmt*);.int sq
0460: 6c 69 74 65 33 5f 63 6c 69 65 6e 74 5f 66 69 6e  lite3_client_fin
0470: 61 6c 69 7a 65 28 73 71 6c 69 74 65 33 5f 73 74  alize(sqlite3_st
0480: 6d 74 2a 29 3b 0a 69 6e 74 20 73 71 6c 69 74 65  mt*);.int sqlite
0490: 33 5f 63 6c 69 65 6e 74 5f 63 6c 6f 73 65 28 73  3_client_close(s
04a0: 71 6c 69 74 65 33 2a 29 3b 0a 69 6e 74 20 73 71  qlite3*);.int sq
04b0: 6c 69 74 65 33 5f 73 65 72 76 65 72 5f 73 74 61  lite3_server_sta
04c0: 72 74 28 76 6f 69 64 29 3b 0a 69 6e 74 20 73 71  rt(void);.int sq
04d0: 6c 69 74 65 33 5f 73 65 72 76 65 72 5f 73 74 6f  lite3_server_sto
04e0: 70 28 76 6f 69 64 29 3b 0a 76 6f 69 64 20 73 71  p(void);.void sq
04f0: 6c 69 74 65 33 5f 73 65 72 76 65 72 5f 73 74 61  lite3_server_sta
0500: 72 74 32 28 69 6e 74 20 2a 70 6e 44 65 63 72 29  rt2(int *pnDecr)
0510: 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 74 68  ;../*.** Each th
0520: 72 65 61 64 20 69 73 20 63 6f 6e 74 72 6f 6c 6c  read is controll
0530: 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63  ed by an instanc
0540: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
0550: 6e 67 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e  ng.** structure.
0560: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
0570: 63 74 20 54 68 72 65 61 64 20 54 68 72 65 61 64  ct Thread Thread
0580: 3b 0a 73 74 72 75 63 74 20 54 68 72 65 61 64 20  ;.struct Thread 
0590: 7b 0a 20 20 2f 2a 20 54 68 65 20 66 69 72 73 74  {.  /* The first
05a0: 20 67 72 6f 75 70 20 6f 66 20 66 69 65 6c 64 73   group of fields
05b0: 20 61 72 65 20 77 72 69 74 61 62 6c 65 20 62 79   are writable by
05c0: 20 74 68 65 20 73 75 70 65 72 76 69 73 6f 72 20   the supervisor 
05d0: 74 68 72 65 61 64 0a 20 20 2a 2a 20 61 6e 64 20  thread.  ** and 
05e0: 72 65 61 64 2d 6f 6e 6c 79 20 74 6f 20 74 68 65  read-only to the
05f0: 20 63 6c 69 65 6e 74 20 74 68 72 65 61 64 73 0a   client threads.
0600: 20 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 46 69    */.  char *zFi
0610: 6c 65 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  lename;         
0620: 2f 2a 20 4e 61 6d 65 20 6f 66 20 64 61 74 61 62  /* Name of datab
0630: 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 76 6f  ase file */.  vo
0640: 69 64 20 28 2a 78 4f 70 29 28 54 68 72 65 61 64  id (*xOp)(Thread
0650: 2a 29 3b 20 20 20 20 2f 2a 20 6e 65 78 74 20 6f  *);    /* next o
0660: 70 65 72 61 74 69 6f 6e 20 74 6f 20 64 6f 20 2a  peration to do *
0670: 2f 0a 20 20 63 68 61 72 20 2a 7a 41 72 67 3b 20  /.  char *zArg; 
0680: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0690: 61 72 67 75 6d 65 6e 74 20 75 73 61 62 6c 65 20  argument usable 
06a0: 62 79 20 78 4f 70 20 2a 2f 0a 20 20 76 6f 6c 61  by xOp */.  vola
06b0: 74 69 6c 65 20 69 6e 74 20 6f 70 6e 75 6d 3b 20  tile int opnum; 
06c0: 20 20 20 20 20 2f 2a 20 4f 70 65 72 61 74 69 6f       /* Operatio
06d0: 6e 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 76 6f  n number */.  vo
06e0: 6c 61 74 69 6c 65 20 69 6e 74 20 62 75 73 79 3b  latile int busy;
06f0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
0700: 66 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73  f this thread is
0710: 20 69 6e 20 75 73 65 20 2a 2f 0a 0a 20 20 2f 2a   in use */..  /*
0720: 20 54 68 65 20 6e 65 78 74 20 67 72 6f 75 70 20   The next group 
0730: 6f 66 20 66 69 65 6c 64 73 20 61 72 65 20 77 72  of fields are wr
0740: 69 74 61 62 6c 65 20 62 79 20 74 68 65 20 63 6c  itable by the cl
0750: 69 65 6e 74 20 74 68 72 65 61 64 73 20 0a 20 20  ient threads .  
0760: 2a 2a 20 62 75 74 20 72 65 61 64 2d 6f 6e 6c 79  ** but read-only
0770: 20 74 6f 20 74 68 65 20 73 75 70 65 72 76 69 73   to the supervis
0780: 65 72 20 74 68 72 65 61 64 2e 0a 20 20 2a 2f 0a  er thread..  */.
0790: 20 20 76 6f 6c 61 74 69 6c 65 20 69 6e 74 20 63    volatile int c
07a0: 6f 6d 70 6c 65 74 65 64 3b 20 20 2f 2a 20 4e 75  ompleted;  /* Nu
07b0: 6d 62 65 72 20 6f 66 20 6f 70 65 72 61 74 69 6f  mber of operatio
07c0: 6e 73 20 63 6f 6d 70 6c 65 74 65 64 20 2a 2f 0a  ns completed */.
07d0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20 20    sqlite3 *db;  
07e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 70             /* Op
07f0: 65 6e 20 64 61 74 61 62 61 73 65 20 2a 2f 0a 20  en database */. 
0800: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
0810: 53 74 6d 74 3b 20 20 20 20 20 2f 2a 20 50 65 6e  Stmt;     /* Pen
0820: 64 69 6e 67 20 6f 70 65 72 61 74 69 6f 6e 20 2a  ding operation *
0830: 2f 0a 20 20 63 68 61 72 20 2a 7a 45 72 72 3b 20  /.  char *zErr; 
0840: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0850: 6f 70 65 72 61 74 69 6f 6e 20 65 72 72 6f 72 20  operation error 
0860: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 74 61 74  */.  char *zStat
0870: 69 63 45 72 72 3b 20 20 20 20 20 20 20 20 2f 2a  icErr;        /*
0880: 20 53 74 61 74 69 63 20 65 72 72 6f 72 20 6d 65   Static error me
0890: 73 73 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 72  ssage */.  int r
08a0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
08b0: 20 20 20 20 2f 2a 20 6f 70 65 72 61 74 69 6f 6e      /* operation
08c0: 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   return code */.
08d0: 20 20 69 6e 74 20 61 72 67 63 3b 20 20 20 20 20    int argc;     
08e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 75             /* nu
08f0: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
0900: 69 6e 20 72 65 73 75 6c 74 20 2a 2f 0a 20 20 63  in result */.  c
0910: 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67 76 5b  onst char *argv[
0920: 31 30 30 5d 3b 20 20 20 2f 2a 20 72 65 73 75 6c  100];   /* resul
0930: 74 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 63  t columns */.  c
0940: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6c 76 5b  onst char *colv[
0950: 31 30 30 5d 3b 20 20 20 2f 2a 20 72 65 73 75 6c  100];   /* resul
0960: 74 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a  t column names *
0970: 2f 0a 0a 20 20 2f 2a 20 49 6e 69 74 69 61 6c 69  /..  /* Initiali
0980: 7a 65 64 20 74 6f 20 31 20 62 79 20 74 68 65 20  zed to 1 by the 
0990: 73 75 70 65 72 76 69 73 6f 72 20 74 68 72 65 61  supervisor threa
09a0: 64 20 77 68 65 6e 20 74 68 65 20 63 6c 69 65 6e  d when the clien
09b0: 74 20 69 73 20 0a 20 20 2a 2a 20 63 72 65 61 74  t is .  ** creat
09c0: 65 64 2c 20 61 6e 64 20 74 68 65 6e 20 64 65 65  ed, and then dee
09d0: 6d 65 64 20 72 65 61 64 2d 6f 6e 6c 79 20 74 6f  med read-only to
09e0: 20 74 68 65 20 73 75 70 65 72 76 69 73 6f 72 20   the supervisor 
09f0: 74 68 72 65 61 64 2e 20 0a 20 20 2a 2a 20 49 73  thread. .  ** Is
0a00: 20 73 65 74 20 74 6f 20 30 20 62 79 20 74 68 65   set to 0 by the
0a10: 20 73 65 72 76 65 72 20 74 68 72 65 61 64 20 62   server thread b
0a20: 65 6c 6f 6e 67 69 6e 67 20 74 6f 20 74 68 69 73  elonging to this
0a30: 20 63 6c 69 65 6e 74 20 0a 20 20 2a 2a 20 6a 75   client .  ** ju
0a40: 73 74 20 62 65 66 6f 72 65 20 69 74 20 65 78 69  st before it exi
0a50: 74 73 2e 20 20 0a 20 20 2a 2f 0a 20 20 69 6e 74  ts.  .  */.  int
0a60: 20 6e 53 65 72 76 65 72 3b 20 20 20 20 20 20 20   nServer;       
0a70: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
0a80: 6f 66 20 73 65 72 76 65 72 20 74 68 72 65 61 64  of server thread
0a90: 73 20 72 75 6e 6e 69 6e 67 20 2a 2f 0a 7d 3b 0a  s running */.};.
0aa0: 0a 2f 2a 0a 2a 2a 20 54 68 65 72 65 20 63 61 6e  ./*.** There can
0ab0: 20 62 65 20 61 73 20 6d 61 6e 79 20 61 73 20 32   be as many as 2
0ac0: 36 20 74 68 72 65 61 64 73 20 72 75 6e 6e 69 6e  6 threads runnin
0ad0: 67 20 61 74 20 6f 6e 63 65 2e 20 20 45 61 63 68  g at once.  Each
0ae0: 20 69 73 20 6e 61 6d 65 64 0a 2a 2a 20 62 79 20   is named.** by 
0af0: 61 20 63 61 70 69 74 61 6c 20 6c 65 74 74 65 72  a capital letter
0b00: 3a 20 41 2c 20 42 2c 20 43 2c 20 2e 2e 2e 2c 20  : A, B, C, ..., 
0b10: 59 2c 20 5a 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  Y, Z..*/.#define
0b20: 20 4e 5f 54 48 52 45 41 44 20 32 36 0a 73 74 61   N_THREAD 26.sta
0b30: 74 69 63 20 54 68 72 65 61 64 20 74 68 72 65 61  tic Thread threa
0b40: 64 73 65 74 5b 4e 5f 54 48 52 45 41 44 5d 3b 0a  dset[N_THREAD];.
0b50: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 69 6e 20  ./*.** The main 
0b60: 6c 6f 6f 70 20 66 6f 72 20 61 20 74 68 72 65 61  loop for a threa
0b70: 64 2e 20 20 54 68 72 65 61 64 73 20 75 73 65 20  d.  Threads use 
0b80: 62 75 73 79 20 77 61 69 74 69 6e 67 2e 20 0a 2a  busy waiting. .*
0b90: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 63  /.static void *c
0ba0: 6c 69 65 6e 74 5f 6d 61 69 6e 28 76 6f 69 64 20  lient_main(void 
0bb0: 2a 70 41 72 67 29 7b 0a 20 20 54 68 72 65 61 64  *pArg){.  Thread
0bc0: 20 2a 70 20 3d 20 28 54 68 72 65 61 64 2a 29 70   *p = (Thread*)p
0bd0: 41 72 67 3b 0a 20 20 69 66 28 20 70 2d 3e 64 62  Arg;.  if( p->db
0be0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
0bf0: 63 6c 69 65 6e 74 5f 63 6c 6f 73 65 28 70 2d 3e  client_close(p->
0c00: 64 62 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  db);.  }.  sqlit
0c10: 65 33 5f 63 6c 69 65 6e 74 5f 6f 70 65 6e 28 70  e3_client_open(p
0c20: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 26 70 2d  ->zFilename, &p-
0c30: 3e 64 62 29 3b 0a 20 20 69 66 28 20 53 51 4c 49  >db);.  if( SQLI
0c40: 54 45 5f 4f 4b 21 3d 73 71 6c 69 74 65 33 5f 65  TE_OK!=sqlite3_e
0c50: 72 72 63 6f 64 65 28 70 2d 3e 64 62 29 20 29 7b  rrcode(p->db) ){
0c60: 0a 20 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20 73  .    p->zErr = s
0c70: 74 72 64 75 70 28 73 71 6c 69 74 65 33 5f 65 72  trdup(sqlite3_er
0c80: 72 6d 73 67 28 70 2d 3e 64 62 29 29 3b 0a 20 20  rmsg(p->db));.  
0c90: 20 20 73 71 6c 69 74 65 33 5f 63 6c 69 65 6e 74    sqlite3_client
0ca0: 5f 63 6c 6f 73 65 28 70 2d 3e 64 62 29 3b 0a 20  _close(p->db);. 
0cb0: 20 20 20 70 2d 3e 64 62 20 3d 20 30 3b 0a 20 20     p->db = 0;.  
0cc0: 7d 0a 20 20 70 2d 3e 70 53 74 6d 74 20 3d 20 30  }.  p->pStmt = 0
0cd0: 3b 0a 20 20 70 2d 3e 63 6f 6d 70 6c 65 74 65 64  ;.  p->completed
0ce0: 20 3d 20 31 3b 0a 20 20 77 68 69 6c 65 28 20 70   = 1;.  while( p
0cf0: 2d 3e 6f 70 6e 75 6d 3c 3d 70 2d 3e 63 6f 6d 70  ->opnum<=p->comp
0d00: 6c 65 74 65 64 20 29 20 73 63 68 65 64 5f 79 69  leted ) sched_yi
0d10: 65 6c 64 28 29 3b 0a 20 20 77 68 69 6c 65 28 20  eld();.  while( 
0d20: 70 2d 3e 78 4f 70 20 29 7b 0a 20 20 20 20 69 66  p->xOp ){.    if
0d30: 28 20 70 2d 3e 7a 45 72 72 20 26 26 20 70 2d 3e  ( p->zErr && p->
0d40: 7a 45 72 72 21 3d 70 2d 3e 7a 53 74 61 74 69 63  zErr!=p->zStatic
0d50: 45 72 72 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  Err ){.      sql
0d60: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 45 72  ite3_free(p->zEr
0d70: 72 29 3b 0a 20 20 20 20 20 20 70 2d 3e 7a 45 72  r);.      p->zEr
0d80: 72 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  r = 0;.    }.   
0d90: 20 28 2a 70 2d 3e 78 4f 70 29 28 70 29 3b 0a 20   (*p->xOp)(p);. 
0da0: 20 20 20 70 2d 3e 63 6f 6d 70 6c 65 74 65 64 2b     p->completed+
0db0: 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70 2d  +;.    while( p-
0dc0: 3e 6f 70 6e 75 6d 3c 3d 70 2d 3e 63 6f 6d 70 6c  >opnum<=p->compl
0dd0: 65 74 65 64 20 29 20 73 63 68 65 64 5f 79 69 65  eted ) sched_yie
0de0: 6c 64 28 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  ld();.  }.  if( 
0df0: 70 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20  p->pStmt ){.    
0e00: 73 71 6c 69 74 65 33 5f 63 6c 69 65 6e 74 5f 66  sqlite3_client_f
0e10: 69 6e 61 6c 69 7a 65 28 70 2d 3e 70 53 74 6d 74  inalize(p->pStmt
0e20: 29 3b 0a 20 20 20 20 70 2d 3e 70 53 74 6d 74 20  );.    p->pStmt 
0e30: 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  = 0;.  }.  if( p
0e40: 2d 3e 64 62 20 29 7b 0a 20 20 20 20 73 71 6c 69  ->db ){.    sqli
0e50: 74 65 33 5f 63 6c 69 65 6e 74 5f 63 6c 6f 73 65  te3_client_close
0e60: 28 70 2d 3e 64 62 29 3b 0a 20 20 20 20 70 2d 3e  (p->db);.    p->
0e70: 64 62 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66  db = 0;.  }.  if
0e80: 28 20 70 2d 3e 7a 45 72 72 20 26 26 20 70 2d 3e  ( p->zErr && p->
0e90: 7a 45 72 72 21 3d 70 2d 3e 7a 53 74 61 74 69 63  zErr!=p->zStatic
0ea0: 45 72 72 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  Err ){.    sqlit
0eb0: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 45 72 72 29  e3_free(p->zErr)
0ec0: 3b 0a 20 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20  ;.    p->zErr = 
0ed0: 30 3b 0a 20 20 7d 0a 20 20 70 2d 3e 63 6f 6d 70  0;.  }.  p->comp
0ee0: 6c 65 74 65 64 2b 2b 3b 0a 23 69 66 6e 64 65 66  leted++;.#ifndef
0ef0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 44 45 50   SQLITE_OMIT_DEP
0f00: 52 45 43 41 54 45 44 0a 20 20 73 71 6c 69 74 65  RECATED.  sqlite
0f10: 33 5f 74 68 72 65 61 64 5f 63 6c 65 61 6e 75 70  3_thread_cleanup
0f20: 28 29 3b 0a 23 65 6e 64 69 66 0a 20 20 72 65 74  ();.#endif.  ret
0f30: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
0f40: 47 65 74 20 61 20 74 68 72 65 61 64 20 49 44 20  Get a thread ID 
0f50: 77 68 69 63 68 20 69 73 20 61 6e 20 75 70 70 65  which is an uppe
0f60: 72 20 63 61 73 65 20 6c 65 74 74 65 72 2e 20 20  r case letter.  
0f70: 52 65 74 75 72 6e 20 74 68 65 20 69 6e 64 65 78  Return the index
0f80: 2e 0a 2a 2a 20 49 66 20 74 68 65 20 61 72 67 75  ..** If the argu
0f90: 6d 65 6e 74 20 69 73 20 6e 6f 74 20 61 20 76 61  ment is not a va
0fa0: 6c 69 64 20 74 68 72 65 61 64 20 49 44 20 70 75  lid thread ID pu
0fb0: 74 20 61 6e 20 65 72 72 6f 72 20 6d 65 73 73 61  t an error messa
0fc0: 67 65 20 69 6e 0a 2a 2a 20 74 68 65 20 69 6e 74  ge in.** the int
0fd0: 65 72 70 72 65 74 65 72 20 61 6e 64 20 72 65 74  erpreter and ret
0fe0: 75 72 6e 20 2d 31 2e 0a 2a 2f 0a 73 74 61 74 69  urn -1..*/.stati
0ff0: 63 20 69 6e 74 20 70 61 72 73 65 5f 63 6c 69 65  c int parse_clie
1000: 6e 74 5f 69 64 28 54 63 6c 5f 49 6e 74 65 72 70  nt_id(Tcl_Interp
1010: 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20   *interp, const 
1020: 63 68 61 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69  char *zArg){.  i
1030: 66 28 20 7a 41 72 67 3d 3d 30 20 7c 7c 20 7a 41  f( zArg==0 || zA
1040: 72 67 5b 30 5d 3d 3d 30 20 7c 7c 20 7a 41 72 67  rg[0]==0 || zArg
1050: 5b 31 5d 21 3d 30 20 7c 7c 20 21 69 73 75 70 70  [1]!=0 || !isupp
1060: 65 72 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61  er((unsigned cha
1070: 72 29 7a 41 72 67 5b 30 5d 29 20 29 7b 0a 20 20  r)zArg[0]) ){.  
1080: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
1090: 6c 74 28 69 6e 74 65 72 70 2c 20 22 74 68 72 65  lt(interp, "thre
10a0: 61 64 20 49 44 20 6d 75 73 74 20 62 65 20 61 6e  ad ID must be an
10b0: 20 75 70 70 65 72 20 63 61 73 65 20 6c 65 74 74   upper case lett
10c0: 65 72 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  er", 0);.    ret
10d0: 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20 72 65  urn -1;.  }.  re
10e0: 74 75 72 6e 20 7a 41 72 67 5b 30 5d 20 2d 20 27  turn zArg[0] - '
10f0: 41 27 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61  A';.}../*.** Usa
1100: 67 65 3a 20 20 20 20 63 6c 69 65 6e 74 5f 63 72  ge:    client_cr
1110: 65 61 74 65 20 4e 41 4d 45 20 20 46 49 4c 45 4e  eate NAME  FILEN
1120: 41 4d 45 0a 2a 2a 0a 2a 2a 20 4e 41 4d 45 20 73  AME.**.** NAME s
1130: 68 6f 75 6c 64 20 62 65 20 61 6e 20 75 70 70 65  hould be an uppe
1140: 72 20 63 61 73 65 20 6c 65 74 74 65 72 2e 20 20  r case letter.  
1150: 53 74 61 72 74 20 74 68 65 20 74 68 72 65 61 64  Start the thread
1160: 20 72 75 6e 6e 69 6e 67 20 77 69 74 68 0a 2a 2a   running with.**
1170: 20 61 6e 20 6f 70 65 6e 20 63 6f 6e 6e 65 63 74   an open connect
1180: 69 6f 6e 20 74 6f 20 74 68 65 20 67 69 76 65 6e  ion to the given
1190: 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 73 74   database..*/.st
11a0: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 63 6c 69  atic int tcl_cli
11b0: 65 6e 74 5f 63 72 65 61 74 65 28 0a 20 20 76 6f  ent_create(.  vo
11c0: 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54  id *NotUsed,.  T
11d0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
11e0: 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c  p,    /* The TCL
11f0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61   interpreter tha
1200: 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63  t invoked this c
1210: 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20  ommand */.  int 
1220: 61 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20  argc,           
1230: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1240: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63  arguments */.  c
1250: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76  onst char **argv
1260: 20 20 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66        /* Text of
1270: 20 65 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a   each argument *
1280: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  /.){.  int i;.  
1290: 70 74 68 72 65 61 64 5f 74 20 78 3b 0a 20 20 69  pthread_t x;.  i
12a0: 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 61 72  nt rc;..  if( ar
12b0: 67 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c  gc!=3 ){.    Tcl
12c0: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
12d0: 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20 61  terp, "wrong # a
12e0: 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 5c  rgs: should be \
12f0: 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20 20  "", argv[0],.   
1300: 20 20 20 20 22 20 49 44 20 46 49 4c 45 4e 41 4d      " ID FILENAM
1310: 45 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75  E", 0);.    retu
1320: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
1330: 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f 63 6c  }.  i = parse_cl
1340: 69 65 6e 74 5f 69 64 28 69 6e 74 65 72 70 2c 20  ient_id(interp, 
1350: 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20  argv[1]);.  if( 
1360: 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c  i<0 ) return TCL
1370: 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 74 68  _ERROR;.  if( th
1380: 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79 20  readset[i].busy 
1390: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
13a0: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
13b0: 22 74 68 72 65 61 64 20 22 2c 20 61 72 67 76 5b  "thread ", argv[
13c0: 31 5d 2c 20 22 20 69 73 20 61 6c 72 65 61 64 79  1], " is already
13d0: 20 72 75 6e 6e 69 6e 67 22 2c 20 30 29 3b 0a 20   running", 0);. 
13e0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
13f0: 52 4f 52 3b 0a 20 20 7d 0a 20 20 74 68 72 65 61  ROR;.  }.  threa
1400: 64 73 65 74 5b 69 5d 2e 62 75 73 79 20 3d 20 31  dset[i].busy = 1
1410: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1420: 28 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 7a 46  (threadset[i].zF
1430: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 74 68 72 65  ilename);.  thre
1440: 61 64 73 65 74 5b 69 5d 2e 7a 46 69 6c 65 6e 61  adset[i].zFilena
1450: 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  me = sqlite3_mpr
1460: 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b  intf("%s", argv[
1470: 32 5d 29 3b 0a 20 20 74 68 72 65 61 64 73 65 74  2]);.  threadset
1480: 5b 69 5d 2e 6f 70 6e 75 6d 20 3d 20 31 3b 0a 20  [i].opnum = 1;. 
1490: 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 63 6f   threadset[i].co
14a0: 6d 70 6c 65 74 65 64 20 3d 20 30 3b 0a 20 20 72  mpleted = 0;.  r
14b0: 63 20 3d 20 70 74 68 72 65 61 64 5f 63 72 65 61  c = pthread_crea
14c0: 74 65 28 26 78 2c 20 30 2c 20 63 6c 69 65 6e 74  te(&x, 0, client
14d0: 5f 6d 61 69 6e 2c 20 26 74 68 72 65 61 64 73 65  _main, &threadse
14e0: 74 5b 69 5d 29 3b 0a 20 20 69 66 28 20 72 63 20  t[i]);.  if( rc 
14f0: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
1500: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
1510: 22 66 61 69 6c 65 64 20 74 6f 20 63 72 65 61 74  "failed to creat
1520: 65 20 74 68 65 20 74 68 72 65 61 64 22 2c 20 30  e the thread", 0
1530: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1540: 72 65 65 28 74 68 72 65 61 64 73 65 74 5b 69 5d  ree(threadset[i]
1550: 2e 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20  .zFilename);.   
1560: 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75   threadset[i].bu
1570: 73 79 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75  sy = 0;.    retu
1580: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
1590: 7d 0a 20 20 70 74 68 72 65 61 64 5f 64 65 74 61  }.  pthread_deta
15a0: 63 68 28 78 29 3b 0a 20 20 69 66 28 20 74 68 72  ch(x);.  if( thr
15b0: 65 61 64 73 65 74 5b 69 5d 2e 6e 53 65 72 76 65  eadset[i].nServe
15c0: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 74 68 72 65  r==0 ){.    thre
15d0: 61 64 73 65 74 5b 69 5d 2e 6e 53 65 72 76 65 72  adset[i].nServer
15e0: 20 3d 20 31 3b 0a 20 20 20 20 73 71 6c 69 74 65   = 1;.    sqlite
15f0: 33 5f 73 65 72 76 65 72 5f 73 74 61 72 74 32 28  3_server_start2(
1600: 26 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 6e 53  &threadset[i].nS
1610: 65 72 76 65 72 29 3b 0a 20 20 7d 0a 20 20 72 65  erver);.  }.  re
1620: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
1630: 2f 2a 0a 2a 2a 20 57 61 69 74 20 66 6f 72 20 61  /*.** Wait for a
1640: 20 74 68 72 65 61 64 20 74 6f 20 72 65 61 63 68   thread to reach
1650: 20 69 74 73 20 69 64 6c 65 20 73 74 61 74 65 2e   its idle state.
1660: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1670: 63 6c 69 65 6e 74 5f 77 61 69 74 28 54 68 72 65  client_wait(Thre
1680: 61 64 20 2a 70 29 7b 0a 20 20 77 68 69 6c 65 28  ad *p){.  while(
1690: 20 70 2d 3e 6f 70 6e 75 6d 3e 70 2d 3e 63 6f 6d   p->opnum>p->com
16a0: 70 6c 65 74 65 64 20 29 20 73 63 68 65 64 5f 79  pleted ) sched_y
16b0: 69 65 6c 64 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ield();.}../*.**
16c0: 20 55 73 61 67 65 3a 20 20 63 6c 69 65 6e 74 5f   Usage:  client_
16d0: 77 61 69 74 20 49 44 0a 2a 2a 0a 2a 2a 20 57 61  wait ID.**.** Wa
16e0: 69 74 20 6f 6e 20 74 68 72 65 61 64 20 49 44 20  it on thread ID 
16f0: 74 6f 20 72 65 61 63 68 20 69 74 73 20 69 64 6c  to reach its idl
1700: 65 20 73 74 61 74 65 2e 0a 2a 2f 0a 73 74 61 74  e state..*/.stat
1710: 69 63 20 69 6e 74 20 74 63 6c 5f 63 6c 69 65 6e  ic int tcl_clien
1720: 74 5f 77 61 69 74 28 0a 20 20 76 6f 69 64 20 2a  t_wait(.  void *
1730: 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49  NotUsed,.  Tcl_I
1740: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20  nterp *interp,  
1750: 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74    /* The TCL int
1760: 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e  erpreter that in
1770: 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61  voked this comma
1780: 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63  nd */.  int argc
1790: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
17a0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75  * Number of argu
17b0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74  ments */.  const
17c0: 20 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20 20   char **argv    
17d0: 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61 63    /* Text of eac
17e0: 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b  h argument */.){
17f0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 66 28  .  int i;..  if(
1800: 20 61 72 67 63 21 3d 32 20 29 7b 0a 20 20 20 20   argc!=2 ){.    
1810: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
1820: 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67 20  (interp, "wrong 
1830: 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20 62  # args: should b
1840: 65 20 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a  e \"", argv[0],.
1850: 20 20 20 20 20 20 20 22 20 49 44 22 2c 20 30 29         " ID", 0)
1860: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
1870: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20  _ERROR;.  }.  i 
1880: 3d 20 70 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69  = parse_client_i
1890: 64 28 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 31  d(interp, argv[1
18a0: 5d 29 3b 0a 20 20 69 66 28 20 69 3c 30 20 29 20  ]);.  if( i<0 ) 
18b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
18c0: 3b 0a 20 20 69 66 28 20 21 74 68 72 65 61 64 73  ;.  if( !threads
18d0: 65 74 5b 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20  et[i].busy ){.  
18e0: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
18f0: 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73  lt(interp, "no s
1900: 75 63 68 20 74 68 72 65 61 64 22 2c 20 30 29 3b  uch thread", 0);
1910: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
1920: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69  ERROR;.  }.  cli
1930: 65 6e 74 5f 77 61 69 74 28 26 74 68 72 65 61 64  ent_wait(&thread
1940: 73 65 74 5b 69 5d 29 3b 0a 20 20 72 65 74 75 72  set[i]);.  retur
1950: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
1960: 2a 2a 20 53 74 6f 70 20 61 20 74 68 72 65 61 64  ** Stop a thread
1970: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
1980: 20 73 74 6f 70 5f 74 68 72 65 61 64 28 54 68 72   stop_thread(Thr
1990: 65 61 64 20 2a 70 29 7b 0a 20 20 63 6c 69 65 6e  ead *p){.  clien
19a0: 74 5f 77 61 69 74 28 70 29 3b 0a 20 20 70 2d 3e  t_wait(p);.  p->
19b0: 78 4f 70 20 3d 20 30 3b 0a 20 20 70 2d 3e 6f 70  xOp = 0;.  p->op
19c0: 6e 75 6d 2b 2b 3b 0a 20 20 63 6c 69 65 6e 74 5f  num++;.  client_
19d0: 77 61 69 74 28 70 29 3b 0a 20 20 73 71 6c 69 74  wait(p);.  sqlit
19e0: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 41 72 67 29  e3_free(p->zArg)
19f0: 3b 0a 20 20 70 2d 3e 7a 41 72 67 20 3d 20 30 3b  ;.  p->zArg = 0;
1a00: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
1a10: 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  p->zFilename);. 
1a20: 20 70 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d 20   p->zFilename = 
1a30: 30 3b 0a 20 20 70 2d 3e 62 75 73 79 20 3d 20 30  0;.  p->busy = 0
1a40: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65  ;.}../*.** Usage
1a50: 3a 20 20 63 6c 69 65 6e 74 5f 68 61 6c 74 20 49  :  client_halt I
1a60: 44 0a 2a 2a 0a 2a 2a 20 43 61 75 73 65 20 61 20  D.**.** Cause a 
1a70: 63 6c 69 65 6e 74 20 74 68 72 65 61 64 20 74 6f  client thread to
1a80: 20 73 68 75 74 20 69 74 73 65 6c 66 20 64 6f 77   shut itself dow
1a90: 6e 2e 20 20 57 61 69 74 20 66 6f 72 20 74 68 65  n.  Wait for the
1aa0: 20 73 68 75 74 64 6f 77 6e 20 74 6f 20 62 65 0a   shutdown to be.
1ab0: 2a 2a 20 63 6f 6d 70 6c 65 74 65 64 2e 20 20 49  ** completed.  I
1ac0: 66 20 49 44 20 69 73 20 22 2a 22 20 74 68 65 6e  f ID is "*" then
1ad0: 20 73 74 6f 70 20 61 6c 6c 20 63 6c 69 65 6e 74   stop all client
1ae0: 20 74 68 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61   threads..*/.sta
1af0: 74 69 63 20 69 6e 74 20 74 63 6c 5f 63 6c 69 65  tic int tcl_clie
1b00: 6e 74 5f 68 61 6c 74 28 0a 20 20 76 6f 69 64 20  nt_halt(.  void 
1b10: 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f  *NotUsed,.  Tcl_
1b20: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
1b30: 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e     /* The TCL in
1b40: 74 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69  terpreter that i
1b50: 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d  nvoked this comm
1b60: 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67  and */.  int arg
1b70: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
1b80: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
1b90: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73  uments */.  cons
1ba0: 74 20 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20  t char **argv   
1bb0: 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61     /* Text of ea
1bc0: 63 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29  ch argument */.)
1bd0: 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 69 66  {.  int i;..  if
1be0: 28 20 61 72 67 63 21 3d 32 20 29 7b 0a 20 20 20  ( argc!=2 ){.   
1bf0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
1c00: 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67  t(interp, "wrong
1c10: 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20   # args: should 
1c20: 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c  be \"", argv[0],
1c30: 0a 20 20 20 20 20 20 20 22 20 49 44 22 2c 20 30  .       " ID", 0
1c40: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
1c50: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69  L_ERROR;.  }.  i
1c60: 66 28 20 61 72 67 76 5b 31 5d 5b 30 5d 3d 3d 27  f( argv[1][0]=='
1c70: 2a 27 20 26 26 20 61 72 67 76 5b 31 5d 5b 31 5d  *' && argv[1][1]
1c80: 3d 3d 30 20 29 7b 0a 20 20 20 20 66 6f 72 28 69  ==0 ){.    for(i
1c90: 3d 30 3b 20 69 3c 4e 5f 54 48 52 45 41 44 3b 20  =0; i<N_THREAD; 
1ca0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20  i++){.      if( 
1cb0: 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73  threadset[i].bus
1cc0: 79 20 29 7b 0a 20 20 20 20 20 20 20 20 73 74 6f  y ){.        sto
1cd0: 70 5f 74 68 72 65 61 64 28 26 74 68 72 65 61 64  p_thread(&thread
1ce0: 73 65 74 5b 69 5d 29 3b 0a 20 20 20 20 20 20 7d  set[i]);.      }
1cf0: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a  .    }.  }else{.
1d00: 20 20 20 20 69 20 3d 20 70 61 72 73 65 5f 63 6c      i = parse_cl
1d10: 69 65 6e 74 5f 69 64 28 69 6e 74 65 72 70 2c 20  ient_id(interp, 
1d20: 61 72 67 76 5b 31 5d 29 3b 0a 20 20 20 20 69 66  argv[1]);.    if
1d30: 28 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54  ( i<0 ) return T
1d40: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 69 66  CL_ERROR;.    if
1d50: 28 20 21 74 68 72 65 61 64 73 65 74 5b 69 5d 2e  ( !threadset[i].
1d60: 62 75 73 79 20 29 7b 0a 20 20 20 20 20 20 54 63  busy ){.      Tc
1d70: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
1d80: 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68 20  nterp, "no such 
1d90: 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20 20  thread", 0);.   
1da0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
1db0: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  ROR;.    }.    s
1dc0: 74 6f 70 5f 74 68 72 65 61 64 28 26 74 68 72 65  top_thread(&thre
1dd0: 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20 7d 0a 0a  adset[i]);.  }..
1de0: 20 20 2f 2a 20 49 66 20 6e 6f 20 63 6c 69 65 6e    /* If no clien
1df0: 74 20 74 68 72 65 61 64 73 20 61 72 65 20 73 74  t threads are st
1e00: 69 6c 6c 20 72 75 6e 6e 69 6e 67 2c 20 61 6c 73  ill running, als
1e10: 6f 20 73 74 6f 70 20 74 68 65 20 73 65 72 76 65  o stop the serve
1e20: 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  r */.  for(i=0; 
1e30: 69 3c 4e 5f 54 48 52 45 41 44 20 26 26 20 74 68  i<N_THREAD && th
1e40: 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79 3d  readset[i].busy=
1e50: 3d 30 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66 28  =0; i++){}.  if(
1e60: 20 69 3e 3d 4e 5f 54 48 52 45 41 44 20 29 7b 0a   i>=N_THREAD ){.
1e70: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 65 72 76      sqlite3_serv
1e80: 65 72 5f 73 74 6f 70 28 29 3b 0a 20 20 20 20 77  er_stop();.    w
1e90: 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 20  hile( 1 ){.     
1ea0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 4e 5f 54 48   for(i=0; i<N_TH
1eb0: 52 45 41 44 20 26 26 20 74 68 72 65 61 64 73 65  READ && threadse
1ec0: 74 5b 69 5d 2e 6e 53 65 72 76 65 72 3d 3d 30 3b  t[i].nServer==0;
1ed0: 20 69 2b 2b 29 3b 0a 20 20 20 20 20 20 69 66 28   i++);.      if(
1ee0: 20 69 3d 3d 4e 5f 54 48 52 45 41 44 20 29 20 62   i==N_THREAD ) b
1ef0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 73 63 68 65  reak;.      sche
1f00: 64 5f 79 69 65 6c 64 28 29 3b 0a 20 20 20 20 7d  d_yield();.    }
1f10: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54 43  .  }.  return TC
1f20: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  L_OK;.}../*.** U
1f30: 73 61 67 65 3a 20 63 6c 69 65 6e 74 5f 61 72 67  sage: client_arg
1f40: 63 20 20 49 44 0a 2a 2a 0a 2a 2a 20 57 61 69 74  c  ID.**.** Wait
1f50: 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20 72 65 63   on the most rec
1f60: 65 6e 74 20 63 6c 69 65 6e 74 5f 73 74 65 70 20  ent client_step 
1f70: 74 6f 20 63 6f 6d 70 6c 65 74 65 2c 20 74 68 65  to complete, the
1f80: 6e 20 72 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20  n return the.** 
1f90: 6e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e  number of column
1fa0: 73 20 69 6e 20 74 68 65 20 72 65 73 75 6c 74 20  s in the result 
1fb0: 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  set..*/.static i
1fc0: 6e 74 20 74 63 6c 5f 63 6c 69 65 6e 74 5f 61 72  nt tcl_client_ar
1fd0: 67 63 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55  gc(.  void *NotU
1fe0: 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72  sed,.  Tcl_Inter
1ff0: 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a  p *interp,    /*
2000: 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   The TCL interpr
2010: 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65  eter that invoke
2020: 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a  d this command *
2030: 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20  /.  int argc,   
2040: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
2050: 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74  mber of argument
2060: 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  s */.  const cha
2070: 72 20 2a 2a 61 72 67 76 20 20 20 20 20 20 2f 2a  r **argv      /*
2080: 20 54 65 78 74 20 6f 66 20 65 61 63 68 20 61 72   Text of each ar
2090: 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69  gument */.){.  i
20a0: 6e 74 20 69 3b 0a 20 20 63 68 61 72 20 7a 42 75  nt i;.  char zBu
20b0: 66 5b 31 30 30 5d 3b 0a 0a 20 20 69 66 28 20 61  f[100];..  if( a
20c0: 72 67 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  rgc!=2 ){.    Tc
20d0: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
20e0: 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20  nterp, "wrong # 
20f0: 61 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20  args: should be 
2100: 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20  \"", argv[0],.  
2110: 20 20 20 20 20 22 20 49 44 22 2c 20 30 29 3b 0a       " ID", 0);.
2120: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
2130: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20  RROR;.  }.  i = 
2140: 70 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69 64 28  parse_client_id(
2150: 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29  interp, argv[1])
2160: 3b 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72 65  ;.  if( i<0 ) re
2170: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
2180: 20 20 69 66 28 20 21 74 68 72 65 61 64 73 65 74    if( !threadset
2190: 5b 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20 20  [i].busy ){.    
21a0: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
21b0: 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63  (interp, "no suc
21c0: 68 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20  h thread", 0);. 
21d0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
21e0: 52 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69 65 6e  ROR;.  }.  clien
21f0: 74 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65  t_wait(&threadse
2200: 74 5b 69 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33  t[i]);.  sqlite3
2210: 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66  _snprintf(sizeof
2220: 28 7a 42 75 66 29 2c 20 7a 42 75 66 2c 20 22 25  (zBuf), zBuf, "%
2230: 64 22 2c 20 74 68 72 65 61 64 73 65 74 5b 69 5d  d", threadset[i]
2240: 2e 61 72 67 63 29 3b 0a 20 20 54 63 6c 5f 41 70  .argc);.  Tcl_Ap
2250: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
2260: 70 2c 20 7a 42 75 66 2c 20 30 29 3b 0a 20 20 72  p, zBuf, 0);.  r
2270: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
2280: 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 63 6c  ./*.** Usage: cl
2290: 69 65 6e 74 5f 61 72 67 76 20 20 49 44 20 20 20  ient_argv  ID   
22a0: 4e 0a 2a 2a 0a 2a 2a 20 57 61 69 74 20 6f 6e 20  N.**.** Wait on 
22b0: 74 68 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 20  the most recent 
22c0: 63 6c 69 65 6e 74 5f 73 74 65 70 20 74 6f 20 63  client_step to c
22d0: 6f 6d 70 6c 65 74 65 2c 20 74 68 65 6e 20 72 65  omplete, then re
22e0: 74 75 72 6e 20 74 68 65 0a 2a 2a 20 76 61 6c 75  turn the.** valu
22f0: 65 20 6f 66 20 74 68 65 20 4e 2d 74 68 20 63 6f  e of the N-th co
2300: 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 72 65 73  lumns in the res
2310: 75 6c 74 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74  ult set..*/.stat
2320: 69 63 20 69 6e 74 20 74 63 6c 5f 63 6c 69 65 6e  ic int tcl_clien
2330: 74 5f 61 72 67 76 28 0a 20 20 76 6f 69 64 20 2a  t_argv(.  void *
2340: 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49  NotUsed,.  Tcl_I
2350: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20  nterp *interp,  
2360: 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74    /* The TCL int
2370: 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e  erpreter that in
2380: 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61  voked this comma
2390: 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63  nd */.  int argc
23a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
23b0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75  * Number of argu
23c0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74  ments */.  const
23d0: 20 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20 20   char **argv    
23e0: 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61 63    /* Text of eac
23f0: 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b  h argument */.){
2400: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20  .  int i;.  int 
2410: 6e 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 21 3d  n;..  if( argc!=
2420: 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  3 ){.    Tcl_App
2430: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
2440: 2c 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a  , "wrong # args:
2450: 20 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20   should be \"", 
2460: 61 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20  argv[0],.       
2470: 22 20 49 44 20 4e 22 2c 20 30 29 3b 0a 20 20 20  " ID N", 0);.   
2480: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
2490: 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70 61 72  R;.  }.  i = par
24a0: 73 65 5f 63 6c 69 65 6e 74 5f 69 64 28 69 6e 74  se_client_id(int
24b0: 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b 0a 20  erp, argv[1]);. 
24c0: 20 69 66 28 20 69 3c 30 20 29 20 72 65 74 75 72   if( i<0 ) retur
24d0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69  n TCL_ERROR;.  i
24e0: 66 28 20 21 74 68 72 65 61 64 73 65 74 5b 69 5d  f( !threadset[i]
24f0: 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54 63 6c  .busy ){.    Tcl
2500: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
2510: 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68 20 74  terp, "no such t
2520: 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20 20 20  hread", 0);.    
2530: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
2540: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f  ;.  }.  if( Tcl_
2550: 47 65 74 49 6e 74 28 69 6e 74 65 72 70 2c 20 61  GetInt(interp, a
2560: 72 67 76 5b 32 5d 2c 20 26 6e 29 20 29 20 72 65  rgv[2], &n) ) re
2570: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
2580: 20 20 63 6c 69 65 6e 74 5f 77 61 69 74 28 26 74    client_wait(&t
2590: 68 72 65 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20  hreadset[i]);.  
25a0: 69 66 28 20 6e 3c 30 20 7c 7c 20 6e 3e 3d 74 68  if( n<0 || n>=th
25b0: 72 65 61 64 73 65 74 5b 69 5d 2e 61 72 67 63 20  readset[i].argc 
25c0: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
25d0: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
25e0: 22 63 6f 6c 75 6d 6e 20 6e 75 6d 62 65 72 20 6f  "column number o
25f0: 75 74 20 6f 66 20 72 61 6e 67 65 22 2c 20 30 29  ut of range", 0)
2600: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
2610: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 54 63  _ERROR;.  }.  Tc
2620: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
2630: 6e 74 65 72 70 2c 20 74 68 72 65 61 64 73 65 74  nterp, threadset
2640: 5b 69 5d 2e 61 72 67 76 5b 6e 5d 2c 20 30 29 3b  [i].argv[n], 0);
2650: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
2660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65  ;.}../*.** Usage
2670: 3a 20 63 6c 69 65 6e 74 5f 63 6f 6c 6e 61 6d 65  : client_colname
2680: 20 20 49 44 20 20 20 4e 0a 2a 2a 0a 2a 2a 20 57    ID   N.**.** W
2690: 61 69 74 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20  ait on the most 
26a0: 72 65 63 65 6e 74 20 63 6c 69 65 6e 74 5f 73 74  recent client_st
26b0: 65 70 20 74 6f 20 63 6f 6d 70 6c 65 74 65 2c 20  ep to complete, 
26c0: 74 68 65 6e 20 72 65 74 75 72 6e 20 74 68 65 0a  then return the.
26d0: 2a 2a 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 4e  ** name of the N
26e0: 2d 74 68 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74  -th columns in t
26f0: 68 65 20 72 65 73 75 6c 74 20 73 65 74 2e 0a 2a  he result set..*
2700: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  /.static int tcl
2710: 5f 63 6c 69 65 6e 74 5f 63 6f 6c 6e 61 6d 65 28  _client_colname(
2720: 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64  .  void *NotUsed
2730: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
2740: 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68  interp,    /* Th
2750: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
2760: 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74  r that invoked t
2770: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20  his command */. 
2780: 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20   int argc,      
2790: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
27a0: 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a  r of arguments *
27b0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
27c0: 2a 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54 65  *argv      /* Te
27d0: 78 74 20 6f 66 20 65 61 63 68 20 61 72 67 75 6d  xt of each argum
27e0: 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ent */.){.  int 
27f0: 69 3b 0a 20 20 69 6e 74 20 6e 3b 0a 0a 20 20 69  i;.  int n;..  i
2800: 66 28 20 61 72 67 63 21 3d 33 20 29 7b 0a 20 20  f( argc!=3 ){.  
2810: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
2820: 6c 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e  lt(interp, "wron
2830: 67 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64  g # args: should
2840: 20 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30 5d   be \"", argv[0]
2850: 2c 0a 20 20 20 20 20 20 20 22 20 49 44 20 4e 22  ,.       " ID N"
2860: 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  , 0);.    return
2870: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
2880: 20 20 69 20 3d 20 70 61 72 73 65 5f 63 6c 69 65    i = parse_clie
2890: 6e 74 5f 69 64 28 69 6e 74 65 72 70 2c 20 61 72  nt_id(interp, ar
28a0: 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 69 3c  gv[1]);.  if( i<
28b0: 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  0 ) return TCL_E
28c0: 52 52 4f 52 3b 0a 20 20 69 66 28 20 21 74 68 72  RROR;.  if( !thr
28d0: 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79 20 29  eadset[i].busy )
28e0: 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64  {.    Tcl_Append
28f0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22  Result(interp, "
2900: 6e 6f 20 73 75 63 68 20 74 68 72 65 61 64 22 2c  no such thread",
2910: 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20   0);.    return 
2920: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
2930: 20 69 66 28 20 54 63 6c 5f 47 65 74 49 6e 74 28   if( Tcl_GetInt(
2940: 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 32 5d 2c  interp, argv[2],
2950: 20 26 6e 29 20 29 20 72 65 74 75 72 6e 20 54 43   &n) ) return TC
2960: 4c 5f 45 52 52 4f 52 3b 0a 20 20 63 6c 69 65 6e  L_ERROR;.  clien
2970: 74 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65  t_wait(&threadse
2980: 74 5b 69 5d 29 3b 0a 20 20 69 66 28 20 6e 3c 30  t[i]);.  if( n<0
2990: 20 7c 7c 20 6e 3e 3d 74 68 72 65 61 64 73 65 74   || n>=threadset
29a0: 5b 69 5d 2e 61 72 67 63 20 29 7b 0a 20 20 20 20  [i].argc ){.    
29b0: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
29c0: 28 69 6e 74 65 72 70 2c 20 22 63 6f 6c 75 6d 6e  (interp, "column
29d0: 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f 66 20 72   number out of r
29e0: 61 6e 67 65 22 2c 20 30 29 3b 0a 20 20 20 20 72  ange", 0);.    r
29f0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
2a00: 0a 20 20 7d 0a 20 20 54 63 6c 5f 41 70 70 65 6e  .  }.  Tcl_Appen
2a10: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
2a20: 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 63 6f 6c  threadset[i].col
2a30: 76 5b 6e 5d 2c 20 30 29 3b 0a 20 20 72 65 74 75  v[n], 0);.  retu
2a40: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 65 78  rn TCL_OK;.}..ex
2a50: 74 65 72 6e 20 63 6f 6e 73 74 20 63 68 61 72 20  tern const char 
2a60: 2a 73 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28  *sqlite3ErrName(
2a70: 69 6e 74 29 3b 0a 0a 2f 2a 0a 2a 2a 20 55 73 61  int);../*.** Usa
2a80: 67 65 3a 20 63 6c 69 65 6e 74 5f 72 65 73 75 6c  ge: client_resul
2a90: 74 20 20 49 44 0a 2a 2a 0a 2a 2a 20 57 61 69 74  t  ID.**.** Wait
2aa0: 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20 72 65 63   on the most rec
2ab0: 65 6e 74 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f  ent operation to
2ac0: 20 63 6f 6d 70 6c 65 74 65 2c 20 74 68 65 6e 20   complete, then 
2ad0: 72 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20 72 65  return the.** re
2ae0: 73 75 6c 74 20 63 6f 64 65 20 66 72 6f 6d 20 74  sult code from t
2af0: 68 61 74 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a  hat operation..*
2b00: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  /.static int tcl
2b10: 5f 63 6c 69 65 6e 74 5f 72 65 73 75 6c 74 28 0a  _client_result(.
2b20: 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c    void *NotUsed,
2b30: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
2b40: 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65  nterp,    /* The
2b50: 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72   TCL interpreter
2b60: 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68   that invoked th
2b70: 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20  is command */.  
2b80: 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20  int argc,       
2b90: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
2ba0: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f   of arguments */
2bb0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
2bc0: 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54 65 78  argv      /* Tex
2bd0: 74 20 6f 66 20 65 61 63 68 20 61 72 67 75 6d 65  t of each argume
2be0: 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69  nt */.){.  int i
2bf0: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
2c00: 7a 4e 61 6d 65 3b 0a 0a 20 20 69 66 28 20 61 72  zName;..  if( ar
2c10: 67 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c  gc!=2 ){.    Tcl
2c20: 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e  _AppendResult(in
2c30: 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20 61  terp, "wrong # a
2c40: 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 5c  rgs: should be \
2c50: 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20 20  "", argv[0],.   
2c60: 20 20 20 20 22 20 49 44 22 2c 20 30 29 3b 0a 20      " ID", 0);. 
2c70: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
2c80: 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70  ROR;.  }.  i = p
2c90: 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69 64 28 69  arse_client_id(i
2ca0: 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b  nterp, argv[1]);
2cb0: 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72 65 74  .  if( i<0 ) ret
2cc0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
2cd0: 20 69 66 28 20 21 74 68 72 65 61 64 73 65 74 5b   if( !threadset[
2ce0: 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54  i].busy ){.    T
2cf0: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
2d00: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
2d10: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
2d20: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
2d30: 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69 65 6e 74  OR;.  }.  client
2d40: 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65 74  _wait(&threadset
2d50: 5b 69 5d 29 3b 0a 20 20 7a 4e 61 6d 65 20 3d 20  [i]);.  zName = 
2d60: 73 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 74  sqlite3ErrName(t
2d70: 68 72 65 61 64 73 65 74 5b 69 5d 2e 72 63 29 3b  hreadset[i].rc);
2d80: 0a 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73  .  Tcl_AppendRes
2d90: 75 6c 74 28 69 6e 74 65 72 70 2c 20 7a 4e 61 6d  ult(interp, zNam
2da0: 65 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20  e, 0);.  return 
2db0: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
2dc0: 20 55 73 61 67 65 3a 20 63 6c 69 65 6e 74 5f 65   Usage: client_e
2dd0: 72 72 6f 72 20 20 49 44 0a 2a 2a 0a 2a 2a 20 57  rror  ID.**.** W
2de0: 61 69 74 20 6f 6e 20 74 68 65 20 6d 6f 73 74 20  ait on the most 
2df0: 72 65 63 65 6e 74 20 6f 70 65 72 61 74 69 6f 6e  recent operation
2e00: 20 74 6f 20 63 6f 6d 70 6c 65 74 65 2c 20 74 68   to complete, th
2e10: 65 6e 20 72 65 74 75 72 6e 20 74 68 65 0a 2a 2a  en return the.**
2e20: 20 65 72 72 6f 72 20 73 74 72 69 6e 67 2e 0a 2a   error string..*
2e30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  /.static int tcl
2e40: 5f 63 6c 69 65 6e 74 5f 65 72 72 6f 72 28 0a 20  _client_error(. 
2e50: 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c 0a   void *NotUsed,.
2e60: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
2e70: 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20  terp,    /* The 
2e80: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20  TCL interpreter 
2e90: 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69  that invoked thi
2ea0: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69  s command */.  i
2eb0: 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20 20  nt argc,        
2ec0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
2ed0: 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  of arguments */.
2ee0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
2ef0: 72 67 76 20 20 20 20 20 20 2f 2a 20 54 65 78 74  rgv      /* Text
2f00: 20 6f 66 20 65 61 63 68 20 61 72 67 75 6d 65 6e   of each argumen
2f10: 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b  t */.){.  int i;
2f20: 0a 0a 20 20 69 66 28 20 61 72 67 63 21 3d 32 20  ..  if( argc!=2 
2f30: 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  ){.    Tcl_Appen
2f40: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  dResult(interp, 
2f50: 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20 73  "wrong # args: s
2f60: 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20 61 72  hould be \"", ar
2f70: 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20 22 20  gv[0],.       " 
2f80: 49 44 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74  ID", 0);.    ret
2f90: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
2fa0: 20 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f 63   }.  i = parse_c
2fb0: 6c 69 65 6e 74 5f 69 64 28 69 6e 74 65 72 70 2c  lient_id(interp,
2fc0: 20 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28   argv[1]);.  if(
2fd0: 20 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54 43   i<0 ) return TC
2fe0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 21  L_ERROR;.  if( !
2ff0: 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73  threadset[i].bus
3000: 79 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  y ){.    Tcl_App
3010: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
3020: 2c 20 22 6e 6f 20 73 75 63 68 20 74 68 72 65 61  , "no such threa
3030: 64 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75  d", 0);.    retu
3040: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
3050: 7d 0a 20 20 63 6c 69 65 6e 74 5f 77 61 69 74 28  }.  client_wait(
3060: 26 74 68 72 65 61 64 73 65 74 5b 69 5d 29 3b 0a  &threadset[i]);.
3070: 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75    Tcl_AppendResu
3080: 6c 74 28 69 6e 74 65 72 70 2c 20 74 68 72 65 61  lt(interp, threa
3090: 64 73 65 74 5b 69 5d 2e 7a 45 72 72 2c 20 30 29  dset[i].zErr, 0)
30a0: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
30b0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  K;.}../*.** This
30c0: 20 70 72 6f 63 65 64 75 72 65 20 72 75 6e 73 20   procedure runs 
30d0: 69 6e 20 74 68 65 20 74 68 72 65 61 64 20 74 6f  in the thread to
30e0: 20 63 6f 6d 70 69 6c 65 20 61 6e 20 53 51 4c 20   compile an SQL 
30f0: 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74  statement..*/.st
3100: 61 74 69 63 20 76 6f 69 64 20 64 6f 5f 63 6f 6d  atic void do_com
3110: 70 69 6c 65 28 54 68 72 65 61 64 20 2a 70 29 7b  pile(Thread *p){
3120: 0a 20 20 69 66 28 20 70 2d 3e 64 62 3d 3d 30 20  .  if( p->db==0 
3130: 29 7b 0a 20 20 20 20 70 2d 3e 7a 45 72 72 20 3d  ){.    p->zErr =
3140: 20 70 2d 3e 7a 53 74 61 74 69 63 45 72 72 20 3d   p->zStaticErr =
3150: 20 22 6e 6f 20 64 61 74 61 62 61 73 65 20 69 73   "no database is
3160: 20 6f 70 65 6e 22 3b 0a 20 20 20 20 70 2d 3e 72   open";.    p->r
3170: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
3180: 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20  ;.    return;.  
3190: 7d 0a 20 20 69 66 28 20 70 2d 3e 70 53 74 6d 74  }.  if( p->pStmt
31a0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
31b0: 63 6c 69 65 6e 74 5f 66 69 6e 61 6c 69 7a 65 28  client_finalize(
31c0: 70 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 70  p->pStmt);.    p
31d0: 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 7d  ->pStmt = 0;.  }
31e0: 0a 20 20 70 2d 3e 72 63 20 3d 20 73 71 6c 69 74  .  p->rc = sqlit
31f0: 65 33 5f 63 6c 69 65 6e 74 5f 70 72 65 70 61 72  e3_client_prepar
3200: 65 28 70 2d 3e 64 62 2c 20 70 2d 3e 7a 41 72 67  e(p->db, p->zArg
3210: 2c 20 2d 31 2c 20 26 70 2d 3e 70 53 74 6d 74 2c  , -1, &p->pStmt,
3220: 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73   0);.}../*.** Us
3230: 61 67 65 3a 20 63 6c 69 65 6e 74 5f 63 6f 6d 70  age: client_comp
3240: 69 6c 65 20 49 44 20 53 51 4c 0a 2a 2a 0a 2a 2a  ile ID SQL.**.**
3250: 20 43 6f 6d 70 69 6c 65 20 61 20 6e 65 77 20 76   Compile a new v
3260: 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65 2e 0a  irtual machine..
3270: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  */.static int tc
3280: 6c 5f 63 6c 69 65 6e 74 5f 63 6f 6d 70 69 6c 65  l_client_compile
3290: 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74 55 73 65  (.  void *NotUse
32a0: 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  d,.  Tcl_Interp 
32b0: 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54  *interp,    /* T
32c0: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
32d0: 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20  er that invoked 
32e0: 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a  this command */.
32f0: 20 20 69 6e 74 20 61 72 67 63 2c 20 20 20 20 20    int argc,     
3300: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
3310: 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  er of arguments 
3320: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
3330: 2a 2a 61 72 67 76 20 20 20 20 20 20 2f 2a 20 54  **argv      /* T
3340: 65 78 74 20 6f 66 20 65 61 63 68 20 61 72 67 75  ext of each argu
3350: 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ment */.){.  int
3360: 20 69 3b 0a 20 20 69 66 28 20 61 72 67 63 21 3d   i;.  if( argc!=
3370: 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70  3 ){.    Tcl_App
3380: 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70  endResult(interp
3390: 2c 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a  , "wrong # args:
33a0: 20 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20   should be \"", 
33b0: 61 72 67 76 5b 30 5d 2c 0a 20 20 20 20 20 20 20  argv[0],.       
33c0: 22 20 49 44 20 53 51 4c 22 2c 20 30 29 3b 0a 20  " ID SQL", 0);. 
33d0: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
33e0: 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70  ROR;.  }.  i = p
33f0: 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69 64 28 69  arse_client_id(i
3400: 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b  nterp, argv[1]);
3410: 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72 65 74  .  if( i<0 ) ret
3420: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
3430: 20 69 66 28 20 21 74 68 72 65 61 64 73 65 74 5b   if( !threadset[
3440: 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54  i].busy ){.    T
3450: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
3460: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
3470: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
3480: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
3490: 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69 65 6e 74  OR;.  }.  client
34a0: 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65 74  _wait(&threadset
34b0: 5b 69 5d 29 3b 0a 20 20 74 68 72 65 61 64 73 65  [i]);.  threadse
34c0: 74 5b 69 5d 2e 78 4f 70 20 3d 20 64 6f 5f 63 6f  t[i].xOp = do_co
34d0: 6d 70 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33  mpile;.  sqlite3
34e0: 5f 66 72 65 65 28 74 68 72 65 61 64 73 65 74 5b  _free(threadset[
34f0: 69 5d 2e 7a 41 72 67 29 3b 0a 20 20 74 68 72 65  i].zArg);.  thre
3500: 61 64 73 65 74 5b 69 5d 2e 7a 41 72 67 20 3d 20  adset[i].zArg = 
3510: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
3520: 22 25 73 22 2c 20 61 72 67 76 5b 32 5d 29 3b 0a  "%s", argv[2]);.
3530: 20 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e 6f    threadset[i].o
3540: 70 6e 75 6d 2b 2b 3b 0a 20 20 72 65 74 75 72 6e  pnum++;.  return
3550: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a   TCL_OK;.}../*.*
3560: 2a 20 54 68 69 73 20 70 72 6f 63 65 64 75 72 65  * This procedure
3570: 20 72 75 6e 73 20 69 6e 20 74 68 65 20 74 68 72   runs in the thr
3580: 65 61 64 20 74 6f 20 73 74 65 70 20 74 68 65 20  ead to step the 
3590: 76 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65 2e  virtual machine.
35a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
35b0: 64 6f 5f 73 74 65 70 28 54 68 72 65 61 64 20 2a  do_step(Thread *
35c0: 70 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  p){.  int i;.  i
35d0: 66 28 20 70 2d 3e 70 53 74 6d 74 3d 3d 30 20 29  f( p->pStmt==0 )
35e0: 7b 0a 20 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20  {.    p->zErr = 
35f0: 70 2d 3e 7a 53 74 61 74 69 63 45 72 72 20 3d 20  p->zStaticErr = 
3600: 22 6e 6f 20 76 69 72 74 75 61 6c 20 6d 61 63 68  "no virtual mach
3610: 69 6e 65 20 61 76 61 69 6c 61 62 6c 65 22 3b 0a  ine available";.
3620: 20 20 20 20 70 2d 3e 72 63 20 3d 20 53 51 4c 49      p->rc = SQLI
3630: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 72 65  TE_ERROR;.    re
3640: 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 70 2d 3e 72  turn;.  }.  p->r
3650: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 6c 69 65  c = sqlite3_clie
3660: 6e 74 5f 73 74 65 70 28 70 2d 3e 70 53 74 6d 74  nt_step(p->pStmt
3670: 29 3b 0a 20 20 69 66 28 20 70 2d 3e 72 63 3d 3d  );.  if( p->rc==
3680: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
3690: 20 20 70 2d 3e 61 72 67 63 20 3d 20 73 71 6c 69    p->argc = sqli
36a0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74  te3_column_count
36b0: 28 70 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20  (p->pStmt);.    
36c0: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 71 6c 69 74  for(i=0; i<sqlit
36d0: 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 2d  e3_data_count(p-
36e0: 3e 70 53 74 6d 74 29 3b 20 69 2b 2b 29 7b 0a 20  >pStmt); i++){. 
36f0: 20 20 20 20 20 70 2d 3e 61 72 67 76 5b 69 5d 20       p->argv[i] 
3700: 3d 20 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  = (char*)sqlite3
3710: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 2d 3e  _column_text(p->
3720: 70 53 74 6d 74 2c 20 69 29 3b 0a 20 20 20 20 7d  pStmt, i);.    }
3730: 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  .    for(i=0; i<
3740: 70 2d 3e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20  p->argc; i++){. 
3750: 20 20 20 20 20 70 2d 3e 63 6f 6c 76 5b 69 5d 20       p->colv[i] 
3760: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
3770: 5f 6e 61 6d 65 28 70 2d 3e 70 53 74 6d 74 2c 20  _name(p->pStmt, 
3780: 69 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  i);.    }.  }.}.
3790: 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 63 6c  ./*.** Usage: cl
37a0: 69 65 6e 74 5f 73 74 65 70 20 49 44 0a 2a 2a 0a  ient_step ID.**.
37b0: 2a 2a 20 41 64 76 61 6e 63 65 20 74 68 65 20 76  ** Advance the v
37c0: 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65 20 62  irtual machine b
37d0: 79 20 6f 6e 65 20 73 74 65 70 0a 2a 2f 0a 73 74  y one step.*/.st
37e0: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 63 6c 69  atic int tcl_cli
37f0: 65 6e 74 5f 73 74 65 70 28 0a 20 20 76 6f 69 64  ent_step(.  void
3800: 20 2a 4e 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c   *NotUsed,.  Tcl
3810: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
3820: 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69      /* The TCL i
3830: 6e 74 65 72 70 72 65 74 65 72 20 74 68 61 74 20  nterpreter that 
3840: 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d  invoked this com
3850: 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72  mand */.  int ar
3860: 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  gc,             
3870: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72   /* Number of ar
3880: 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e  guments */.  con
3890: 73 74 20 63 68 61 72 20 2a 2a 61 72 67 76 20 20  st char **argv  
38a0: 20 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 65      /* Text of e
38b0: 61 63 68 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a  ach argument */.
38c0: 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 66  ){.  int i;.  if
38d0: 28 20 61 72 67 63 21 3d 32 20 29 7b 0a 20 20 20  ( argc!=2 ){.   
38e0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
38f0: 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67  t(interp, "wrong
3900: 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20   # args: should 
3910: 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c  be \"", argv[0],
3920: 0a 20 20 20 20 20 20 20 22 20 49 44 4c 22 2c 20  .       " IDL", 
3930: 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  0);.    return T
3940: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
3950: 69 20 3d 20 70 61 72 73 65 5f 63 6c 69 65 6e 74  i = parse_client
3960: 5f 69 64 28 69 6e 74 65 72 70 2c 20 61 72 67 76  _id(interp, argv
3970: 5b 31 5d 29 3b 0a 20 20 69 66 28 20 69 3c 30 20  [1]);.  if( i<0 
3980: 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52  ) return TCL_ERR
3990: 4f 52 3b 0a 20 20 69 66 28 20 21 74 68 72 65 61  OR;.  if( !threa
39a0: 64 73 65 74 5b 69 5d 2e 62 75 73 79 20 29 7b 0a  dset[i].busy ){.
39b0: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
39c0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f  sult(interp, "no
39d0: 20 73 75 63 68 20 74 68 72 65 61 64 22 2c 20 30   such thread", 0
39e0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
39f0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 63  L_ERROR;.  }.  c
3a00: 6c 69 65 6e 74 5f 77 61 69 74 28 26 74 68 72 65  lient_wait(&thre
3a10: 61 64 73 65 74 5b 69 5d 29 3b 0a 20 20 74 68 72  adset[i]);.  thr
3a20: 65 61 64 73 65 74 5b 69 5d 2e 78 4f 70 20 3d 20  eadset[i].xOp = 
3a30: 64 6f 5f 73 74 65 70 3b 0a 20 20 74 68 72 65 61  do_step;.  threa
3a40: 64 73 65 74 5b 69 5d 2e 6f 70 6e 75 6d 2b 2b 3b  dset[i].opnum++;
3a50: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
3a60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
3a70: 70 72 6f 63 65 64 75 72 65 20 72 75 6e 73 20 69  procedure runs i
3a80: 6e 20 74 68 65 20 74 68 72 65 61 64 20 74 6f 20  n the thread to 
3a90: 66 69 6e 61 6c 69 7a 65 20 61 20 76 69 72 74 75  finalize a virtu
3aa0: 61 6c 20 6d 61 63 68 69 6e 65 2e 0a 2a 2f 0a 73  al machine..*/.s
3ab0: 74 61 74 69 63 20 76 6f 69 64 20 64 6f 5f 66 69  tatic void do_fi
3ac0: 6e 61 6c 69 7a 65 28 54 68 72 65 61 64 20 2a 70  nalize(Thread *p
3ad0: 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 53 74 6d  ){.  if( p->pStm
3ae0: 74 3d 3d 30 20 29 7b 0a 20 20 20 20 70 2d 3e 7a  t==0 ){.    p->z
3af0: 45 72 72 20 3d 20 70 2d 3e 7a 53 74 61 74 69 63  Err = p->zStatic
3b00: 45 72 72 20 3d 20 22 6e 6f 20 76 69 72 74 75 61  Err = "no virtua
3b10: 6c 20 6d 61 63 68 69 6e 65 20 61 76 61 69 6c 61  l machine availa
3b20: 62 6c 65 22 3b 0a 20 20 20 20 70 2d 3e 72 63 20  ble";.    p->rc 
3b30: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
3b40: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
3b50: 20 20 70 2d 3e 72 63 20 3d 20 73 71 6c 69 74 65    p->rc = sqlite
3b60: 33 5f 63 6c 69 65 6e 74 5f 66 69 6e 61 6c 69 7a  3_client_finaliz
3b70: 65 28 70 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 70  e(p->pStmt);.  p
3b80: 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 7d 0a 0a  ->pStmt = 0;.}..
3b90: 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a 20 63 6c 69  /*.** Usage: cli
3ba0: 65 6e 74 5f 66 69 6e 61 6c 69 7a 65 20 49 44 0a  ent_finalize ID.
3bb0: 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 69 7a 65 20 74  **.** Finalize t
3bc0: 68 65 20 76 69 72 74 75 61 6c 20 6d 61 63 68 69  he virtual machi
3bd0: 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ne..*/.static in
3be0: 74 20 74 63 6c 5f 63 6c 69 65 6e 74 5f 66 69 6e  t tcl_client_fin
3bf0: 61 6c 69 7a 65 28 0a 20 20 76 6f 69 64 20 2a 4e  alize(.  void *N
3c00: 6f 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e  otUsed,.  Tcl_In
3c10: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20  terp *interp,   
3c20: 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65   /* The TCL inte
3c30: 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76  rpreter that inv
3c40: 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e  oked this comman
3c50: 64 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c  d */.  int argc,
3c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3c70: 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d   Number of argum
3c80: 65 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ents */.  const 
3c90: 63 68 61 72 20 2a 2a 61 72 67 76 20 20 20 20 20  char **argv     
3ca0: 20 2f 2a 20 54 65 78 74 20 6f 66 20 65 61 63 68   /* Text of each
3cb0: 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a   argument */.){.
3cc0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 61    int i;.  if( a
3cd0: 72 67 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  rgc!=2 ){.    Tc
3ce0: 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69  l_AppendResult(i
3cf0: 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20  nterp, "wrong # 
3d00: 61 72 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20  args: should be 
3d10: 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20  \"", argv[0],.  
3d20: 20 20 20 20 20 22 20 49 44 4c 22 2c 20 30 29 3b       " IDL", 0);
3d30: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
3d40: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d  ERROR;.  }.  i =
3d50: 20 70 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69 64   parse_client_id
3d60: 28 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d  (interp, argv[1]
3d70: 29 3b 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72  );.  if( i<0 ) r
3d80: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
3d90: 0a 20 20 69 66 28 20 21 74 68 72 65 61 64 73 65  .  if( !threadse
3da0: 74 5b 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20  t[i].busy ){.   
3db0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
3dc0: 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75  t(interp, "no su
3dd0: 63 68 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a  ch thread", 0);.
3de0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
3df0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69 65  RROR;.  }.  clie
3e00: 6e 74 5f 77 61 69 74 28 26 74 68 72 65 61 64 73  nt_wait(&threads
3e10: 65 74 5b 69 5d 29 3b 0a 20 20 74 68 72 65 61 64  et[i]);.  thread
3e20: 73 65 74 5b 69 5d 2e 78 4f 70 20 3d 20 64 6f 5f  set[i].xOp = do_
3e30: 66 69 6e 61 6c 69 7a 65 3b 0a 20 20 73 71 6c 69  finalize;.  sqli
3e40: 74 65 33 5f 66 72 65 65 28 74 68 72 65 61 64 73  te3_free(threads
3e50: 65 74 5b 69 5d 2e 7a 41 72 67 29 3b 0a 20 20 74  et[i].zArg);.  t
3e60: 68 72 65 61 64 73 65 74 5b 69 5d 2e 7a 41 72 67  hreadset[i].zArg
3e70: 20 3d 20 30 3b 0a 20 20 74 68 72 65 61 64 73 65   = 0;.  threadse
3e80: 74 5b 69 5d 2e 6f 70 6e 75 6d 2b 2b 3b 0a 20 20  t[i].opnum++;.  
3e90: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
3ea0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 70 72 6f  ../*.** This pro
3eb0: 63 65 64 75 72 65 20 72 75 6e 73 20 69 6e 20 74  cedure runs in t
3ec0: 68 65 20 74 68 72 65 61 64 20 74 6f 20 72 65 73  he thread to res
3ed0: 65 74 20 61 20 76 69 72 74 75 61 6c 20 6d 61 63  et a virtual mac
3ee0: 68 69 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  hine..*/.static 
3ef0: 76 6f 69 64 20 64 6f 5f 72 65 73 65 74 28 54 68  void do_reset(Th
3f00: 72 65 61 64 20 2a 70 29 7b 0a 20 20 69 66 28 20  read *p){.  if( 
3f10: 70 2d 3e 70 53 74 6d 74 3d 3d 30 20 29 7b 0a 20  p->pStmt==0 ){. 
3f20: 20 20 20 70 2d 3e 7a 45 72 72 20 3d 20 70 2d 3e     p->zErr = p->
3f30: 7a 53 74 61 74 69 63 45 72 72 20 3d 20 22 6e 6f  zStaticErr = "no
3f40: 20 76 69 72 74 75 61 6c 20 6d 61 63 68 69 6e 65   virtual machine
3f50: 20 61 76 61 69 6c 61 62 6c 65 22 3b 0a 20 20 20   available";.   
3f60: 20 70 2d 3e 72 63 20 3d 20 53 51 4c 49 54 45 5f   p->rc = SQLITE_
3f70: 45 52 52 4f 52 3b 0a 20 20 20 20 72 65 74 75 72  ERROR;.    retur
3f80: 6e 3b 0a 20 20 7d 0a 20 20 70 2d 3e 72 63 20 3d  n;.  }.  p->rc =
3f90: 20 73 71 6c 69 74 65 33 5f 63 6c 69 65 6e 74 5f   sqlite3_client_
3fa0: 72 65 73 65 74 28 70 2d 3e 70 53 74 6d 74 29 3b  reset(p->pStmt);
3fb0: 0a 20 20 70 2d 3e 70 53 74 6d 74 20 3d 20 30 3b  .  p->pStmt = 0;
3fc0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55 73 61 67 65 3a  .}../*.** Usage:
3fd0: 20 63 6c 69 65 6e 74 5f 72 65 73 65 74 20 49 44   client_reset ID
3fe0: 0a 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 69 7a 65 20  .**.** Finalize 
3ff0: 74 68 65 20 76 69 72 74 75 61 6c 20 6d 61 63 68  the virtual mach
4000: 69 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ine..*/.static i
4010: 6e 74 20 74 63 6c 5f 63 6c 69 65 6e 74 5f 72 65  nt tcl_client_re
4020: 73 65 74 28 0a 20 20 76 6f 69 64 20 2a 4e 6f 74  set(.  void *Not
4030: 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Used,.  Tcl_Inte
4040: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
4050: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
4060: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
4070: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
4080: 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 20  */.  int argc,  
4090: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
40a0: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
40b0: 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ts */.  const ch
40c0: 61 72 20 2a 2a 61 72 67 76 20 20 20 20 20 20 2f  ar **argv      /
40d0: 2a 20 54 65 78 74 20 6f 66 20 65 61 63 68 20 61  * Text of each a
40e0: 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20 20  rgument */.){.  
40f0: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 61 72 67  int i;.  if( arg
4100: 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=2 ){.    Tcl_
4110: 41 70 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74  AppendResult(int
4120: 65 72 70 2c 20 22 77 72 6f 6e 67 20 23 20 61 72  erp, "wrong # ar
4130: 67 73 3a 20 73 68 6f 75 6c 64 20 62 65 20 5c 22  gs: should be \"
4140: 22 2c 20 61 72 67 76 5b 30 5d 2c 0a 20 20 20 20  ", argv[0],.    
4150: 20 20 20 22 20 49 44 4c 22 2c 20 30 29 3b 0a 20     " IDL", 0);. 
4160: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
4170: 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 20 3d 20 70  ROR;.  }.  i = p
4180: 61 72 73 65 5f 63 6c 69 65 6e 74 5f 69 64 28 69  arse_client_id(i
4190: 6e 74 65 72 70 2c 20 61 72 67 76 5b 31 5d 29 3b  nterp, argv[1]);
41a0: 0a 20 20 69 66 28 20 69 3c 30 20 29 20 72 65 74  .  if( i<0 ) ret
41b0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
41c0: 20 69 66 28 20 21 74 68 72 65 61 64 73 65 74 5b   if( !threadset[
41d0: 69 5d 2e 62 75 73 79 20 29 7b 0a 20 20 20 20 54  i].busy ){.    T
41e0: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
41f0: 69 6e 74 65 72 70 2c 20 22 6e 6f 20 73 75 63 68  interp, "no such
4200: 20 74 68 72 65 61 64 22 2c 20 30 29 3b 0a 20 20   thread", 0);.  
4210: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
4220: 4f 52 3b 0a 20 20 7d 0a 20 20 63 6c 69 65 6e 74  OR;.  }.  client
4230: 5f 77 61 69 74 28 26 74 68 72 65 61 64 73 65 74  _wait(&threadset
4240: 5b 69 5d 29 3b 0a 20 20 74 68 72 65 61 64 73 65  [i]);.  threadse
4250: 74 5b 69 5d 2e 78 4f 70 20 3d 20 64 6f 5f 72 65  t[i].xOp = do_re
4260: 73 65 74 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  set;.  sqlite3_f
4270: 72 65 65 28 74 68 72 65 61 64 73 65 74 5b 69 5d  ree(threadset[i]
4280: 2e 7a 41 72 67 29 3b 0a 20 20 74 68 72 65 61 64  .zArg);.  thread
4290: 73 65 74 5b 69 5d 2e 7a 41 72 67 20 3d 20 30 3b  set[i].zArg = 0;
42a0: 0a 20 20 74 68 72 65 61 64 73 65 74 5b 69 5d 2e  .  threadset[i].
42b0: 6f 70 6e 75 6d 2b 2b 3b 0a 20 20 72 65 74 75 72  opnum++;.  retur
42c0: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
42d0: 2a 2a 20 55 73 61 67 65 3a 20 63 6c 69 65 6e 74  ** Usage: client
42e0: 5f 73 77 61 70 20 49 44 20 49 44 0a 2a 2a 0a 2a  _swap ID ID.**.*
42f0: 2a 20 49 6e 74 65 72 63 68 61 6e 67 65 20 74 68  * Interchange th
4300: 65 20 73 71 6c 69 74 65 2a 20 70 6f 69 6e 74 65  e sqlite* pointe
4310: 72 20 62 65 74 77 65 65 6e 20 74 77 6f 20 74 68  r between two th
4320: 72 65 61 64 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  reads..*/.static
4330: 20 69 6e 74 20 74 63 6c 5f 63 6c 69 65 6e 74 5f   int tcl_client_
4340: 73 77 61 70 28 0a 20 20 76 6f 69 64 20 2a 4e 6f  swap(.  void *No
4350: 74 55 73 65 64 2c 0a 20 20 54 63 6c 5f 49 6e 74  tUsed,.  Tcl_Int
4360: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20  erp *interp,    
4370: 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72  /* The TCL inter
4380: 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f  preter that invo
4390: 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64  ked this command
43a0: 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20   */.  int argc, 
43b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
43c0: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65  Number of argume
43d0: 6e 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  nts */.  const c
43e0: 68 61 72 20 2a 2a 61 72 67 76 20 20 20 20 20 20  har **argv      
43f0: 2f 2a 20 54 65 78 74 20 6f 66 20 65 61 63 68 20  /* Text of each 
4400: 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 29 7b 0a 20  argument */.){. 
4410: 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 73 71 6c   int i, j;.  sql
4420: 69 74 65 33 20 2a 74 65 6d 70 3b 0a 20 20 69 66  ite3 *temp;.  if
4430: 28 20 61 72 67 63 21 3d 33 20 29 7b 0a 20 20 20  ( argc!=3 ){.   
4440: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
4450: 74 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67  t(interp, "wrong
4460: 20 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20   # args: should 
4470: 62 65 20 5c 22 22 2c 20 61 72 67 76 5b 30 5d 2c  be \"", argv[0],
4480: 0a 20 20 20 20 20 20 20 22 20 49 44 31 20 49 44  .       " ID1 ID
4490: 32 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75  2", 0);.    retu
44a0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
44b0: 7d 0a 20 20 69 20 3d 20 70 61 72 73 65 5f 63 6c  }.  i = parse_cl
44c0: 69 65 6e 74 5f 69 64 28 69 6e 74 65 72 70 2c 20  ient_id(interp, 
44d0: 61 72 67 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20  argv[1]);.  if( 
44e0: 69 3c 30 20 29 20 72 65 74 75 72 6e 20 54 43 4c  i<0 ) return TCL
44f0: 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 21 74  _ERROR;.  if( !t
4500: 68 72 65 61 64 73 65 74 5b 69 5d 2e 62 75 73 79  hreadset[i].busy
4510: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65   ){.    Tcl_Appe
4520: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
4530: 20 22 6e 6f 20 73 75 63 68 20 74 68 72 65 61 64   "no such thread
4540: 22 2c 20 30 29 3b 0a 20 20 20 20 72 65 74 75 72  ", 0);.    retur
4550: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
4560: 0a 20 20 63 6c 69 65 6e 74 5f 77 61 69 74 28 26  .  client_wait(&
4570: 74 68 72 65 61 64 73 65 74 5b 69 5d 29 3b 0a 20  threadset[i]);. 
4580: 20 6a 20 3d 20 70 61 72 73 65 5f 63 6c 69 65 6e   j = parse_clien
4590: 74 5f 69 64 28 69 6e 74 65 72 70 2c 20 61 72 67  t_id(interp, arg
45a0: 76 5b 32 5d 29 3b 0a 20 20 69 66 28 20 6a 3c 30  v[2]);.  if( j<0
45b0: 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52   ) return TCL_ER
45c0: 52 4f 52 3b 0a 20 20 69 66 28 20 21 74 68 72 65  ROR;.  if( !thre
45d0: 61 64 73 65 74 5b 6a 5d 2e 62 75 73 79 20 29 7b  adset[j].busy ){
45e0: 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52  .    Tcl_AppendR
45f0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e  esult(interp, "n
4600: 6f 20 73 75 63 68 20 74 68 72 65 61 64 22 2c 20  o such thread", 
4610: 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  0);.    return T
4620: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
4630: 63 6c 69 65 6e 74 5f 77 61 69 74 28 26 74 68 72  client_wait(&thr
4640: 65 61 64 73 65 74 5b 6a 5d 29 3b 0a 20 20 74 65  eadset[j]);.  te
4650: 6d 70 20 3d 20 74 68 72 65 61 64 73 65 74 5b 69  mp = threadset[i
4660: 5d 2e 64 62 3b 0a 20 20 74 68 72 65 61 64 73 65  ].db;.  threadse
4670: 74 5b 69 5d 2e 64 62 20 3d 20 74 68 72 65 61 64  t[i].db = thread
4680: 73 65 74 5b 6a 5d 2e 64 62 3b 0a 20 20 74 68 72  set[j].db;.  thr
4690: 65 61 64 73 65 74 5b 6a 5d 2e 64 62 20 3d 20 74  eadset[j].db = t
46a0: 65 6d 70 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  emp;.  return TC
46b0: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  L_OK;.}../*.** R
46c0: 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73  egister commands
46d0: 20 77 69 74 68 20 74 68 65 20 54 43 4c 20 69 6e   with the TCL in
46e0: 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e  terpreter..*/.in
46f0: 74 20 53 71 6c 69 74 65 74 65 73 74 37 5f 49 6e  t Sqlitetest7_In
4700: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
4710: 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74 69 63  nterp){.  static
4720: 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20 63   struct {.     c
4730: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
4740: 20 54 63 6c 5f 43 6d 64 50 72 6f 63 20 2a 78 50   Tcl_CmdProc *xP
4750: 72 6f 63 3b 0a 20 20 7d 20 61 43 6d 64 5b 5d 20  roc;.  } aCmd[] 
4760: 3d 20 7b 0a 20 20 20 20 20 7b 20 22 63 6c 69 65  = {.     { "clie
4770: 6e 74 5f 63 72 65 61 74 65 22 2c 20 20 20 20 20  nt_create",     
4780: 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63  (Tcl_CmdProc*)tc
4790: 6c 5f 63 6c 69 65 6e 74 5f 63 72 65 61 74 65 20  l_client_create 
47a0: 20 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22 63      },.     { "c
47b0: 6c 69 65 6e 74 5f 77 61 69 74 22 2c 20 20 20 20  lient_wait",    
47c0: 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a     (Tcl_CmdProc*
47d0: 29 74 63 6c 5f 63 6c 69 65 6e 74 5f 77 61 69 74  )tcl_client_wait
47e0: 20 20 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 7b         },.     {
47f0: 20 22 63 6c 69 65 6e 74 5f 68 61 6c 74 22 2c 20   "client_halt", 
4800: 20 20 20 20 20 20 28 54 63 6c 5f 43 6d 64 50 72        (Tcl_CmdPr
4810: 6f 63 2a 29 74 63 6c 5f 63 6c 69 65 6e 74 5f 68  oc*)tcl_client_h
4820: 61 6c 74 20 20 20 20 20 20 20 7d 2c 0a 20 20 20  alt       },.   
4830: 20 20 7b 20 22 63 6c 69 65 6e 74 5f 61 72 67 63    { "client_argc
4840: 22 2c 20 20 20 20 20 20 20 28 54 63 6c 5f 43 6d  ",       (Tcl_Cm
4850: 64 50 72 6f 63 2a 29 74 63 6c 5f 63 6c 69 65 6e  dProc*)tcl_clien
4860: 74 5f 61 72 67 63 20 20 20 20 20 20 20 7d 2c 0a  t_argc       },.
4870: 20 20 20 20 20 7b 20 22 63 6c 69 65 6e 74 5f 61       { "client_a
4880: 72 67 76 22 2c 20 20 20 20 20 20 20 28 54 63 6c  rgv",       (Tcl
4890: 5f 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f 63 6c  _CmdProc*)tcl_cl
48a0: 69 65 6e 74 5f 61 72 67 76 20 20 20 20 20 20 20  ient_argv       
48b0: 7d 2c 0a 20 20 20 20 20 7b 20 22 63 6c 69 65 6e  },.     { "clien
48c0: 74 5f 63 6f 6c 6e 61 6d 65 22 2c 20 20 20 20 28  t_colname",    (
48d0: 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63 6c  Tcl_CmdProc*)tcl
48e0: 5f 63 6c 69 65 6e 74 5f 63 6f 6c 6e 61 6d 65 20  _client_colname 
48f0: 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22 63 6c     },.     { "cl
4900: 69 65 6e 74 5f 72 65 73 75 6c 74 22 2c 20 20 20  ient_result",   
4910: 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29    (Tcl_CmdProc*)
4920: 74 63 6c 5f 63 6c 69 65 6e 74 5f 72 65 73 75 6c  tcl_client_resul
4930: 74 20 20 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20  t     },.     { 
4940: 22 63 6c 69 65 6e 74 5f 65 72 72 6f 72 22 2c 20  "client_error", 
4950: 20 20 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f       (Tcl_CmdPro
4960: 63 2a 29 74 63 6c 5f 63 6c 69 65 6e 74 5f 65 72  c*)tcl_client_er
4970: 72 6f 72 20 20 20 20 20 20 7d 2c 0a 20 20 20 20  ror      },.    
4980: 20 7b 20 22 63 6c 69 65 6e 74 5f 63 6f 6d 70 69   { "client_compi
4990: 6c 65 22 2c 20 20 20 20 28 54 63 6c 5f 43 6d 64  le",    (Tcl_Cmd
49a0: 50 72 6f 63 2a 29 74 63 6c 5f 63 6c 69 65 6e 74  Proc*)tcl_client
49b0: 5f 63 6f 6d 70 69 6c 65 20 20 20 20 7d 2c 0a 20  _compile    },. 
49c0: 20 20 20 20 7b 20 22 63 6c 69 65 6e 74 5f 73 74      { "client_st
49d0: 65 70 22 2c 20 20 20 20 20 20 20 28 54 63 6c 5f  ep",       (Tcl_
49e0: 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f 63 6c 69  CmdProc*)tcl_cli
49f0: 65 6e 74 5f 73 74 65 70 20 20 20 20 20 20 20 7d  ent_step       }
4a00: 2c 0a 20 20 20 20 20 7b 20 22 63 6c 69 65 6e 74  ,.     { "client
4a10: 5f 72 65 73 65 74 22 2c 20 20 20 20 20 20 28 54  _reset",      (T
4a20: 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74 63 6c 5f  cl_CmdProc*)tcl_
4a30: 63 6c 69 65 6e 74 5f 72 65 73 65 74 20 20 20 20  client_reset    
4a40: 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22 63 6c 69    },.     { "cli
4a50: 65 6e 74 5f 66 69 6e 61 6c 69 7a 65 22 2c 20 20  ent_finalize",  
4a60: 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63 2a 29 74   (Tcl_CmdProc*)t
4a70: 63 6c 5f 63 6c 69 65 6e 74 5f 66 69 6e 61 6c 69  cl_client_finali
4a80: 7a 65 20 20 20 7d 2c 0a 20 20 20 20 20 7b 20 22  ze   },.     { "
4a90: 63 6c 69 65 6e 74 5f 73 77 61 70 22 2c 20 20 20  client_swap",   
4aa0: 20 20 20 20 28 54 63 6c 5f 43 6d 64 50 72 6f 63      (Tcl_CmdProc
4ab0: 2a 29 74 63 6c 5f 63 6c 69 65 6e 74 5f 73 77 61  *)tcl_client_swa
4ac0: 70 20 20 20 20 20 20 20 7d 2c 0a 20 20 7d 3b 0a  p       },.  };.
4ad0: 20 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28    int i;..  for(
4ae0: 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 43  i=0; i<sizeof(aC
4af0: 6d 64 29 2f 73 69 7a 65 6f 66 28 61 43 6d 64 5b  md)/sizeof(aCmd[
4b00: 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54  0]); i++){.    T
4b10: 63 6c 5f 43 72 65 61 74 65 43 6f 6d 6d 61 6e 64  cl_CreateCommand
4b20: 28 69 6e 74 65 72 70 2c 20 61 43 6d 64 5b 69 5d  (interp, aCmd[i]
4b30: 2e 7a 4e 61 6d 65 2c 20 61 43 6d 64 5b 69 5d 2e  .zName, aCmd[i].
4b40: 78 50 72 6f 63 2c 20 30 2c 20 30 29 3b 0a 20 20  xProc, 0, 0);.  
4b50: 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  }.  return TCL_O
4b60: 4b 3b 0a 7d 0a 23 65 6c 73 65 0a 69 6e 74 20 53  K;.}.#else.int S
4b70: 71 6c 69 74 65 74 65 73 74 37 5f 49 6e 69 74 28  qlitetest7_Init(
4b80: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
4b90: 72 70 29 7b 20 72 65 74 75 72 6e 20 54 43 4c 5f  rp){ return TCL_
4ba0: 4f 4b 3b 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20  OK; }.#endif /* 
4bb0: 53 51 4c 49 54 45 5f 4f 53 5f 55 4e 49 58 20 2a  SQLITE_OS_UNIX *
4bc0: 2f 0a                                            /.