/ Hex Artifact Content
Login

Artifact 65297bcce8d5acd5aadef42acbe739aef5a2ef5e74c7b73361ca19f3e21de657:


0000: 2f 2a 0a 2a 2a 20 32 30 31 36 2d 30 35 2d 32 38  /*.** 2016-05-28
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
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 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 6e 20 53 51 4c 69 74 65 20 76 69   of an SQLite vi
01b0: 72 74 75 61 6c 20 74 61 62 6c 65 20 66 6f 72 0a  rtual table for.
01c0: 2a 2a 20 72 65 61 64 69 6e 67 20 43 53 56 20 66  ** reading CSV f
01d0: 69 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20 55 73 61 67  iles..**.** Usag
01e0: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 2e 6c 6f 61  e:.**.**    .loa
01f0: 64 20 2e 2f 63 73 76 0a 2a 2a 20 20 20 20 43 52  d ./csv.**    CR
0200: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42  EATE VIRTUAL TAB
0210: 4c 45 20 74 65 6d 70 2e 63 73 76 20 55 53 49 4e  LE temp.csv USIN
0220: 47 20 63 73 76 28 66 69 6c 65 6e 61 6d 65 3d 46  G csv(filename=F
0230: 49 4c 45 4e 41 4d 45 29 3b 0a 2a 2a 20 20 20 20  ILENAME);.**    
0240: 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 63 73  SELECT * FROM cs
0250: 76 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6c  v;.**.** The col
0260: 75 6d 6e 73 20 61 72 65 20 6e 61 6d 65 64 20 22  umns are named "
0270: 63 31 22 2c 20 22 63 32 22 2c 20 22 63 33 22 2c  c1", "c2", "c3",
0280: 20 2e 2e 2e 20 62 79 20 64 65 66 61 75 6c 74 2e   ... by default.
0290: 20 20 42 75 74 20 74 68 65 0a 2a 2a 20 61 70 70    But the.** app
02a0: 6c 69 63 61 74 69 6f 6e 20 63 61 6e 20 64 65 66  lication can def
02b0: 69 6e 65 20 69 74 73 20 6f 77 6e 20 43 52 45 41  ine its own CREA
02c0: 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65  TE TABLE stateme
02d0: 6e 74 20 61 73 20 61 6e 20 61 64 64 69 74 69 6f  nt as an additio
02e0: 6e 61 6c 0a 2a 2a 20 70 61 72 61 6d 65 74 65 72  nal.** parameter
02f0: 2e 20 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a  .  For example:.
0300: 2a 2a 0a 2a 2a 20 20 20 20 43 52 45 41 54 45 20  **.**    CREATE 
0310: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 65  VIRTUAL TABLE te
0320: 6d 70 2e 63 73 76 32 20 55 53 49 4e 47 20 63 73  mp.csv2 USING cs
0330: 76 28 0a 2a 2a 20 20 20 20 20 20 20 66 69 6c 65  v(.**       file
0340: 6e 61 6d 65 20 3d 20 22 2e 2e 2f 68 74 74 70 2e  name = "../http.
0350: 6c 6f 67 22 2c 0a 2a 2a 20 20 20 20 20 20 20 73  log",.**       s
0360: 63 68 65 6d 61 20 3d 20 22 43 52 45 41 54 45 20  chema = "CREATE 
0370: 54 41 42 4c 45 20 78 28 64 61 74 65 2c 69 70 61  TABLE x(date,ipa
0380: 64 64 72 2c 75 72 6c 2c 72 65 66 65 72 72 65 72  ddr,url,referrer
0390: 2c 75 73 65 72 41 67 65 6e 74 29 22 0a 2a 2a 20  ,userAgent)".** 
03a0: 20 20 20 29 3b 0a 2a 2a 0a 2a 2a 20 49 6e 73 74     );.**.** Inst
03b0: 65 61 64 20 6f 66 20 73 70 65 63 69 66 79 69 6e  ead of specifyin
03c0: 67 20 61 20 66 69 6c 65 2c 20 74 68 65 20 74 65  g a file, the te
03d0: 78 74 20 6f 66 20 74 68 65 20 43 53 56 20 63 61  xt of the CSV ca
03e0: 6e 20 62 65 20 6c 6f 61 64 65 64 20 75 73 69 6e  n be loaded usin
03f0: 67 0a 2a 2a 20 74 68 65 20 64 61 74 61 3d 20 70  g.** the data= p
0400: 61 72 61 6d 65 74 65 72 2e 0a 2a 2a 0a 2a 2a 20  arameter..**.** 
0410: 49 66 20 74 68 65 20 63 6f 6c 75 6d 6e 73 3d 4e  If the columns=N
0420: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 73 75   parameter is su
0430: 70 70 6c 69 65 64 2c 20 74 68 65 6e 20 74 68 65  pplied, then the
0440: 20 43 53 56 20 66 69 6c 65 20 69 73 20 61 73 73   CSV file is ass
0450: 75 6d 65 64 20 74 6f 20 68 61 76 65 0a 2a 2a 20  umed to have.** 
0460: 4e 20 63 6f 6c 75 6d 6e 73 2e 20 20 49 66 20 74  N columns.  If t
0470: 68 65 20 63 6f 6c 75 6d 6e 73 20 70 61 72 61 6d  he columns param
0480: 65 74 65 72 20 69 73 20 6f 6d 69 74 74 65 64 2c  eter is omitted,
0490: 20 74 68 65 20 43 53 56 20 66 69 6c 65 20 69 73   the CSV file is
04a0: 20 6f 70 65 6e 65 64 0a 2a 2a 20 61 73 20 73 6f   opened.** as so
04b0: 6f 6e 20 61 73 20 74 68 65 20 76 69 72 74 75 61  on as the virtua
04c0: 6c 20 74 61 62 6c 65 20 69 73 20 63 6f 6e 73 74  l table is const
04d0: 72 75 63 74 65 64 20 61 6e 64 20 74 68 65 20 66  ructed and the f
04e0: 69 72 73 74 20 72 6f 77 20 6f 66 20 74 68 65 20  irst row of the 
04f0: 43 53 56 0a 2a 2a 20 69 73 20 72 65 61 64 20 69  CSV.** is read i
0500: 6e 20 6f 72 64 65 72 20 74 6f 20 63 6f 75 6e 74  n order to count
0510: 20 74 68 65 20 74 61 62 6c 65 73 2e 0a 2a 2a 0a   the tables..**.
0520: 2a 2a 20 53 6f 6d 65 20 65 78 74 72 61 20 64 65  ** Some extra de
0530: 62 75 67 67 69 6e 67 20 66 65 61 74 75 72 65 73  bugging features
0540: 20 28 75 73 65 64 20 66 6f 72 20 74 65 73 74 69   (used for testi
0550: 6e 67 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ng virtual table
0560: 73 29 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65  s) are available
0570: 0a 2a 2a 20 69 66 20 74 68 69 73 20 6d 6f 64 75  .** if this modu
0580: 6c 65 20 69 73 20 63 6f 6d 70 69 6c 65 64 20 77  le is compiled w
0590: 69 74 68 20 2d 44 53 51 4c 49 54 45 5f 54 45 53  ith -DSQLITE_TES
05a0: 54 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c  T..*/.#include <
05b0: 73 71 6c 69 74 65 33 65 78 74 2e 68 3e 0a 53 51  sqlite3ext.h>.SQ
05c0: 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49  LITE_EXTENSION_I
05d0: 4e 49 54 31 0a 23 69 6e 63 6c 75 64 65 20 3c 73  NIT1.#include <s
05e0: 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64  tring.h>.#includ
05f0: 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e  e <stdlib.h>.#in
0600: 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e  clude <assert.h>
0610: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72  .#include <stdar
0620: 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 63  g.h>.#include <c
0630: 74 79 70 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  type.h>.#include
0640: 20 3c 73 74 64 69 6f 2e 68 3e 0a 0a 23 69 66 6e   <stdio.h>..#ifn
0650: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
0660: 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 0a 2f 2a  VIRTUALTABLE../*
0670: 0a 2a 2a 20 41 20 6d 61 63 72 6f 20 74 6f 20 68  .** A macro to h
0680: 69 6e 74 20 74 6f 20 74 68 65 20 63 6f 6d 70 69  int to the compi
0690: 6c 65 72 20 74 68 61 74 20 61 20 66 75 6e 63 74  ler that a funct
06a0: 69 6f 6e 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62  ion should not b
06b0: 65 0a 2a 2a 20 69 6e 6c 69 6e 65 64 2e 0a 2a 2f  e.** inlined..*/
06c0: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 5f 47  .#if defined(__G
06d0: 4e 55 43 5f 5f 29 0a 23 20 20 64 65 66 69 6e 65  NUC__).#  define
06e0: 20 43 53 56 5f 4e 4f 49 4e 4c 49 4e 45 20 20 5f   CSV_NOINLINE  _
06f0: 5f 61 74 74 72 69 62 75 74 65 5f 5f 28 28 6e 6f  _attribute__((no
0700: 69 6e 6c 69 6e 65 29 29 0a 23 65 6c 69 66 20 64  inline)).#elif d
0710: 65 66 69 6e 65 64 28 5f 4d 53 43 5f 56 45 52 29  efined(_MSC_VER)
0720: 20 26 26 20 5f 4d 53 43 5f 56 45 52 3e 3d 31 33   && _MSC_VER>=13
0730: 31 30 0a 23 20 20 64 65 66 69 6e 65 20 43 53 56  10.#  define CSV
0740: 5f 4e 4f 49 4e 4c 49 4e 45 20 20 5f 5f 64 65 63  _NOINLINE  __dec
0750: 6c 73 70 65 63 28 6e 6f 69 6e 6c 69 6e 65 29 0a  lspec(noinline).
0760: 23 65 6c 73 65 0a 23 20 20 64 65 66 69 6e 65 20  #else.#  define 
0770: 43 53 56 5f 4e 4f 49 4e 4c 49 4e 45 0a 23 65 6e  CSV_NOINLINE.#en
0780: 64 69 66 0a 0a 0a 2f 2a 20 4d 61 78 20 73 69 7a  dif.../* Max siz
0790: 65 20 6f 66 20 74 68 65 20 65 72 72 6f 72 20 6d  e of the error m
07a0: 65 73 73 61 67 65 20 69 6e 20 61 20 43 73 76 52  essage in a CsvR
07b0: 65 61 64 65 72 20 2a 2f 0a 23 64 65 66 69 6e 65  eader */.#define
07c0: 20 43 53 56 5f 4d 58 45 52 52 20 32 30 30 0a 0a   CSV_MXERR 200..
07d0: 2f 2a 20 53 69 7a 65 20 6f 66 20 74 68 65 20 43  /* Size of the C
07e0: 73 76 52 65 61 64 65 72 20 69 6e 70 75 74 20 62  svReader input b
07f0: 75 66 66 65 72 20 2a 2f 0a 23 64 65 66 69 6e 65  uffer */.#define
0800: 20 43 53 56 5f 49 4e 42 55 46 53 5a 20 31 30 32   CSV_INBUFSZ 102
0810: 34 0a 0a 2f 2a 20 41 20 63 6f 6e 74 65 78 74 20  4../* A context 
0820: 6f 62 6a 65 63 74 20 75 73 65 64 20 77 68 65 6e  object used when
0830: 20 72 65 61 64 20 61 20 43 53 56 20 66 69 6c 65   read a CSV file
0840: 2e 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  . */.typedef str
0850: 75 63 74 20 43 73 76 52 65 61 64 65 72 20 43 73  uct CsvReader Cs
0860: 76 52 65 61 64 65 72 3b 0a 73 74 72 75 63 74 20  vReader;.struct 
0870: 43 73 76 52 65 61 64 65 72 20 7b 0a 20 20 46 49  CsvReader {.  FI
0880: 4c 45 20 2a 69 6e 3b 20 20 20 20 20 20 20 20 20  LE *in;         
0890: 20 20 20 20 20 2f 2a 20 52 65 61 64 20 74 68 65       /* Read the
08a0: 20 43 53 56 20 74 65 78 74 20 66 72 6f 6d 20 74   CSV text from t
08b0: 68 69 73 20 69 6e 70 75 74 20 73 74 72 65 61 6d  his input stream
08c0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 3b 20 20   */.  char *z;  
08d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
08e0: 41 63 63 75 6d 75 6c 61 74 65 64 20 74 65 78 74  Accumulated text
08f0: 20 66 6f 72 20 61 20 66 69 65 6c 64 20 2a 2f 0a   for a field */.
0900: 20 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20    int n;        
0910: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0920: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 7a  er of bytes in z
0930: 20 2a 2f 0a 20 20 69 6e 74 20 6e 41 6c 6c 6f 63   */.  int nAlloc
0940: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
0950: 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 20  Space allocated 
0960: 66 6f 72 20 7a 5b 5d 20 2a 2f 0a 20 20 69 6e 74  for z[] */.  int
0970: 20 6e 4c 69 6e 65 3b 20 20 20 20 20 20 20 20 20   nLine;         
0980: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 6c      /* Current l
0990: 69 6e 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20  ine number */.  
09a0: 69 6e 74 20 62 4e 6f 74 46 69 72 73 74 3b 20 20  int bNotFirst;  
09b0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
09c0: 66 20 70 72 69 6f 72 20 74 65 78 74 20 68 61 73  f prior text has
09d0: 20 62 65 65 6e 20 73 65 65 6e 20 2a 2f 0a 20 20   been seen */.  
09e0: 69 6e 74 20 63 54 65 72 6d 3b 20 20 20 20 20 20  int cTerm;      
09f0: 20 20 20 20 20 20 20 2f 2a 20 43 68 61 72 61 63         /* Charac
0a00: 74 65 72 20 74 68 61 74 20 74 65 72 6d 69 6e 61  ter that termina
0a10: 74 65 64 20 74 68 65 20 6d 6f 73 74 20 72 65 63  ted the most rec
0a20: 65 6e 74 20 66 69 65 6c 64 20 2a 2f 0a 20 20 73  ent field */.  s
0a30: 69 7a 65 5f 74 20 69 49 6e 3b 20 20 20 20 20 20  ize_t iIn;      
0a40: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 75 6e        /* Next un
0a50: 72 65 61 64 20 63 68 61 72 61 63 74 65 72 20 69  read character i
0a60: 6e 20 74 68 65 20 69 6e 70 75 74 20 62 75 66 66  n the input buff
0a70: 65 72 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6e  er */.  size_t n
0a80: 49 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  In;            /
0a90: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 61 72  * Number of char
0aa0: 61 63 74 65 72 73 20 69 6e 20 74 68 65 20 69 6e  acters in the in
0ab0: 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  put buffer */.  
0ac0: 63 68 61 72 20 2a 7a 49 6e 3b 20 20 20 20 20 20  char *zIn;      
0ad0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 69 6e         /* The in
0ae0: 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  put buffer */.  
0af0: 63 68 61 72 20 7a 45 72 72 5b 43 53 56 5f 4d 58  char zErr[CSV_MX
0b00: 45 52 52 5d 3b 20 20 2f 2a 20 45 72 72 6f 72 20  ERR];  /* Error 
0b10: 6d 65 73 73 61 67 65 20 2a 2f 0a 7d 3b 0a 0a 2f  message */.};../
0b20: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 43  * Initialize a C
0b30: 73 76 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20  svReader object 
0b40: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63  */.static void c
0b50: 73 76 5f 72 65 61 64 65 72 5f 69 6e 69 74 28 43  sv_reader_init(C
0b60: 73 76 52 65 61 64 65 72 20 2a 70 29 7b 0a 20 20  svReader *p){.  
0b70: 70 2d 3e 69 6e 20 3d 20 30 3b 0a 20 20 70 2d 3e  p->in = 0;.  p->
0b80: 7a 20 3d 20 30 3b 0a 20 20 70 2d 3e 6e 20 3d 20  z = 0;.  p->n = 
0b90: 30 3b 0a 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20 3d  0;.  p->nAlloc =
0ba0: 20 30 3b 0a 20 20 70 2d 3e 6e 4c 69 6e 65 20 3d   0;.  p->nLine =
0bb0: 20 30 3b 0a 20 20 70 2d 3e 62 4e 6f 74 46 69 72   0;.  p->bNotFir
0bc0: 73 74 20 3d 20 30 3b 0a 20 20 70 2d 3e 6e 49 6e  st = 0;.  p->nIn
0bd0: 20 3d 20 30 3b 0a 20 20 70 2d 3e 7a 49 6e 20 3d   = 0;.  p->zIn =
0be0: 20 30 3b 0a 20 20 70 2d 3e 7a 45 72 72 5b 30 5d   0;.  p->zErr[0]
0bf0: 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20 43 6c 6f 73   = 0;.}../* Clos
0c00: 65 20 61 6e 64 20 72 65 73 65 74 20 61 20 43 73  e and reset a Cs
0c10: 76 52 65 61 64 65 72 20 6f 62 6a 65 63 74 20 2a  vReader object *
0c20: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 73  /.static void cs
0c30: 76 5f 72 65 61 64 65 72 5f 72 65 73 65 74 28 43  v_reader_reset(C
0c40: 73 76 52 65 61 64 65 72 20 2a 70 29 7b 0a 20 20  svReader *p){.  
0c50: 69 66 28 20 70 2d 3e 69 6e 20 29 7b 0a 20 20 20  if( p->in ){.   
0c60: 20 66 63 6c 6f 73 65 28 70 2d 3e 69 6e 29 3b 0a   fclose(p->in);.
0c70: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
0c80: 28 70 2d 3e 7a 49 6e 29 3b 0a 20 20 7d 0a 20 20  (p->zIn);.  }.  
0c90: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e  sqlite3_free(p->
0ca0: 7a 29 3b 0a 20 20 63 73 76 5f 72 65 61 64 65 72  z);.  csv_reader
0cb0: 5f 69 6e 69 74 28 70 29 3b 0a 7d 0a 0a 2f 2a 20  _init(p);.}../* 
0cc0: 52 65 70 6f 72 74 20 61 6e 20 65 72 72 6f 72 20  Report an error 
0cd0: 6f 6e 20 61 20 43 73 76 52 65 61 64 65 72 20 2a  on a CsvReader *
0ce0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 73  /.static void cs
0cf0: 76 5f 65 72 72 6d 73 67 28 43 73 76 52 65 61 64  v_errmsg(CsvRead
0d00: 65 72 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61  er *p, const cha
0d10: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29  r *zFormat, ...)
0d20: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
0d30: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
0d40: 46 6f 72 6d 61 74 29 3b 0a 20 20 73 71 6c 69 74  Format);.  sqlit
0d50: 65 33 5f 76 73 6e 70 72 69 6e 74 66 28 43 53 56  e3_vsnprintf(CSV
0d60: 5f 4d 58 45 52 52 2c 20 70 2d 3e 7a 45 72 72 2c  _MXERR, p->zErr,
0d70: 20 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20   zFormat, ap);. 
0d80: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a   va_end(ap);.}..
0d90: 2f 2a 20 4f 70 65 6e 20 74 68 65 20 66 69 6c 65  /* Open the file
0da0: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
0db0: 20 61 20 43 73 76 52 65 61 64 65 72 0a 2a 2a 20   a CsvReader.** 
0dc0: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
0dd0: 72 20 6f 66 20 65 72 72 6f 72 73 2e 0a 2a 2f 0a  r of errors..*/.
0de0: 73 74 61 74 69 63 20 69 6e 74 20 63 73 76 5f 72  static int csv_r
0df0: 65 61 64 65 72 5f 6f 70 65 6e 28 0a 20 20 43 73  eader_open(.  Cs
0e00: 76 52 65 61 64 65 72 20 2a 70 2c 20 20 20 20 20  vReader *p,     
0e10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
0e20: 20 72 65 61 64 65 72 20 74 6f 20 6f 70 65 6e 20   reader to open 
0e30: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
0e40: 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20  *zFilename,     
0e50: 20 2f 2a 20 52 65 61 64 20 66 72 6f 6d 20 74 68   /* Read from th
0e60: 69 73 20 66 69 6c 65 6e 61 6d 65 20 2a 2f 0a 20  is filename */. 
0e70: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61   const char *zDa
0e80: 74 61 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ta           /* 
0e90: 20 2e 2e 2e 20 6f 72 20 75 73 65 20 74 68 69 73   ... or use this
0ea0: 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 66   data */.){.  if
0eb0: 28 20 7a 46 69 6c 65 6e 61 6d 65 20 29 7b 0a 20  ( zFilename ){. 
0ec0: 20 20 20 70 2d 3e 7a 49 6e 20 3d 20 73 71 6c 69     p->zIn = sqli
0ed0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 43 53 56 5f  te3_malloc( CSV_
0ee0: 49 4e 42 55 46 53 5a 20 29 3b 0a 20 20 20 20 69  INBUFSZ );.    i
0ef0: 66 28 20 70 2d 3e 7a 49 6e 3d 3d 30 20 29 7b 0a  f( p->zIn==0 ){.
0f00: 20 20 20 20 20 20 63 73 76 5f 65 72 72 6d 73 67        csv_errmsg
0f10: 28 70 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f  (p, "out of memo
0f20: 72 79 22 29 3b 0a 20 20 20 20 20 20 72 65 74 75  ry");.      retu
0f30: 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20  rn 1;.    }.    
0f40: 70 2d 3e 69 6e 20 3d 20 66 6f 70 65 6e 28 7a 46  p->in = fopen(zF
0f50: 69 6c 65 6e 61 6d 65 2c 20 22 72 62 22 29 3b 0a  ilename, "rb");.
0f60: 20 20 20 20 69 66 28 20 70 2d 3e 69 6e 3d 3d 30      if( p->in==0
0f70: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
0f80: 33 5f 66 72 65 65 28 70 2d 3e 7a 49 6e 29 3b 0a  3_free(p->zIn);.
0f90: 20 20 20 20 20 20 63 73 76 5f 72 65 61 64 65 72        csv_reader
0fa0: 5f 72 65 73 65 74 28 70 29 3b 0a 20 20 20 20 20  _reset(p);.     
0fb0: 20 63 73 76 5f 65 72 72 6d 73 67 28 70 2c 20 22   csv_errmsg(p, "
0fc0: 63 61 6e 6e 6f 74 20 6f 70 65 6e 20 27 25 73 27  cannot open '%s'
0fd0: 20 66 6f 72 20 72 65 61 64 69 6e 67 22 2c 20 7a   for reading", z
0fe0: 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 20  Filename);.     
0ff0: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d   return 1;.    }
1000: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73  .  }else{.    as
1010: 73 65 72 74 28 20 70 2d 3e 69 6e 3d 3d 30 20 29  sert( p->in==0 )
1020: 3b 0a 20 20 20 20 70 2d 3e 7a 49 6e 20 3d 20 28  ;.    p->zIn = (
1030: 63 68 61 72 2a 29 7a 44 61 74 61 3b 0a 20 20 20  char*)zData;.   
1040: 20 70 2d 3e 6e 49 6e 20 3d 20 73 74 72 6c 65 6e   p->nIn = strlen
1050: 28 7a 44 61 74 61 29 3b 0a 20 20 7d 0a 20 20 72  (zData);.  }.  r
1060: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 54  eturn 0;.}../* T
1070: 68 65 20 69 6e 70 75 74 20 62 75 66 66 65 72 20  he input buffer 
1080: 68 61 73 20 6f 76 65 72 66 6c 6f 77 65 64 2e 20  has overflowed. 
1090: 20 52 65 66 69 6c 6c 20 74 68 65 20 69 6e 70 75   Refill the inpu
10a0: 74 20 62 75 66 66 65 72 2c 20 74 68 65 6e 0a 2a  t buffer, then.*
10b0: 2a 20 72 65 74 75 72 6e 20 74 68 65 20 6e 65 78  * return the nex
10c0: 74 20 63 68 61 72 61 63 74 65 72 0a 2a 2f 0a 73  t character.*/.s
10d0: 74 61 74 69 63 20 43 53 56 5f 4e 4f 49 4e 4c 49  tatic CSV_NOINLI
10e0: 4e 45 20 69 6e 74 20 63 73 76 5f 67 65 74 63 5f  NE int csv_getc_
10f0: 72 65 66 69 6c 6c 28 43 73 76 52 65 61 64 65 72  refill(CsvReader
1100: 20 2a 70 29 7b 0a 20 20 73 69 7a 65 5f 74 20 67   *p){.  size_t g
1110: 6f 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70  ot;..  assert( p
1120: 2d 3e 69 49 6e 3e 3d 70 2d 3e 6e 49 6e 20 29 3b  ->iIn>=p->nIn );
1130: 20 20 2f 2a 20 4f 6e 6c 79 20 63 61 6c 6c 65 64    /* Only called
1140: 20 6f 6e 20 61 6e 20 65 6d 70 74 79 20 69 6e 70   on an empty inp
1150: 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 61  ut buffer */.  a
1160: 73 73 65 72 74 28 20 70 2d 3e 69 6e 21 3d 30 20  ssert( p->in!=0 
1170: 29 3b 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 6c  );        /* Onl
1180: 79 20 63 61 6c 6c 65 64 20 69 66 20 72 65 61 64  y called if read
1190: 69 6e 67 20 66 72 6f 6d 61 20 66 69 6c 65 20 2a  ing froma file *
11a0: 2f 0a 0a 20 20 67 6f 74 20 3d 20 66 72 65 61 64  /..  got = fread
11b0: 28 70 2d 3e 7a 49 6e 2c 20 31 2c 20 43 53 56 5f  (p->zIn, 1, CSV_
11c0: 49 4e 42 55 46 53 5a 2c 20 70 2d 3e 69 6e 29 3b  INBUFSZ, p->in);
11d0: 0a 20 20 69 66 28 20 67 6f 74 3d 3d 30 20 29 20  .  if( got==0 ) 
11e0: 72 65 74 75 72 6e 20 45 4f 46 3b 0a 20 20 70 2d  return EOF;.  p-
11f0: 3e 6e 49 6e 20 3d 20 67 6f 74 3b 0a 20 20 70 2d  >nIn = got;.  p-
1200: 3e 69 49 6e 20 3d 20 31 3b 0a 20 20 72 65 74 75  >iIn = 1;.  retu
1210: 72 6e 20 70 2d 3e 7a 49 6e 5b 30 5d 3b 0a 7d 0a  rn p->zIn[0];.}.
1220: 0a 2f 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e  ./* Return the n
1230: 65 78 74 20 63 68 61 72 61 63 74 65 72 20 6f 66  ext character of
1240: 20 69 6e 70 75 74 2e 20 20 52 65 74 75 72 6e 20   input.  Return 
1250: 45 4f 46 20 61 74 20 65 6e 64 20 6f 66 20 69 6e  EOF at end of in
1260: 70 75 74 2e 20 2a 2f 0a 73 74 61 74 69 63 20 69  put. */.static i
1270: 6e 74 20 63 73 76 5f 67 65 74 63 28 43 73 76 52  nt csv_getc(CsvR
1280: 65 61 64 65 72 20 2a 70 29 7b 0a 20 20 69 66 28  eader *p){.  if(
1290: 20 70 2d 3e 69 49 6e 20 3e 3d 20 70 2d 3e 6e 49   p->iIn >= p->nI
12a0: 6e 20 29 7b 0a 20 20 20 20 69 66 28 20 70 2d 3e  n ){.    if( p->
12b0: 69 6e 21 3d 30 20 29 20 72 65 74 75 72 6e 20 63  in!=0 ) return c
12c0: 73 76 5f 67 65 74 63 5f 72 65 66 69 6c 6c 28 70  sv_getc_refill(p
12d0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 45 4f  );.    return EO
12e0: 46 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  F;.  }.  return 
12f0: 28 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a  ((unsigned char*
1300: 29 70 2d 3e 7a 49 6e 29 5b 70 2d 3e 69 49 6e 2b  )p->zIn)[p->iIn+
1310: 2b 5d 3b 0a 7d 0a 0a 2f 2a 20 49 6e 63 72 65 61  +];.}../* Increa
1320: 73 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20 70  se the size of p
1330: 2d 3e 7a 20 61 6e 64 20 61 70 70 65 6e 64 20 63  ->z and append c
1340: 68 61 72 61 63 74 65 72 20 63 20 74 6f 20 74 68  haracter c to th
1350: 65 20 65 6e 64 2e 20 0a 2a 2a 20 52 65 74 75 72  e end. .** Retur
1360: 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73 20 61  n 0 on success a
1370: 6e 64 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74  nd non-zero if t
1380: 68 65 72 65 20 69 73 20 61 6e 20 4f 4f 4d 20 65  here is an OOM e
1390: 72 72 6f 72 20 2a 2f 0a 73 74 61 74 69 63 20 43  rror */.static C
13a0: 53 56 5f 4e 4f 49 4e 4c 49 4e 45 20 69 6e 74 20  SV_NOINLINE int 
13b0: 63 73 76 5f 72 65 73 69 7a 65 5f 61 6e 64 5f 61  csv_resize_and_a
13c0: 70 70 65 6e 64 28 43 73 76 52 65 61 64 65 72 20  ppend(CsvReader 
13d0: 2a 70 2c 20 63 68 61 72 20 63 29 7b 0a 20 20 63  *p, char c){.  c
13e0: 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e 74  har *zNew;.  int
13f0: 20 6e 4e 65 77 20 3d 20 70 2d 3e 6e 41 6c 6c 6f   nNew = p->nAllo
1400: 63 2a 32 20 2b 20 31 30 30 3b 0a 20 20 7a 4e 65  c*2 + 100;.  zNe
1410: 77 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c  w = sqlite3_real
1420: 6c 6f 63 36 34 28 70 2d 3e 7a 2c 20 6e 4e 65 77  loc64(p->z, nNew
1430: 29 3b 0a 20 20 69 66 28 20 7a 4e 65 77 20 29 7b  );.  if( zNew ){
1440: 0a 20 20 20 20 70 2d 3e 7a 20 3d 20 7a 4e 65 77  .    p->z = zNew
1450: 3b 0a 20 20 20 20 70 2d 3e 6e 41 6c 6c 6f 63 20  ;.    p->nAlloc 
1460: 3d 20 6e 4e 65 77 3b 0a 20 20 20 20 70 2d 3e 7a  = nNew;.    p->z
1470: 5b 70 2d 3e 6e 2b 2b 5d 20 3d 20 63 3b 0a 20 20  [p->n++] = c;.  
1480: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 65    return 0;.  }e
1490: 6c 73 65 7b 0a 20 20 20 20 63 73 76 5f 65 72 72  lse{.    csv_err
14a0: 6d 73 67 28 70 2c 20 22 6f 75 74 20 6f 66 20 6d  msg(p, "out of m
14b0: 65 6d 6f 72 79 22 29 3b 0a 20 20 20 20 72 65 74  emory");.    ret
14c0: 75 72 6e 20 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  urn 1;.  }.}../*
14d0: 20 41 70 70 65 6e 64 20 61 20 73 69 6e 67 6c 65   Append a single
14e0: 20 63 68 61 72 61 63 74 65 72 20 74 6f 20 74 68   character to th
14f0: 65 20 43 73 76 52 65 61 64 65 72 2e 7a 5b 5d 20  e CsvReader.z[] 
1500: 61 72 72 61 79 2e 0a 2a 2a 20 52 65 74 75 72 6e  array..** Return
1510: 20 30 20 6f 6e 20 73 75 63 63 65 73 73 20 61 6e   0 on success an
1520: 64 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68  d non-zero if th
1530: 65 72 65 20 69 73 20 61 6e 20 4f 4f 4d 20 65 72  ere is an OOM er
1540: 72 6f 72 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ror */.static in
1550: 74 20 63 73 76 5f 61 70 70 65 6e 64 28 43 73 76  t csv_append(Csv
1560: 52 65 61 64 65 72 20 2a 70 2c 20 63 68 61 72 20  Reader *p, char 
1570: 63 29 7b 0a 20 20 69 66 28 20 70 2d 3e 6e 3e 3d  c){.  if( p->n>=
1580: 70 2d 3e 6e 41 6c 6c 6f 63 2d 31 20 29 20 72 65  p->nAlloc-1 ) re
1590: 74 75 72 6e 20 63 73 76 5f 72 65 73 69 7a 65 5f  turn csv_resize_
15a0: 61 6e 64 5f 61 70 70 65 6e 64 28 70 2c 20 63 29  and_append(p, c)
15b0: 3b 0a 20 20 70 2d 3e 7a 5b 70 2d 3e 6e 2b 2b 5d  ;.  p->z[p->n++]
15c0: 20 3d 20 63 3b 0a 20 20 72 65 74 75 72 6e 20 30   = c;.  return 0
15d0: 3b 0a 7d 0a 0a 2f 2a 20 52 65 61 64 20 61 20 73  ;.}../* Read a s
15e0: 69 6e 67 6c 65 20 66 69 65 6c 64 20 6f 66 20 43  ingle field of C
15f0: 53 56 20 74 65 78 74 2e 20 20 43 6f 6d 70 61 74  SV text.  Compat
1600: 69 62 6c 65 20 77 69 74 68 20 72 66 63 34 31 38  ible with rfc418
1610: 30 20 61 6e 64 20 65 78 74 65 6e 64 65 64 0a 2a  0 and extended.*
1620: 2a 20 77 69 74 68 20 74 68 65 20 6f 70 74 69 6f  * with the optio
1630: 6e 20 6f 66 20 68 61 76 69 6e 67 20 61 20 73 65  n of having a se
1640: 70 61 72 61 74 6f 72 20 6f 74 68 65 72 20 74 68  parator other th
1650: 61 6e 20 22 2c 22 2e 0a 2a 2a 0a 2a 2a 20 20 20  an ","..**.**   
1660: 2b 20 20 49 6e 70 75 74 20 63 6f 6d 65 73 20 66  +  Input comes f
1670: 72 6f 6d 20 70 2d 3e 69 6e 2e 0a 2a 2a 20 20 20  rom p->in..**   
1680: 2b 20 20 53 74 6f 72 65 20 72 65 73 75 6c 74 73  +  Store results
1690: 20 69 6e 20 70 2d 3e 7a 20 6f 66 20 6c 65 6e 67   in p->z of leng
16a0: 74 68 20 70 2d 3e 6e 2e 20 20 53 70 61 63 65 20  th p->n.  Space 
16b0: 74 6f 20 68 6f 6c 64 20 70 2d 3e 7a 20 63 6f 6d  to hold p->z com
16c0: 65 73 0a 2a 2a 20 20 20 20 20 20 66 72 6f 6d 20  es.**      from 
16d0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34  sqlite3_malloc64
16e0: 28 29 2e 0a 2a 2a 20 20 20 2b 20 20 4b 65 65 70  ()..**   +  Keep
16f0: 20 74 72 61 63 6b 20 6f 66 20 74 68 65 20 6c 69   track of the li
1700: 6e 65 20 6e 75 6d 62 65 72 20 69 6e 20 70 2d 3e  ne number in p->
1710: 6e 4c 69 6e 65 2e 0a 2a 2a 20 20 20 2b 20 20 53  nLine..**   +  S
1720: 74 6f 72 65 20 74 68 65 20 63 68 61 72 61 63 74  tore the charact
1730: 65 72 20 74 68 61 74 20 74 65 72 6d 69 6e 61 74  er that terminat
1740: 65 73 20 74 68 65 20 66 69 65 6c 64 20 69 6e 20  es the field in 
1750: 70 2d 3e 63 54 65 72 6d 2e 20 20 53 74 6f 72 65  p->cTerm.  Store
1760: 0a 2a 2a 20 20 20 20 20 20 45 4f 46 20 6f 6e 20  .**      EOF on 
1770: 65 6e 64 2d 6f 66 2d 66 69 6c 65 2e 0a 2a 2a 0a  end-of-file..**.
1780: 2a 2a 20 52 65 74 75 72 6e 20 30 20 61 74 20 45  ** Return 0 at E
1790: 4f 46 20 6f 72 20 6f 6e 20 4f 4f 4d 2e 20 20 4f  OF or on OOM.  O
17a0: 6e 20 45 4f 46 2c 20 74 68 65 20 70 2d 3e 63 54  n EOF, the p->cT
17b0: 65 72 6d 20 63 68 61 72 61 63 74 65 72 20 77 69  erm character wi
17c0: 6c 6c 20 68 61 76 65 0a 2a 2a 20 62 65 65 6e 20  ll have.** been 
17d0: 73 65 74 20 74 6f 20 45 4f 46 2e 0a 2a 2f 0a 73  set to EOF..*/.s
17e0: 74 61 74 69 63 20 63 68 61 72 20 2a 63 73 76 5f  tatic char *csv_
17f0: 72 65 61 64 5f 6f 6e 65 5f 66 69 65 6c 64 28 43  read_one_field(C
1800: 73 76 52 65 61 64 65 72 20 2a 70 29 7b 0a 20 20  svReader *p){.  
1810: 69 6e 74 20 63 3b 0a 20 20 70 2d 3e 6e 20 3d 20  int c;.  p->n = 
1820: 30 3b 0a 20 20 63 20 3d 20 63 73 76 5f 67 65 74  0;.  c = csv_get
1830: 63 28 70 29 3b 0a 20 20 69 66 28 20 63 3d 3d 45  c(p);.  if( c==E
1840: 4f 46 20 29 7b 0a 20 20 20 20 70 2d 3e 63 54 65  OF ){.    p->cTe
1850: 72 6d 20 3d 20 45 4f 46 3b 0a 20 20 20 20 72 65  rm = EOF;.    re
1860: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66  turn 0;.  }.  if
1870: 28 20 63 3d 3d 27 22 27 20 29 7b 0a 20 20 20 20  ( c=='"' ){.    
1880: 69 6e 74 20 70 63 2c 20 70 70 63 3b 0a 20 20 20  int pc, ppc;.   
1890: 20 69 6e 74 20 73 74 61 72 74 4c 69 6e 65 20 3d   int startLine =
18a0: 20 70 2d 3e 6e 4c 69 6e 65 3b 0a 20 20 20 20 70   p->nLine;.    p
18b0: 63 20 3d 20 70 70 63 20 3d 20 30 3b 0a 20 20 20  c = ppc = 0;.   
18c0: 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20   while( 1 ){.   
18d0: 20 20 20 63 20 3d 20 63 73 76 5f 67 65 74 63 28     c = csv_getc(
18e0: 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20 63 3c  p);.      if( c<
18f0: 3d 27 22 27 20 7c 7c 20 70 63 3d 3d 27 22 27 20  ='"' || pc=='"' 
1900: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63  ){.        if( c
1910: 3d 3d 27 5c 6e 27 20 29 20 70 2d 3e 6e 4c 69 6e  =='\n' ) p->nLin
1920: 65 2b 2b 3b 0a 20 20 20 20 20 20 20 20 69 66 28  e++;.        if(
1930: 20 63 3d 3d 27 22 27 20 29 7b 0a 20 20 20 20 20   c=='"' ){.     
1940: 20 20 20 20 20 69 66 28 20 70 63 3d 3d 27 22 27       if( pc=='"'
1950: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
1960: 70 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  pc = 0;.        
1970: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
1980: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
1990: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20    }.        if( 
19a0: 28 63 3d 3d 27 2c 27 20 26 26 20 70 63 3d 3d 27  (c==',' && pc=='
19b0: 22 27 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20  "').         || 
19c0: 28 63 3d 3d 27 5c 6e 27 20 26 26 20 70 63 3d 3d  (c=='\n' && pc==
19d0: 27 22 27 29 0a 20 20 20 20 20 20 20 20 20 7c 7c  '"').         ||
19e0: 20 28 63 3d 3d 27 5c 6e 27 20 26 26 20 70 63 3d   (c=='\n' && pc=
19f0: 3d 27 5c 72 27 20 26 26 20 70 70 63 3d 3d 27 22  ='\r' && ppc=='"
1a00: 27 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 28  ').         || (
1a10: 63 3d 3d 45 4f 46 20 26 26 20 70 63 3d 3d 27 22  c==EOF && pc=='"
1a20: 27 29 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20  ').        ){.  
1a30: 20 20 20 20 20 20 20 20 64 6f 7b 20 70 2d 3e 6e          do{ p->n
1a40: 2d 2d 3b 20 7d 77 68 69 6c 65 28 20 70 2d 3e 7a  --; }while( p->z
1a50: 5b 70 2d 3e 6e 5d 21 3d 27 22 27 20 29 3b 0a 20  [p->n]!='"' );. 
1a60: 20 20 20 20 20 20 20 20 20 70 2d 3e 63 54 65 72           p->cTer
1a70: 6d 20 3d 20 28 63 68 61 72 29 63 3b 0a 20 20 20  m = (char)c;.   
1a80: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
1a90: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1aa0: 69 66 28 20 70 63 3d 3d 27 22 27 20 26 26 20 63  if( pc=='"' && c
1ab0: 21 3d 27 5c 72 27 20 29 7b 0a 20 20 20 20 20 20  !='\r' ){.      
1ac0: 20 20 20 20 63 73 76 5f 65 72 72 6d 73 67 28 70      csv_errmsg(p
1ad0: 2c 20 22 6c 69 6e 65 20 25 64 3a 20 75 6e 65 73  , "line %d: unes
1ae0: 63 61 70 65 64 20 25 63 20 63 68 61 72 61 63 74  caped %c charact
1af0: 65 72 22 2c 20 70 2d 3e 6e 4c 69 6e 65 2c 20 27  er", p->nLine, '
1b00: 22 27 29 3b 0a 20 20 20 20 20 20 20 20 20 20 62  "');.          b
1b10: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
1b20: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 45          if( c==E
1b30: 4f 46 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OF ){.          
1b40: 63 73 76 5f 65 72 72 6d 73 67 28 70 2c 20 22 6c  csv_errmsg(p, "l
1b50: 69 6e 65 20 25 64 3a 20 75 6e 74 65 72 6d 69 6e  ine %d: untermin
1b60: 61 74 65 64 20 25 63 2d 71 75 6f 74 65 64 20 66  ated %c-quoted f
1b70: 69 65 6c 64 5c 6e 22 2c 0a 20 20 20 20 20 20 20  ield\n",.       
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 74                st
1b90: 61 72 74 4c 69 6e 65 2c 20 27 22 27 29 3b 0a 20  artLine, '"');. 
1ba0: 20 20 20 20 20 20 20 20 20 70 2d 3e 63 54 65 72           p->cTer
1bb0: 6d 20 3d 20 28 63 68 61 72 29 63 3b 0a 20 20 20  m = (char)c;.   
1bc0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
1bd0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
1be0: 20 20 20 20 20 20 69 66 28 20 63 73 76 5f 61 70        if( csv_ap
1bf0: 70 65 6e 64 28 70 2c 20 28 63 68 61 72 29 63 29  pend(p, (char)c)
1c00: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20   ) return 0;.   
1c10: 20 20 20 70 70 63 20 3d 20 70 63 3b 0a 20 20 20     ppc = pc;.   
1c20: 20 20 20 70 63 20 3d 20 63 3b 0a 20 20 20 20 7d     pc = c;.    }
1c30: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a  .  }else{.    /*
1c40: 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20   If this is the 
1c50: 66 69 72 73 74 20 66 69 65 6c 64 20 62 65 69 6e  first field bein
1c60: 67 20 70 61 72 73 65 64 20 61 6e 64 20 69 74 20  g parsed and it 
1c70: 62 65 67 69 6e 73 20 77 69 74 68 20 74 68 65 0a  begins with the.
1c80: 20 20 20 20 2a 2a 20 55 54 46 2d 38 20 42 4f 4d      ** UTF-8 BOM
1c90: 20 20 28 30 78 45 46 20 42 42 20 42 46 29 20 74    (0xEF BB BF) t
1ca0: 68 65 6e 20 73 6b 69 70 20 74 68 65 20 42 4f 4d  hen skip the BOM
1cb0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 28 63 26 30   */.    if( (c&0
1cc0: 78 66 66 29 3d 3d 30 78 65 66 20 26 26 20 70 2d  xff)==0xef && p-
1cd0: 3e 62 4e 6f 74 46 69 72 73 74 3d 3d 30 20 29 7b  >bNotFirst==0 ){
1ce0: 0a 20 20 20 20 20 20 63 73 76 5f 61 70 70 65 6e  .      csv_appen
1cf0: 64 28 70 2c 20 28 63 68 61 72 29 63 29 3b 0a 20  d(p, (char)c);. 
1d00: 20 20 20 20 20 63 20 3d 20 63 73 76 5f 67 65 74       c = csv_get
1d10: 63 28 70 29 3b 0a 20 20 20 20 20 20 69 66 28 20  c(p);.      if( 
1d20: 28 63 26 30 78 66 66 29 3d 3d 30 78 62 62 20 29  (c&0xff)==0xbb )
1d30: 7b 0a 20 20 20 20 20 20 20 20 63 73 76 5f 61 70  {.        csv_ap
1d40: 70 65 6e 64 28 70 2c 20 28 63 68 61 72 29 63 29  pend(p, (char)c)
1d50: 3b 0a 20 20 20 20 20 20 20 20 63 20 3d 20 63 73  ;.        c = cs
1d60: 76 5f 67 65 74 63 28 70 29 3b 0a 20 20 20 20 20  v_getc(p);.     
1d70: 20 20 20 69 66 28 20 28 63 26 30 78 66 66 29 3d     if( (c&0xff)=
1d80: 3d 30 78 62 66 20 29 7b 0a 20 20 20 20 20 20 20  =0xbf ){.       
1d90: 20 20 20 70 2d 3e 62 4e 6f 74 46 69 72 73 74 20     p->bNotFirst 
1da0: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 70  = 1;.          p
1db0: 2d 3e 6e 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ->n = 0;.       
1dc0: 20 20 20 72 65 74 75 72 6e 20 63 73 76 5f 72 65     return csv_re
1dd0: 61 64 5f 6f 6e 65 5f 66 69 65 6c 64 28 70 29 3b  ad_one_field(p);
1de0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
1df0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 77 68 69   }.    }.    whi
1e00: 6c 65 28 20 63 3e 27 2c 27 20 7c 7c 20 28 63 21  le( c>',' || (c!
1e10: 3d 45 4f 46 20 26 26 20 63 21 3d 27 2c 27 20 26  =EOF && c!=',' &
1e20: 26 20 63 21 3d 27 5c 6e 27 29 20 29 7b 0a 20 20  & c!='\n') ){.  
1e30: 20 20 20 20 69 66 28 20 63 73 76 5f 61 70 70 65      if( csv_appe
1e40: 6e 64 28 70 2c 20 28 63 68 61 72 29 63 29 20 29  nd(p, (char)c) )
1e50: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20   return 0;.     
1e60: 20 63 20 3d 20 63 73 76 5f 67 65 74 63 28 70 29   c = csv_getc(p)
1e70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
1e80: 63 3d 3d 27 5c 6e 27 20 29 7b 0a 20 20 20 20 20  c=='\n' ){.     
1e90: 20 70 2d 3e 6e 4c 69 6e 65 2b 2b 3b 0a 20 20 20   p->nLine++;.   
1ea0: 20 20 20 69 66 28 20 70 2d 3e 6e 3e 30 20 26 26     if( p->n>0 &&
1eb0: 20 70 2d 3e 7a 5b 70 2d 3e 6e 2d 31 5d 3d 3d 27   p->z[p->n-1]=='
1ec0: 5c 72 27 20 29 20 70 2d 3e 6e 2d 2d 3b 0a 20 20  \r' ) p->n--;.  
1ed0: 20 20 7d 0a 20 20 20 20 70 2d 3e 63 54 65 72 6d    }.    p->cTerm
1ee0: 20 3d 20 28 63 68 61 72 29 63 3b 0a 20 20 7d 0a   = (char)c;.  }.
1ef0: 20 20 69 66 28 20 70 2d 3e 7a 20 29 20 70 2d 3e    if( p->z ) p->
1f00: 7a 5b 70 2d 3e 6e 5d 20 3d 20 30 3b 0a 20 20 70  z[p->n] = 0;.  p
1f10: 2d 3e 62 4e 6f 74 46 69 72 73 74 20 3d 20 31 3b  ->bNotFirst = 1;
1f20: 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 7a 3b 0a  .  return p->z;.
1f30: 7d 0a 0a 0a 2f 2a 20 46 6f 72 77 61 72 64 20 72  }.../* Forward r
1f40: 65 66 65 72 65 6e 63 65 73 20 74 6f 20 74 68 65  eferences to the
1f50: 20 76 61 72 69 6f 75 73 20 76 69 72 74 75 61 6c   various virtual
1f60: 20 74 61 62 6c 65 20 6d 65 74 68 6f 64 73 20 69   table methods i
1f70: 6d 70 6c 65 6d 65 6e 74 65 64 0a 2a 2a 20 69 6e  mplemented.** in
1f80: 20 74 68 69 73 20 66 69 6c 65 2e 20 2a 2f 0a 73   this file. */.s
1f90: 74 61 74 69 63 20 69 6e 74 20 63 73 76 74 61 62  tatic int csvtab
1fa0: 43 72 65 61 74 65 28 73 71 6c 69 74 65 33 2a 2c  Create(sqlite3*,
1fb0: 20 76 6f 69 64 2a 2c 20 69 6e 74 2c 20 63 6f 6e   void*, int, con
1fc0: 73 74 20 63 68 61 72 2a 63 6f 6e 73 74 2a 2c 20  st char*const*, 
1fd0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
1fe0: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
1ff0: 74 65 33 5f 76 74 61 62 2a 2a 2c 63 68 61 72 2a  te3_vtab**,char*
2000: 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 63  *);.static int c
2010: 73 76 74 61 62 43 6f 6e 6e 65 63 74 28 73 71 6c  svtabConnect(sql
2020: 69 74 65 33 2a 2c 20 76 6f 69 64 2a 2c 20 69 6e  ite3*, void*, in
2030: 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 2a 63 6f  t, const char*co
2040: 6e 73 74 2a 2c 20 0a 20 20 20 20 20 20 20 20 20  nst*, .         
2050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2060: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 2a 2a    sqlite3_vtab**
2070: 2c 63 68 61 72 2a 2a 29 3b 0a 73 74 61 74 69 63  ,char**);.static
2080: 20 69 6e 74 20 63 73 76 74 61 62 42 65 73 74 49   int csvtabBestI
2090: 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61  ndex(sqlite3_vta
20a0: 62 2a 2c 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  b*,sqlite3_index
20b0: 5f 69 6e 66 6f 2a 29 3b 0a 73 74 61 74 69 63 20  _info*);.static 
20c0: 69 6e 74 20 63 73 76 74 61 62 44 69 73 63 6f 6e  int csvtabDiscon
20d0: 6e 65 63 74 28 73 71 6c 69 74 65 33 5f 76 74 61  nect(sqlite3_vta
20e0: 62 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  b*);.static int 
20f0: 63 73 76 74 61 62 4f 70 65 6e 28 73 71 6c 69 74  csvtabOpen(sqlit
2100: 65 33 5f 76 74 61 62 2a 2c 20 73 71 6c 69 74 65  e3_vtab*, sqlite
2110: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 2a 29  3_vtab_cursor**)
2120: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 63 73 76  ;.static int csv
2130: 74 61 62 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  tabClose(sqlite3
2140: 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29 3b 0a  _vtab_cursor*);.
2150: 73 74 61 74 69 63 20 69 6e 74 20 63 73 76 74 61  static int csvta
2160: 62 46 69 6c 74 65 72 28 73 71 6c 69 74 65 33 5f  bFilter(sqlite3_
2170: 76 74 61 62 5f 63 75 72 73 6f 72 2a 2c 20 69 6e  vtab_cursor*, in
2180: 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20  t idxNum, const 
2190: 63 68 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 20  char *idxStr,.  
21a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21b0: 20 20 20 20 20 20 20 20 69 6e 74 20 61 72 67 63          int argc
21c0: 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20  , sqlite3_value 
21d0: 2a 2a 61 72 67 76 29 3b 0a 73 74 61 74 69 63 20  **argv);.static 
21e0: 69 6e 74 20 63 73 76 74 61 62 4e 65 78 74 28 73  int csvtabNext(s
21f0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
2200: 6f 72 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  or*);.static int
2210: 20 63 73 76 74 61 62 45 6f 66 28 73 71 6c 69 74   csvtabEof(sqlit
2220: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 29  e3_vtab_cursor*)
2230: 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 63 73 76  ;.static int csv
2240: 74 61 62 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65  tabColumn(sqlite
2250: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 2a 2c 73  3_vtab_cursor*,s
2260: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c  qlite3_context*,
2270: 69 6e 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  int);.static int
2280: 20 63 73 76 74 61 62 52 6f 77 69 64 28 73 71 6c   csvtabRowid(sql
2290: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
22a0: 2a 2c 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 2a  *,sqlite3_int64*
22b0: 29 3b 0a 0a 2f 2a 20 41 6e 20 69 6e 73 74 61 6e  );../* An instan
22c0: 63 65 20 6f 66 20 74 68 65 20 43 53 56 20 76 69  ce of the CSV vi
22d0: 72 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 74  rtual table */.t
22e0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 43 73  ypedef struct Cs
22f0: 76 54 61 62 6c 65 20 7b 0a 20 20 73 71 6c 69 74  vTable {.  sqlit
2300: 65 33 5f 76 74 61 62 20 62 61 73 65 3b 20 20 20  e3_vtab base;   
2310: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 61             /* Ba
2320: 73 65 20 63 6c 61 73 73 2e 20 20 4d 75 73 74 20  se class.  Must 
2330: 62 65 20 66 69 72 73 74 20 2a 2f 0a 20 20 63 68  be first */.  ch
2340: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20  ar *zFilename;  
2350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2360: 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 43 53 56   Name of the CSV
2370: 20 66 69 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20   file */.  char 
2380: 2a 7a 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *zData;         
2390: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 61             /* Ra
23a0: 77 20 43 53 56 20 64 61 74 61 20 69 6e 20 6c 69  w CSV data in li
23b0: 65 75 20 6f 66 20 7a 46 69 6c 65 6e 61 6d 65 20  eu of zFilename 
23c0: 2a 2f 0a 20 20 6c 6f 6e 67 20 69 53 74 61 72 74  */.  long iStart
23d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
23e0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74       /* Offset t
23f0: 6f 20 73 74 61 72 74 20 6f 66 20 64 61 74 61 20  o start of data 
2400: 69 6e 20 7a 46 69 6c 65 6e 61 6d 65 20 2a 2f 0a  in zFilename */.
2410: 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20    int nCol;     
2420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2430: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
2440: 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 43 53  olumns in the CS
2450: 56 20 66 69 6c 65 20 2a 2f 0a 20 20 75 6e 73 69  V file */.  unsi
2460: 67 6e 65 64 20 69 6e 74 20 74 73 74 46 6c 61 67  gned int tstFlag
2470: 73 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42  s;          /* B
2480: 69 74 20 76 61 6c 75 65 73 20 75 73 65 64 20 66  it values used f
2490: 6f 72 20 74 65 73 74 69 6e 67 20 2a 2f 0a 7d 20  or testing */.} 
24a0: 43 73 76 54 61 62 6c 65 3b 0a 0a 2f 2a 20 41 6c  CsvTable;../* Al
24b0: 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 66 6f 72  lowed values for
24c0: 20 74 73 74 46 6c 61 67 73 20 2a 2f 0a 23 64 65   tstFlags */.#de
24d0: 66 69 6e 65 20 43 53 56 54 45 53 54 5f 46 49 44  fine CSVTEST_FID
24e0: 58 20 20 30 78 30 30 30 31 20 20 20 20 20 20 2f  X  0x0001      /
24f0: 2a 20 50 72 65 74 65 6e 64 20 74 68 61 74 20 63  * Pretend that c
2500: 6f 6e 73 74 72 61 69 6e 65 64 20 73 65 61 72 63  onstrained searc
2510: 68 73 20 63 6f 73 74 20 6c 65 73 73 2a 2f 0a 0a  hs cost less*/..
2520: 2f 2a 20 41 20 63 75 72 73 6f 72 20 66 6f 72 20  /* A cursor for 
2530: 74 68 65 20 43 53 56 20 76 69 72 74 75 61 6c 20  the CSV virtual 
2540: 74 61 62 6c 65 20 2a 2f 0a 74 79 70 65 64 65 66  table */.typedef
2550: 20 73 74 72 75 63 74 20 43 73 76 43 75 72 73 6f   struct CsvCurso
2560: 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  r {.  sqlite3_vt
2570: 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 20  ab_cursor base; 
2580: 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c        /* Base cl
2590: 61 73 73 2e 20 20 4d 75 73 74 20 62 65 20 66 69  ass.  Must be fi
25a0: 72 73 74 20 2a 2f 0a 20 20 43 73 76 52 65 61 64  rst */.  CsvRead
25b0: 65 72 20 72 64 72 3b 20 20 20 20 20 20 20 20 20  er rdr;         
25c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
25d0: 43 73 76 52 65 61 64 65 72 20 6f 62 6a 65 63 74  CsvReader object
25e0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 7a 56   */.  char **azV
25f0: 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  al;             
2600: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f        /* Value o
2610: 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f  f the current ro
2620: 77 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 4c 65 6e  w */.  int *aLen
2630: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
2640: 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68         /* Length
2650: 20 6f 66 20 65 61 63 68 20 65 6e 74 72 79 20 2a   of each entry *
2660: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  /.  sqlite3_int6
2670: 34 20 69 52 6f 77 69 64 3b 20 20 20 20 20 20 20  4 iRowid;       
2680: 20 20 20 20 2f 2a 20 54 68 65 20 63 75 72 72 65      /* The curre
2690: 6e 74 20 72 6f 77 69 64 2e 20 20 4e 65 67 61 74  nt rowid.  Negat
26a0: 69 76 65 20 66 6f 72 20 45 4f 46 20 2a 2f 0a 7d  ive for EOF */.}
26b0: 20 43 73 76 43 75 72 73 6f 72 3b 0a 0a 2f 2a 20   CsvCursor;../* 
26c0: 54 72 61 6e 73 66 65 72 20 65 72 72 6f 72 20 6d  Transfer error m
26d0: 65 73 73 61 67 65 20 74 65 78 74 20 66 72 6f 6d  essage text from
26e0: 20 61 20 72 65 61 64 65 72 20 69 6e 74 6f 20 61   a reader into a
26f0: 20 43 73 76 54 61 62 6c 65 20 2a 2f 0a 73 74 61   CsvTable */.sta
2700: 74 69 63 20 76 6f 69 64 20 63 73 76 5f 78 66 65  tic void csv_xfe
2710: 72 5f 65 72 72 6f 72 28 43 73 76 54 61 62 6c 65  r_error(CsvTable
2720: 20 2a 70 54 61 62 2c 20 43 73 76 52 65 61 64 65   *pTab, CsvReade
2730: 72 20 2a 70 52 64 72 29 7b 0a 20 20 73 71 6c 69  r *pRdr){.  sqli
2740: 74 65 33 5f 66 72 65 65 28 70 54 61 62 2d 3e 62  te3_free(pTab->b
2750: 61 73 65 2e 7a 45 72 72 4d 73 67 29 3b 0a 20 20  ase.zErrMsg);.  
2760: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
2770: 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  sg = sqlite3_mpr
2780: 69 6e 74 66 28 22 25 73 22 2c 20 70 52 64 72 2d  intf("%s", pRdr-
2790: 3e 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  >zErr);.}../*.**
27a0: 20 54 68 69 73 20 6d 65 74 68 6f 64 20 69 73 20   This method is 
27b0: 74 68 65 20 64 65 73 74 72 75 63 74 6f 72 20 66  the destructor f
27c0: 6f 20 61 20 43 73 76 54 61 62 6c 65 20 6f 62 6a  o a CsvTable obj
27d0: 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ect..*/.static i
27e0: 6e 74 20 63 73 76 74 61 62 44 69 73 63 6f 6e 6e  nt csvtabDisconn
27f0: 65 63 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ect(sqlite3_vtab
2800: 20 2a 70 56 74 61 62 29 7b 0a 20 20 43 73 76 54   *pVtab){.  CsvT
2810: 61 62 6c 65 20 2a 70 20 3d 20 28 43 73 76 54 61  able *p = (CsvTa
2820: 62 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 73 71  ble*)pVtab;.  sq
2830: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 46  lite3_free(p->zF
2840: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 73 71 6c 69  ilename);.  sqli
2850: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 44 61 74  te3_free(p->zDat
2860: 61 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  a);.  sqlite3_fr
2870: 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  ee(p);.  return 
2880: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
2890: 20 53 6b 69 70 20 6c 65 61 64 69 6e 67 20 77 68   Skip leading wh
28a0: 69 74 65 73 70 61 63 65 2e 20 20 52 65 74 75 72  itespace.  Retur
28b0: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  n a pointer to t
28c0: 68 65 20 66 69 72 73 74 20 6e 6f 6e 2d 77 68 69  he first non-whi
28d0: 74 65 73 70 61 63 65 0a 2a 2a 20 63 68 61 72 61  tespace.** chara
28e0: 63 74 65 72 2c 20 6f 72 20 74 6f 20 74 68 65 20  cter, or to the 
28f0: 7a 65 72 6f 20 74 65 72 6d 69 6e 61 74 6f 72 20  zero terminator 
2900: 69 66 20 74 68 65 20 73 74 72 69 6e 67 20 68 61  if the string ha
2910: 73 20 6f 6e 6c 79 20 77 68 69 74 65 73 70 61 63  s only whitespac
2920: 65 20 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73  e */.static cons
2930: 74 20 63 68 61 72 20 2a 63 73 76 5f 73 6b 69 70  t char *csv_skip
2940: 5f 77 68 69 74 65 73 70 61 63 65 28 63 6f 6e 73  _whitespace(cons
2950: 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20 77 68  t char *z){.  wh
2960: 69 6c 65 28 20 69 73 73 70 61 63 65 28 28 75 6e  ile( isspace((un
2970: 73 69 67 6e 65 64 20 63 68 61 72 29 7a 5b 30 5d  signed char)z[0]
2980: 29 20 29 20 7a 2b 2b 3b 0a 20 20 72 65 74 75 72  ) ) z++;.  retur
2990: 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 20 52 65 6d 6f 76  n z;.}../* Remov
29a0: 65 20 74 72 61 69 6c 69 6e 67 20 77 68 69 74 65  e trailing white
29b0: 73 70 61 63 65 20 66 72 6f 6d 20 74 68 65 20 65  space from the e
29c0: 6e 64 20 6f 66 20 73 74 72 69 6e 67 20 7a 5b 5d  nd of string z[]
29d0: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
29e0: 63 73 76 5f 74 72 69 6d 5f 77 68 69 74 65 73 70  csv_trim_whitesp
29f0: 61 63 65 28 63 68 61 72 20 2a 7a 29 7b 0a 20 20  ace(char *z){.  
2a00: 73 69 7a 65 5f 74 20 6e 20 3d 20 73 74 72 6c 65  size_t n = strle
2a10: 6e 28 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 6e  n(z);.  while( n
2a20: 3e 30 20 26 26 20 69 73 73 70 61 63 65 28 28 75  >0 && isspace((u
2a30: 6e 73 69 67 6e 65 64 20 63 68 61 72 29 7a 5b 6e  nsigned char)z[n
2a40: 5d 29 20 29 20 6e 2d 2d 3b 0a 20 20 7a 5b 6e 5d  ]) ) n--;.  z[n]
2a50: 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20 44 65 71 75   = 0;.}../* Dequ
2a60: 6f 74 65 20 74 68 65 20 73 74 72 69 6e 67 20 2a  ote the string *
2a70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 73  /.static void cs
2a80: 76 5f 64 65 71 75 6f 74 65 28 63 68 61 72 20 2a  v_dequote(char *
2a90: 7a 29 7b 0a 20 20 69 6e 74 20 6a 3b 0a 20 20 63  z){.  int j;.  c
2aa0: 68 61 72 20 63 51 75 6f 74 65 20 3d 20 7a 5b 30  har cQuote = z[0
2ab0: 5d 3b 0a 20 20 73 69 7a 65 5f 74 20 69 2c 20 6e  ];.  size_t i, n
2ac0: 3b 0a 0a 20 20 69 66 28 20 63 51 75 6f 74 65 21  ;..  if( cQuote!
2ad0: 3d 27 5c 27 27 20 26 26 20 63 51 75 6f 74 65 21  ='\'' && cQuote!
2ae0: 3d 27 22 27 20 29 20 72 65 74 75 72 6e 3b 0a 20  ='"' ) return;. 
2af0: 20 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 29 3b 0a   n = strlen(z);.
2b00: 20 20 69 66 28 20 6e 3c 32 20 7c 7c 20 7a 5b 6e    if( n<2 || z[n
2b10: 2d 31 5d 21 3d 7a 5b 30 5d 20 29 20 72 65 74 75  -1]!=z[0] ) retu
2b20: 72 6e 3b 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a  rn;.  for(i=1, j
2b30: 3d 30 3b 20 69 3c 6e 2d 31 3b 20 69 2b 2b 29 7b  =0; i<n-1; i++){
2b40: 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 63  .    if( z[i]==c
2b50: 51 75 6f 74 65 20 26 26 20 7a 5b 69 2b 31 5d 3d  Quote && z[i+1]=
2b60: 3d 63 51 75 6f 74 65 20 29 20 69 2b 2b 3b 0a 20  =cQuote ) i++;. 
2b70: 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d     z[j++] = z[i]
2b80: 3b 0a 20 20 7d 0a 20 20 7a 5b 6a 5d 20 3d 20 30  ;.  }.  z[j] = 0
2b90: 3b 0a 7d 0a 0a 2f 2a 20 43 68 65 63 6b 20 74 6f  ;.}../* Check to
2ba0: 20 73 65 65 20 69 66 20 74 68 65 20 73 74 72 69   see if the stri
2bb0: 6e 67 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72  ng is of the for
2bc0: 6d 3a 20 20 22 54 41 47 20 3d 20 56 41 4c 55 45  m:  "TAG = VALUE
2bd0: 22 20 77 69 74 68 20 6f 70 74 69 6f 6e 61 6c 0a  " with optional.
2be0: 2a 2a 20 77 68 69 74 65 73 70 61 63 65 20 62 65  ** whitespace be
2bf0: 66 6f 72 65 20 61 6e 64 20 61 72 6f 75 6e 64 20  fore and around 
2c00: 74 6f 6b 65 6e 73 2e 20 20 49 66 20 69 74 20 69  tokens.  If it i
2c10: 73 2c 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e  s, return a poin
2c20: 74 65 72 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69  ter to the.** fi
2c30: 72 73 74 20 63 68 61 72 61 63 74 65 72 20 6f 66  rst character of
2c40: 20 56 41 4c 55 45 2e 20 20 49 66 20 69 74 20 69   VALUE.  If it i
2c50: 73 20 6e 6f 74 2c 20 72 65 74 75 72 6e 20 4e 55  s not, return NU
2c60: 4c 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f  LL..*/.static co
2c70: 6e 73 74 20 63 68 61 72 20 2a 63 73 76 5f 70 61  nst char *csv_pa
2c80: 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 68  rameter(const ch
2c90: 61 72 20 2a 7a 54 61 67 2c 20 69 6e 74 20 6e 54  ar *zTag, int nT
2ca0: 61 67 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ag, const char *
2cb0: 7a 29 7b 0a 20 20 7a 20 3d 20 63 73 76 5f 73 6b  z){.  z = csv_sk
2cc0: 69 70 5f 77 68 69 74 65 73 70 61 63 65 28 7a 29  ip_whitespace(z)
2cd0: 3b 0a 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28  ;.  if( strncmp(
2ce0: 7a 54 61 67 2c 20 7a 2c 20 6e 54 61 67 29 21 3d  zTag, z, nTag)!=
2cf0: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  0 ) return 0;.  
2d00: 7a 20 3d 20 63 73 76 5f 73 6b 69 70 5f 77 68 69  z = csv_skip_whi
2d10: 74 65 73 70 61 63 65 28 7a 2b 6e 54 61 67 29 3b  tespace(z+nTag);
2d20: 0a 20 20 69 66 28 20 7a 5b 30 5d 21 3d 27 3d 27  .  if( z[0]!='='
2d30: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 72   ) return 0;.  r
2d40: 65 74 75 72 6e 20 63 73 76 5f 73 6b 69 70 5f 77  eturn csv_skip_w
2d50: 68 69 74 65 73 70 61 63 65 28 7a 2b 31 29 3b 0a  hitespace(z+1);.
2d60: 7d 0a 0a 2f 2a 20 44 65 63 6f 64 65 20 61 20 70  }../* Decode a p
2d70: 61 72 61 6d 65 74 65 72 20 74 68 61 74 20 72 65  arameter that re
2d80: 71 75 69 72 65 73 20 61 20 64 65 71 75 6f 74 65  quires a dequote
2d90: 64 20 73 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  d string..**.** 
2da0: 52 65 74 75 72 6e 20 31 20 69 66 20 74 68 65 20  Return 1 if the 
2db0: 70 61 72 61 6d 65 74 65 72 20 69 73 20 73 65 65  parameter is see
2dc0: 6e 2c 20 6f 72 20 30 20 69 66 20 6e 6f 74 2e 20  n, or 0 if not. 
2dd0: 20 31 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a   1 is returned.*
2de0: 2a 20 65 76 65 6e 20 69 66 20 74 68 65 72 65 20  * even if there 
2df0: 69 73 20 61 6e 20 65 72 72 6f 72 2e 20 20 49 66  is an error.  If
2e00: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
2e10: 2c 20 74 68 65 6e 20 61 6e 20 65 72 72 6f 72 20  , then an error 
2e20: 6d 65 73 73 61 67 65 0a 2a 2a 20 69 73 20 6c 65  message.** is le
2e30: 66 74 20 69 6e 20 70 2d 3e 7a 45 72 72 2e 20 20  ft in p->zErr.  
2e40: 49 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  If there are no 
2e50: 65 72 72 6f 72 73 2c 20 70 2d 3e 7a 45 72 72 5b  errors, p->zErr[
2e60: 30 5d 3d 3d 30 2e 0a 2a 2f 0a 73 74 61 74 69 63  0]==0..*/.static
2e70: 20 69 6e 74 20 63 73 76 5f 73 74 72 69 6e 67 5f   int csv_string_
2e80: 70 61 72 61 6d 65 74 65 72 28 0a 20 20 43 73 76  parameter(.  Csv
2e90: 52 65 61 64 65 72 20 2a 70 2c 20 20 20 20 20 20  Reader *p,      
2ea0: 20 20 20 20 20 20 2f 2a 20 4c 65 61 76 65 20 74        /* Leave t
2eb0: 68 65 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  he error message
2ec0: 20 68 65 72 65 2c 20 69 66 20 74 68 65 72 65 20   here, if there 
2ed0: 69 73 20 6f 6e 65 20 2a 2f 0a 20 20 63 6f 6e 73  is one */.  cons
2ee0: 74 20 63 68 61 72 20 2a 7a 50 61 72 61 6d 2c 20  t char *zParam, 
2ef0: 20 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65       /* Paramete
2f00: 72 20 77 65 20 61 72 65 20 63 68 65 63 6b 69 6e  r we are checkin
2f10: 67 20 66 6f 72 20 2a 2f 0a 20 20 63 6f 6e 73 74  g for */.  const
2f20: 20 63 68 61 72 20 2a 7a 41 72 67 2c 20 20 20 20   char *zArg,    
2f30: 20 20 20 20 2f 2a 20 52 61 77 20 74 65 78 74 20      /* Raw text 
2f40: 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  of the virtual t
2f50: 61 62 6c 65 20 61 72 67 6d 65 6e 74 20 2a 2f 0a  able argment */.
2f60: 20 20 63 68 61 72 20 2a 2a 70 7a 56 61 6c 20 20    char **pzVal  
2f70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72             /* Wr
2f80: 69 74 65 20 74 68 65 20 64 65 71 75 6f 74 65 64  ite the dequoted
2f90: 20 73 74 72 69 6e 67 20 76 61 6c 75 65 20 68 65   string value he
2fa0: 72 65 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74  re */.){.  const
2fb0: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20   char *zValue;. 
2fc0: 20 7a 56 61 6c 75 65 20 3d 20 63 73 76 5f 70 61   zValue = csv_pa
2fd0: 72 61 6d 65 74 65 72 28 7a 50 61 72 61 6d 2c 28  rameter(zParam,(
2fe0: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 50 61 72 61  int)strlen(zPara
2ff0: 6d 29 2c 7a 41 72 67 29 3b 0a 20 20 69 66 28 20  m),zArg);.  if( 
3000: 7a 56 61 6c 75 65 3d 3d 30 20 29 20 72 65 74 75  zValue==0 ) retu
3010: 72 6e 20 30 3b 0a 20 20 70 2d 3e 7a 45 72 72 5b  rn 0;.  p->zErr[
3020: 30 5d 20 3d 20 30 3b 0a 20 20 69 66 28 20 2a 70  0] = 0;.  if( *p
3030: 7a 56 61 6c 20 29 7b 0a 20 20 20 20 63 73 76 5f  zVal ){.    csv_
3040: 65 72 72 6d 73 67 28 70 2c 20 22 6d 6f 72 65 20  errmsg(p, "more 
3050: 74 68 61 6e 20 6f 6e 65 20 27 25 73 27 20 70 61  than one '%s' pa
3060: 72 61 6d 65 74 65 72 22 2c 20 7a 50 61 72 61 6d  rameter", zParam
3070: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  );.    return 1;
3080: 0a 20 20 7d 0a 20 20 2a 70 7a 56 61 6c 20 3d 20  .  }.  *pzVal = 
3090: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
30a0: 22 25 73 22 2c 20 7a 56 61 6c 75 65 29 3b 0a 20  "%s", zValue);. 
30b0: 20 69 66 28 20 2a 70 7a 56 61 6c 3d 3d 30 20 29   if( *pzVal==0 )
30c0: 7b 0a 20 20 20 20 63 73 76 5f 65 72 72 6d 73 67  {.    csv_errmsg
30d0: 28 70 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f  (p, "out of memo
30e0: 72 79 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ry");.    return
30f0: 20 31 3b 0a 20 20 7d 0a 20 20 63 73 76 5f 74 72   1;.  }.  csv_tr
3100: 69 6d 5f 77 68 69 74 65 73 70 61 63 65 28 2a 70  im_whitespace(*p
3110: 7a 56 61 6c 29 3b 0a 20 20 63 73 76 5f 64 65 71  zVal);.  csv_deq
3120: 75 6f 74 65 28 2a 70 7a 56 61 6c 29 3b 0a 20 20  uote(*pzVal);.  
3130: 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 0a 2f 2a  return 1;.}.../*
3140: 20 52 65 74 75 72 6e 20 30 20 69 66 20 74 68 65   Return 0 if the
3150: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 66 61 6c   argument is fal
3160: 73 65 20 61 6e 64 20 31 20 69 66 20 69 74 20 69  se and 1 if it i
3170: 73 20 74 72 75 65 2e 20 20 52 65 74 75 72 6e 20  s true.  Return 
3180: 2d 31 20 69 66 0a 2a 2a 20 77 65 20 63 61 6e 6e  -1 if.** we cann
3190: 6f 74 20 72 65 61 6c 6c 79 20 74 65 6c 6c 2e 0a  ot really tell..
31a0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 73  */.static int cs
31b0: 76 5f 62 6f 6f 6c 65 61 6e 28 63 6f 6e 73 74 20  v_boolean(const 
31c0: 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 66 28 20  char *z){.  if( 
31d0: 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d 70 28  sqlite3_stricmp(
31e0: 22 79 65 73 22 2c 7a 29 3d 3d 30 0a 20 20 20 7c  "yes",z)==0.   |
31f0: 7c 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63 6d  | sqlite3_stricm
3200: 70 28 22 6f 6e 22 2c 7a 29 3d 3d 30 0a 20 20 20  p("on",z)==0.   
3210: 7c 7c 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63  || sqlite3_stric
3220: 6d 70 28 22 74 72 75 65 22 2c 7a 29 3d 3d 30 0a  mp("true",z)==0.
3230: 20 20 20 7c 7c 20 28 7a 5b 30 5d 3d 3d 27 31 27     || (z[0]=='1'
3240: 20 26 26 20 7a 5b 31 5d 3d 3d 30 29 0a 20 20 29   && z[1]==0).  )
3250: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a  {.    return 1;.
3260: 20 20 7d 0a 20 20 69 66 28 20 73 71 6c 69 74 65    }.  if( sqlite
3270: 33 5f 73 74 72 69 63 6d 70 28 22 6e 6f 22 2c 7a  3_stricmp("no",z
3280: 29 3d 3d 30 0a 20 20 20 7c 7c 20 73 71 6c 69 74  )==0.   || sqlit
3290: 65 33 5f 73 74 72 69 63 6d 70 28 22 6f 66 66 22  e3_stricmp("off"
32a0: 2c 7a 29 3d 3d 30 0a 20 20 20 7c 7c 20 73 71 6c  ,z)==0.   || sql
32b0: 69 74 65 33 5f 73 74 72 69 63 6d 70 28 22 66 61  ite3_stricmp("fa
32c0: 6c 73 65 22 2c 7a 29 3d 3d 30 0a 20 20 20 7c 7c  lse",z)==0.   ||
32d0: 20 28 7a 5b 30 5d 3d 3d 27 30 27 20 26 26 20 7a   (z[0]=='0' && z
32e0: 5b 31 5d 3d 3d 30 29 0a 20 20 29 7b 0a 20 20 20  [1]==0).  ){.   
32f0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20   return 0;.  }. 
3300: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 0a   return -1;.}...
3310: 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 73  /*.** Parameters
3320: 3a 0a 2a 2a 20 20 20 20 66 69 6c 65 6e 61 6d 65  :.**    filename
3330: 3d 46 49 4c 45 4e 41 4d 45 20 20 20 20 20 20 20  =FILENAME       
3340: 20 20 20 4e 61 6d 65 20 6f 66 20 66 69 6c 65 20     Name of file 
3350: 63 6f 6e 74 61 69 6e 69 6e 67 20 43 53 56 20 63  containing CSV c
3360: 6f 6e 74 65 6e 74 0a 2a 2a 20 20 20 20 64 61 74  ontent.**    dat
3370: 61 3d 54 45 58 54 20 20 20 20 20 20 20 20 20 20  a=TEXT          
3380: 20 20 20 20 20 20 20 20 44 69 72 65 63 74 20 43          Direct C
3390: 53 56 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2a 20 20  SV content..**  
33a0: 20 20 73 63 68 65 6d 61 3d 53 43 48 45 4d 41 20    schema=SCHEMA 
33b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 41 6c 74               Alt
33c0: 65 72 6e 61 74 69 76 65 20 43 53 56 20 73 63 68  ernative CSV sch
33d0: 65 6d 61 2e 0a 2a 2a 20 20 20 20 68 65 61 64 65  ema..**    heade
33e0: 72 3d 59 45 53 7c 4e 4f 20 20 20 20 20 20 20 20  r=YES|NO        
33f0: 20 20 20 20 20 20 46 69 72 73 74 20 72 6f 77 20        First row 
3400: 6f 66 20 43 53 56 20 64 65 66 69 6e 65 73 20 74  of CSV defines t
3410: 68 65 20 6e 61 6d 65 73 20 6f 66 0a 2a 2a 20 20  he names of.**  
3420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3430: 20 20 20 20 20 20 20 20 20 20 20 20 20 63 6f 6c               col
3440: 75 6d 6e 73 20 69 66 20 22 79 65 73 22 2e 20 20  umns if "yes".  
3450: 44 65 66 61 75 6c 74 20 22 6e 6f 22 2e 0a 2a 2a  Default "no"..**
3460: 20 20 20 20 63 6f 6c 75 6d 6e 73 3d 4e 20 20 20      columns=N   
3470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 41                 A
3480: 73 73 75 6d 65 20 74 68 65 20 43 53 56 20 66 69  ssume the CSV fi
3490: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 4e 20 63 6f  le contains N co
34a0: 6c 75 6d 6e 73 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 6c  lumns..**.** Onl
34b0: 79 20 61 76 61 69 6c 61 62 6c 65 20 69 66 20 63  y available if c
34c0: 6f 6d 70 69 6c 65 64 20 77 69 74 68 20 53 51 4c  ompiled with SQL
34d0: 49 54 45 5f 54 45 53 54 3a 0a 2a 2a 20 20 20 20  ITE_TEST:.**    
34e0: 0a 2a 2a 20 20 20 20 74 65 73 74 66 6c 61 67 73  .**    testflags
34f0: 3d 4e 20 20 20 20 20 20 20 20 20 20 20 20 20 20  =N              
3500: 20 20 42 69 74 6d 61 73 6b 20 6f 66 20 74 65 73    Bitmask of tes
3510: 74 20 66 6c 61 67 73 2e 20 20 4f 70 74 69 6f 6e  t flags.  Option
3520: 61 6c 0a 2a 2a 0a 2a 2a 20 49 66 20 73 63 68 65  al.**.** If sche
3530: 6d 61 3d 20 69 73 20 6f 6d 69 74 74 65 64 2c 20  ma= is omitted, 
3540: 74 68 65 6e 20 74 68 65 20 63 6f 6c 75 6d 6e 73  then the columns
3550: 20 61 72 65 20 6e 61 6d 65 64 20 22 63 30 22 2c   are named "c0",
3560: 20 22 63 31 22 2c 20 22 63 32 22 2c 0a 2a 2a 20   "c1", "c2",.** 
3570: 61 6e 64 20 73 6f 20 66 6f 72 74 68 2e 20 20 49  and so forth.  I
3580: 66 20 63 6f 6c 75 6d 6e 73 3d 4e 20 69 73 20 6f  f columns=N is o
3590: 6d 69 74 74 65 64 2c 20 74 68 65 6e 20 74 68 65  mitted, then the
35a0: 20 66 69 6c 65 20 69 73 20 6f 70 65 6e 65 64 20   file is opened 
35b0: 61 6e 64 0a 2a 2a 20 74 68 65 20 6e 75 6d 62 65  and.** the numbe
35c0: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
35d0: 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 69 73  the first row is
35e0: 20 63 6f 75 6e 74 65 64 20 74 6f 20 64 65 74 65   counted to dete
35f0: 72 6d 69 6e 65 20 74 68 65 0a 2a 2a 20 63 6f 6c  rmine the.** col
3600: 75 6d 6e 20 63 6f 75 6e 74 2e 20 20 49 66 20 68  umn count.  If h
3610: 65 61 64 65 72 3d 59 45 53 2c 20 74 68 65 6e 20  eader=YES, then 
3620: 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 69 73  the first row is
3630: 20 73 6b 69 70 70 65 64 2e 0a 2a 2f 0a 73 74 61   skipped..*/.sta
3640: 74 69 63 20 69 6e 74 20 63 73 76 74 61 62 43 6f  tic int csvtabCo
3650: 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74 65 33  nnect(.  sqlite3
3660: 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41   *db,.  void *pA
3670: 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  ux,.  int argc, 
3680: 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73  const char *cons
3690: 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65  t*argv,.  sqlite
36a0: 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c  3_vtab **ppVtab,
36b0: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a  .  char **pzErr.
36c0: 29 7b 0a 20 20 43 73 76 54 61 62 6c 65 20 2a 70  ){.  CsvTable *p
36d0: 4e 65 77 20 3d 20 30 3b 20 20 20 20 20 20 20 20  New = 0;        
36e0: 2f 2a 20 54 68 65 20 43 73 76 54 61 62 6c 65 20  /* The CsvTable 
36f0: 6f 62 6a 65 63 74 20 74 6f 20 63 6f 6e 73 74 72  object to constr
3700: 75 63 74 20 2a 2f 0a 20 20 69 6e 74 20 62 48 65  uct */.  int bHe
3710: 61 64 65 72 20 3d 20 2d 31 3b 20 20 20 20 20 20  ader = -1;      
3720: 20 20 20 20 2f 2a 20 68 65 61 64 65 72 3d 20 66      /* header= f
3730: 6c 61 67 73 2e 20 20 2d 31 20 6d 65 61 6e 73 20  lags.  -1 means 
3740: 6e 6f 74 20 73 65 65 6e 20 79 65 74 20 2a 2f 0a  not seen yet */.
3750: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
3760: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 2f 2a 20  E_OK;        /* 
3770: 52 65 73 75 6c 74 20 63 6f 64 65 20 66 72 6f 6d  Result code from
3780: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 2a 2f   this routine */
3790: 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 20 20 20 20  .  int i, j;    
37a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
37b0: 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 73 20 2a   Loop counters *
37c0: 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  /.#ifdef SQLITE_
37d0: 54 45 53 54 0a 20 20 69 6e 74 20 74 73 74 46 6c  TEST.  int tstFl
37e0: 61 67 73 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ags = 0;        
37f0: 20 20 2f 2a 20 56 61 6c 75 65 20 66 6f 72 20 74    /* Value for t
3800: 65 73 74 66 6c 61 67 73 3d 4e 20 70 61 72 61 6d  estflags=N param
3810: 65 74 65 72 20 2a 2f 0a 23 65 6e 64 69 66 0a 20  eter */.#endif. 
3820: 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 2d 39 39 3b   int nCol = -99;
3830: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
3840: 61 6c 75 65 20 6f 66 20 74 68 65 20 63 6f 6c 75  alue of the colu
3850: 6d 6e 73 3d 20 70 61 72 61 6d 65 74 65 72 20 2a  mns= parameter *
3860: 2f 0a 20 20 43 73 76 52 65 61 64 65 72 20 73 52  /.  CsvReader sR
3870: 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  dr;            /
3880: 2a 20 41 20 43 53 56 20 66 69 6c 65 20 72 65 61  * A CSV file rea
3890: 64 65 72 20 75 73 65 64 20 74 6f 20 73 74 6f 72  der used to stor
38a0: 65 20 61 6e 20 65 72 72 6f 72 0a 20 20 20 20 20  e an error.     
38b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38c0: 20 20 20 20 20 20 20 20 2a 2a 20 6d 65 73 73 61          ** messa
38d0: 67 65 20 61 6e 64 2f 6f 72 20 74 6f 20 63 6f 75  ge and/or to cou
38e0: 6e 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  nt the number of
38f0: 20 63 6f 6c 75 6d 6e 73 20 2a 2f 0a 20 20 73 74   columns */.  st
3900: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
3910: 2a 61 7a 50 61 72 61 6d 5b 5d 20 3d 20 7b 0a 20  *azParam[] = {. 
3920: 20 20 20 20 22 66 69 6c 65 6e 61 6d 65 22 2c 20      "filename", 
3930: 22 64 61 74 61 22 2c 20 22 73 63 68 65 6d 61 22  "data", "schema"
3940: 2c 20 0a 20 20 7d 3b 0a 20 20 63 68 61 72 20 2a  , .  };.  char *
3950: 61 7a 50 56 61 6c 75 65 5b 33 5d 3b 20 20 20 20  azPValue[3];    
3960: 20 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65       /* Paramete
3970: 72 20 76 61 6c 75 65 73 20 2a 2f 0a 23 20 64 65  r values */.# de
3980: 66 69 6e 65 20 43 53 56 5f 46 49 4c 45 4e 41 4d  fine CSV_FILENAM
3990: 45 20 28 61 7a 50 56 61 6c 75 65 5b 30 5d 29 0a  E (azPValue[0]).
39a0: 23 20 64 65 66 69 6e 65 20 43 53 56 5f 44 41 54  # define CSV_DAT
39b0: 41 20 20 20 20 20 28 61 7a 50 56 61 6c 75 65 5b  A     (azPValue[
39c0: 31 5d 29 0a 23 20 64 65 66 69 6e 65 20 43 53 56  1]).# define CSV
39d0: 5f 53 43 48 45 4d 41 20 20 20 28 61 7a 50 56 61  _SCHEMA   (azPVa
39e0: 6c 75 65 5b 32 5d 29 0a 0a 0a 20 20 61 73 73 65  lue[2])...  asse
39f0: 72 74 28 20 73 69 7a 65 6f 66 28 61 7a 50 56 61  rt( sizeof(azPVa
3a00: 6c 75 65 29 3d 3d 73 69 7a 65 6f 66 28 61 7a 50  lue)==sizeof(azP
3a10: 61 72 61 6d 29 20 29 3b 0a 20 20 6d 65 6d 73 65  aram) );.  memse
3a20: 74 28 26 73 52 64 72 2c 20 30 2c 20 73 69 7a 65  t(&sRdr, 0, size
3a30: 6f 66 28 73 52 64 72 29 29 3b 0a 20 20 6d 65 6d  of(sRdr));.  mem
3a40: 73 65 74 28 61 7a 50 56 61 6c 75 65 2c 20 30 2c  set(azPValue, 0,
3a50: 20 73 69 7a 65 6f 66 28 61 7a 50 56 61 6c 75 65   sizeof(azPValue
3a60: 29 29 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69  ));.  for(i=3; i
3a70: 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  <argc; i++){.   
3a80: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20 3d   const char *z =
3a90: 20 61 72 67 76 5b 69 5d 3b 0a 20 20 20 20 63 6f   argv[i];.    co
3aa0: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65  nst char *zValue
3ab0: 3b 0a 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a  ;.    for(j=0; j
3ac0: 3c 73 69 7a 65 6f 66 28 61 7a 50 61 72 61 6d 29  <sizeof(azParam)
3ad0: 2f 73 69 7a 65 6f 66 28 61 7a 50 61 72 61 6d 5b  /sizeof(azParam[
3ae0: 30 5d 29 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  0]); j++){.     
3af0: 20 69 66 28 20 63 73 76 5f 73 74 72 69 6e 67 5f   if( csv_string_
3b00: 70 61 72 61 6d 65 74 65 72 28 26 73 52 64 72 2c  parameter(&sRdr,
3b10: 20 61 7a 50 61 72 61 6d 5b 6a 5d 2c 20 7a 2c 20   azParam[j], z, 
3b20: 26 61 7a 50 56 61 6c 75 65 5b 6a 5d 29 20 29 20  &azPValue[j]) ) 
3b30: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20  break;.    }.   
3b40: 20 69 66 28 20 6a 3c 73 69 7a 65 6f 66 28 61 7a   if( j<sizeof(az
3b50: 50 61 72 61 6d 29 2f 73 69 7a 65 6f 66 28 61 7a  Param)/sizeof(az
3b60: 50 61 72 61 6d 5b 30 5d 29 20 29 7b 0a 20 20 20  Param[0]) ){.   
3b70: 20 20 20 69 66 28 20 73 52 64 72 2e 7a 45 72 72     if( sRdr.zErr
3b80: 5b 30 5d 20 29 20 67 6f 74 6f 20 63 73 76 74 61  [0] ) goto csvta
3b90: 62 5f 63 6f 6e 6e 65 63 74 5f 65 72 72 6f 72 3b  b_connect_error;
3ba0: 0a 20 20 20 20 7d 65 6c 73 65 0a 20 20 20 20 69  .    }else.    i
3bb0: 66 28 20 28 7a 56 61 6c 75 65 20 3d 20 63 73 76  f( (zValue = csv
3bc0: 5f 70 61 72 61 6d 65 74 65 72 28 22 68 65 61 64  _parameter("head
3bd0: 65 72 22 2c 36 2c 7a 29 29 21 3d 30 20 29 7b 0a  er",6,z))!=0 ){.
3be0: 20 20 20 20 20 20 69 6e 74 20 78 3b 0a 20 20 20        int x;.   
3bf0: 20 20 20 69 66 28 20 62 48 65 61 64 65 72 3e 3d     if( bHeader>=
3c00: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 73 76  0 ){.        csv
3c10: 5f 65 72 72 6d 73 67 28 26 73 52 64 72 2c 20 22  _errmsg(&sRdr, "
3c20: 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 20 27 68  more than one 'h
3c30: 65 61 64 65 72 27 20 70 61 72 61 6d 65 74 65 72  eader' parameter
3c40: 22 29 3b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f  ");.        goto
3c50: 20 63 73 76 74 61 62 5f 63 6f 6e 6e 65 63 74 5f   csvtab_connect_
3c60: 65 72 72 6f 72 3b 0a 20 20 20 20 20 20 7d 0a 20  error;.      }. 
3c70: 20 20 20 20 20 78 20 3d 20 63 73 76 5f 62 6f 6f       x = csv_boo
3c80: 6c 65 61 6e 28 7a 56 61 6c 75 65 29 3b 0a 20 20  lean(zValue);.  
3c90: 20 20 20 20 69 66 28 20 78 3d 3d 31 20 29 7b 0a      if( x==1 ){.
3ca0: 20 20 20 20 20 20 20 20 62 48 65 61 64 65 72 20          bHeader 
3cb0: 3d 20 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  = 1;.      }else
3cc0: 20 69 66 28 20 78 3d 3d 30 20 29 7b 0a 20 20 20   if( x==0 ){.   
3cd0: 20 20 20 20 20 62 48 65 61 64 65 72 20 3d 20 30       bHeader = 0
3ce0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
3cf0: 20 20 20 20 20 20 20 63 73 76 5f 65 72 72 6d 73         csv_errms
3d00: 67 28 26 73 52 64 72 2c 20 22 75 6e 72 65 63 6f  g(&sRdr, "unreco
3d10: 67 6e 69 7a 65 64 20 61 72 67 75 6d 65 6e 74 20  gnized argument 
3d20: 74 6f 20 27 68 65 61 64 65 72 27 3a 20 25 73 22  to 'header': %s"
3d30: 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20  , zValue);.     
3d40: 20 20 20 67 6f 74 6f 20 63 73 76 74 61 62 5f 63     goto csvtab_c
3d50: 6f 6e 6e 65 63 74 5f 65 72 72 6f 72 3b 0a 20 20  onnect_error;.  
3d60: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a      }.    }else.
3d70: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
3d80: 53 54 0a 20 20 20 20 69 66 28 20 28 7a 56 61 6c  ST.    if( (zVal
3d90: 75 65 20 3d 20 63 73 76 5f 70 61 72 61 6d 65 74  ue = csv_paramet
3da0: 65 72 28 22 74 65 73 74 66 6c 61 67 73 22 2c 39  er("testflags",9
3db0: 2c 7a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ,z))!=0 ){.     
3dc0: 20 74 73 74 46 6c 61 67 73 20 3d 20 28 75 6e 73   tstFlags = (uns
3dd0: 69 67 6e 65 64 20 69 6e 74 29 61 74 6f 69 28 7a  igned int)atoi(z
3de0: 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 65 6c 73  Value);.    }els
3df0: 65 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 28  e.#endif.    if(
3e00: 20 28 7a 56 61 6c 75 65 20 3d 20 63 73 76 5f 70   (zValue = csv_p
3e10: 61 72 61 6d 65 74 65 72 28 22 63 6f 6c 75 6d 6e  arameter("column
3e20: 73 22 2c 37 2c 7a 29 29 21 3d 30 20 29 7b 0a 20  s",7,z))!=0 ){. 
3e30: 20 20 20 20 20 69 66 28 20 6e 43 6f 6c 3e 30 20       if( nCol>0 
3e40: 29 7b 0a 20 20 20 20 20 20 20 20 63 73 76 5f 65  ){.        csv_e
3e50: 72 72 6d 73 67 28 26 73 52 64 72 2c 20 22 6d 6f  rrmsg(&sRdr, "mo
3e60: 72 65 20 74 68 61 6e 20 6f 6e 65 20 27 63 6f 6c  re than one 'col
3e70: 75 6d 6e 73 27 20 70 61 72 61 6d 65 74 65 72 22  umns' parameter"
3e80: 29 3b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20  );.        goto 
3e90: 63 73 76 74 61 62 5f 63 6f 6e 6e 65 63 74 5f 65  csvtab_connect_e
3ea0: 72 72 6f 72 3b 0a 20 20 20 20 20 20 7d 0a 20 20  rror;.      }.  
3eb0: 20 20 20 20 6e 43 6f 6c 20 3d 20 61 74 6f 69 28      nCol = atoi(
3ec0: 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 69  zValue);.      i
3ed0: 66 28 20 6e 43 6f 6c 3c 3d 30 20 29 7b 0a 20 20  f( nCol<=0 ){.  
3ee0: 20 20 20 20 20 20 63 73 76 5f 65 72 72 6d 73 67        csv_errmsg
3ef0: 28 26 73 52 64 72 2c 20 22 6d 75 73 74 20 68 61  (&sRdr, "must ha
3f00: 76 65 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20  ve at least one 
3f10: 63 6f 6c 75 6d 6e 22 29 3b 0a 20 20 20 20 20 20  column");.      
3f20: 20 20 67 6f 74 6f 20 63 73 76 74 61 62 5f 63 6f    goto csvtab_co
3f30: 6e 6e 65 63 74 5f 65 72 72 6f 72 3b 0a 20 20 20  nnect_error;.   
3f40: 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 0a 20     }.    }else. 
3f50: 20 20 20 7b 0a 20 20 20 20 20 20 63 73 76 5f 65     {.      csv_e
3f60: 72 72 6d 73 67 28 26 73 52 64 72 2c 20 22 75 6e  rrmsg(&sRdr, "un
3f70: 72 65 63 6f 67 6e 69 7a 65 64 20 70 61 72 61 6d  recognized param
3f80: 65 74 65 72 20 27 25 73 27 22 2c 20 7a 29 3b 0a  eter '%s'", z);.
3f90: 20 20 20 20 20 20 67 6f 74 6f 20 63 73 76 74 61        goto csvta
3fa0: 62 5f 63 6f 6e 6e 65 63 74 5f 65 72 72 6f 72 3b  b_connect_error;
3fb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
3fc0: 20 28 43 53 56 5f 46 49 4c 45 4e 41 4d 45 3d 3d   (CSV_FILENAME==
3fd0: 30 29 3d 3d 28 43 53 56 5f 44 41 54 41 3d 3d 30  0)==(CSV_DATA==0
3fe0: 29 20 29 7b 0a 20 20 20 20 63 73 76 5f 65 72 72  ) ){.    csv_err
3ff0: 6d 73 67 28 26 73 52 64 72 2c 20 22 6d 75 73 74  msg(&sRdr, "must
4000: 20 65 69 74 68 65 72 20 66 69 6c 65 6e 61 6d 65   either filename
4010: 3d 20 6f 72 20 64 61 74 61 3d 20 62 75 74 20 6e  = or data= but n
4020: 6f 74 20 62 6f 74 68 22 29 3b 0a 20 20 20 20 67  ot both");.    g
4030: 6f 74 6f 20 63 73 76 74 61 62 5f 63 6f 6e 6e 65  oto csvtab_conne
4040: 63 74 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a 20 20  ct_error;.  }.  
4050: 69 66 28 20 6e 43 6f 6c 3c 3d 30 20 26 26 20 63  if( nCol<=0 && c
4060: 73 76 5f 72 65 61 64 65 72 5f 6f 70 65 6e 28 26  sv_reader_open(&
4070: 73 52 64 72 2c 20 43 53 56 5f 46 49 4c 45 4e 41  sRdr, CSV_FILENA
4080: 4d 45 2c 20 43 53 56 5f 44 41 54 41 29 20 29 7b  ME, CSV_DATA) ){
4090: 0a 20 20 20 20 67 6f 74 6f 20 63 73 76 74 61 62  .    goto csvtab
40a0: 5f 63 6f 6e 6e 65 63 74 5f 65 72 72 6f 72 3b 0a  _connect_error;.
40b0: 20 20 7d 0a 20 20 70 4e 65 77 20 3d 20 73 71 6c    }.  pNew = sql
40c0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a  ite3_malloc( siz
40d0: 65 6f 66 28 2a 70 4e 65 77 29 20 29 3b 0a 20 20  eof(*pNew) );.  
40e0: 2a 70 70 56 74 61 62 20 3d 20 28 73 71 6c 69 74  *ppVtab = (sqlit
40f0: 65 33 5f 76 74 61 62 2a 29 70 4e 65 77 3b 0a 20  e3_vtab*)pNew;. 
4100: 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 20 67   if( pNew==0 ) g
4110: 6f 74 6f 20 63 73 76 74 61 62 5f 63 6f 6e 6e 65  oto csvtab_conne
4120: 63 74 5f 6f 6f 6d 3b 0a 20 20 6d 65 6d 73 65 74  ct_oom;.  memset
4130: 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66  (pNew, 0, sizeof
4140: 28 2a 70 4e 65 77 29 29 3b 0a 20 20 69 66 28 20  (*pNew));.  if( 
4150: 6e 43 6f 6c 3e 30 20 29 7b 0a 20 20 20 20 70 4e  nCol>0 ){.    pN
4160: 65 77 2d 3e 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b  ew->nCol = nCol;
4170: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 64 6f  .  }else{.    do
4180: 7b 0a 20 20 20 20 20 20 63 73 76 5f 72 65 61 64  {.      csv_read
4190: 5f 6f 6e 65 5f 66 69 65 6c 64 28 26 73 52 64 72  _one_field(&sRdr
41a0: 29 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e 6e  );.      pNew->n
41b0: 43 6f 6c 2b 2b 3b 0a 20 20 20 20 7d 77 68 69 6c  Col++;.    }whil
41c0: 65 28 20 73 52 64 72 2e 63 54 65 72 6d 3d 3d 27  e( sRdr.cTerm=='
41d0: 2c 27 20 29 3b 0a 20 20 7d 0a 20 20 70 4e 65 77  ,' );.  }.  pNew
41e0: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 20 3d 20 43 53  ->zFilename = CS
41f0: 56 5f 46 49 4c 45 4e 41 4d 45 3b 20 20 43 53 56  V_FILENAME;  CSV
4200: 5f 46 49 4c 45 4e 41 4d 45 20 3d 20 30 3b 0a 20  _FILENAME = 0;. 
4210: 20 70 4e 65 77 2d 3e 7a 44 61 74 61 20 3d 20 43   pNew->zData = C
4220: 53 56 5f 44 41 54 41 3b 20 20 20 20 20 20 20 20  SV_DATA;        
4230: 20 20 43 53 56 5f 44 41 54 41 20 3d 20 30 3b 0a    CSV_DATA = 0;.
4240: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45  #ifdef SQLITE_TE
4250: 53 54 0a 20 20 70 4e 65 77 2d 3e 74 73 74 46 6c  ST.  pNew->tstFl
4260: 61 67 73 20 3d 20 74 73 74 46 6c 61 67 73 3b 0a  ags = tstFlags;.
4270: 23 65 6e 64 69 66 0a 20 20 70 4e 65 77 2d 3e 69  #endif.  pNew->i
4280: 53 74 61 72 74 20 3d 20 62 48 65 61 64 65 72 3d  Start = bHeader=
4290: 3d 31 20 3f 20 66 74 65 6c 6c 28 73 52 64 72 2e  =1 ? ftell(sRdr.
42a0: 69 6e 29 20 3a 20 30 3b 0a 20 20 63 73 76 5f 72  in) : 0;.  csv_r
42b0: 65 61 64 65 72 5f 72 65 73 65 74 28 26 73 52 64  eader_reset(&sRd
42c0: 72 29 3b 0a 20 20 69 66 28 20 43 53 56 5f 53 43  r);.  if( CSV_SC
42d0: 48 45 4d 41 3d 3d 30 20 29 7b 0a 20 20 20 20 63  HEMA==0 ){.    c
42e0: 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 22 3b 0a  har *zSep = "";.
42f0: 20 20 20 20 43 53 56 5f 53 43 48 45 4d 41 20 3d      CSV_SCHEMA =
4300: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
4310: 28 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 78  ("CREATE TABLE x
4320: 28 22 29 3b 0a 20 20 20 20 69 66 28 20 43 53 56  (");.    if( CSV
4330: 5f 53 43 48 45 4d 41 3d 3d 30 20 29 20 67 6f 74  _SCHEMA==0 ) got
4340: 6f 20 63 73 76 74 61 62 5f 63 6f 6e 6e 65 63 74  o csvtab_connect
4350: 5f 6f 6f 6d 3b 0a 20 20 20 20 66 6f 72 28 69 3d  _oom;.    for(i=
4360: 30 3b 20 69 3c 70 4e 65 77 2d 3e 6e 43 6f 6c 3b  0; i<pNew->nCol;
4370: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 43 53 56   i++){.      CSV
4380: 5f 53 43 48 45 4d 41 20 3d 20 73 71 6c 69 74 65  _SCHEMA = sqlite
4390: 33 5f 6d 70 72 69 6e 74 66 28 22 25 7a 25 73 63  3_mprintf("%z%sc
43a0: 25 64 20 54 45 58 54 22 2c 43 53 56 5f 53 43 48  %d TEXT",CSV_SCH
43b0: 45 4d 41 2c 20 7a 53 65 70 2c 20 69 29 3b 0a 20  EMA, zSep, i);. 
43c0: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b       zSep = ",";
43d0: 0a 20 20 20 20 7d 0a 20 20 20 20 43 53 56 5f 53  .    }.    CSV_S
43e0: 43 48 45 4d 41 20 3d 20 73 71 6c 69 74 65 33 5f  CHEMA = sqlite3_
43f0: 6d 70 72 69 6e 74 66 28 22 25 7a 29 3b 22 2c 20  mprintf("%z);", 
4400: 43 53 56 5f 53 43 48 45 4d 41 29 3b 0a 20 20 7d  CSV_SCHEMA);.  }
4410: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
4420: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c  declare_vtab(db,
4430: 20 43 53 56 5f 53 43 48 45 4d 41 29 3b 0a 20 20   CSV_SCHEMA);.  
4440: 69 66 28 20 72 63 20 29 20 67 6f 74 6f 20 63 73  if( rc ) goto cs
4450: 76 74 61 62 5f 63 6f 6e 6e 65 63 74 5f 65 72 72  vtab_connect_err
4460: 6f 72 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  or;.  for(i=0; i
4470: 3c 73 69 7a 65 6f 66 28 61 7a 50 56 61 6c 75 65  <sizeof(azPValue
4480: 29 2f 73 69 7a 65 6f 66 28 61 7a 50 56 61 6c 75  )/sizeof(azPValu
4490: 65 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  e[0]); i++){.   
44a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 7a   sqlite3_free(az
44b0: 50 56 61 6c 75 65 5b 69 5d 29 3b 0a 20 20 7d 0a  PValue[i]);.  }.
44c0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
44d0: 4f 4b 3b 0a 0a 63 73 76 74 61 62 5f 63 6f 6e 6e  OK;..csvtab_conn
44e0: 65 63 74 5f 6f 6f 6d 3a 0a 20 20 72 63 20 3d 20  ect_oom:.  rc = 
44f0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
4500: 63 73 76 5f 65 72 72 6d 73 67 28 26 73 52 64 72  csv_errmsg(&sRdr
4510: 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  , "out of memory
4520: 22 29 3b 0a 0a 63 73 76 74 61 62 5f 63 6f 6e 6e  ");..csvtab_conn
4530: 65 63 74 5f 65 72 72 6f 72 3a 0a 20 20 69 66 28  ect_error:.  if(
4540: 20 70 4e 65 77 20 29 20 63 73 76 74 61 62 44 69   pNew ) csvtabDi
4550: 73 63 6f 6e 6e 65 63 74 28 26 70 4e 65 77 2d 3e  sconnect(&pNew->
4560: 62 61 73 65 29 3b 0a 20 20 66 6f 72 28 69 3d 30  base);.  for(i=0
4570: 3b 20 69 3c 73 69 7a 65 6f 66 28 61 7a 50 56 61  ; i<sizeof(azPVa
4580: 6c 75 65 29 2f 73 69 7a 65 6f 66 28 61 7a 50 56  lue)/sizeof(azPV
4590: 61 6c 75 65 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a  alue[0]); i++){.
45a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
45b0: 28 61 7a 50 56 61 6c 75 65 5b 69 5d 29 3b 0a 20  (azPValue[i]);. 
45c0: 20 7d 0a 20 20 69 66 28 20 73 52 64 72 2e 7a 45   }.  if( sRdr.zE
45d0: 72 72 5b 30 5d 20 29 7b 0a 20 20 20 20 73 71 6c  rr[0] ){.    sql
45e0: 69 74 65 33 5f 66 72 65 65 28 2a 70 7a 45 72 72  ite3_free(*pzErr
45f0: 29 3b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20  );.    *pzErr = 
4600: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
4610: 22 25 73 22 2c 20 73 52 64 72 2e 7a 45 72 72 29  "%s", sRdr.zErr)
4620: 3b 0a 20 20 7d 0a 20 20 63 73 76 5f 72 65 61 64  ;.  }.  csv_read
4630: 65 72 5f 72 65 73 65 74 28 26 73 52 64 72 29 3b  er_reset(&sRdr);
4640: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
4650: 45 5f 4f 4b 20 29 20 72 63 20 3d 20 53 51 4c 49  E_OK ) rc = SQLI
4660: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 72 65 74 75  TE_ERROR;.  retu
4670: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
4680: 52 65 73 65 74 20 74 68 65 20 63 75 72 72 65 6e  Reset the curren
4690: 74 20 72 6f 77 20 63 6f 6e 74 65 6e 74 20 68 65  t row content he
46a0: 6c 64 20 62 79 20 61 20 43 73 76 43 75 72 73 6f  ld by a CsvCurso
46b0: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
46c0: 64 20 63 73 76 74 61 62 43 75 72 73 6f 72 52 6f  d csvtabCursorRo
46d0: 77 52 65 73 65 74 28 43 73 76 43 75 72 73 6f 72  wReset(CsvCursor
46e0: 20 2a 70 43 75 72 29 7b 0a 20 20 43 73 76 54 61   *pCur){.  CsvTa
46f0: 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 43 73 76  ble *pTab = (Csv
4700: 54 61 62 6c 65 2a 29 70 43 75 72 2d 3e 62 61 73  Table*)pCur->bas
4710: 65 2e 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 69  e.pVtab;.  int i
4720: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ;.  for(i=0; i<p
4730: 54 61 62 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  Tab->nCol; i++){
4740: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4750: 65 28 70 43 75 72 2d 3e 61 7a 56 61 6c 5b 69 5d  e(pCur->azVal[i]
4760: 29 3b 0a 20 20 20 20 70 43 75 72 2d 3e 61 7a 56  );.    pCur->azV
4770: 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 70  al[i] = 0;.    p
4780: 43 75 72 2d 3e 61 4c 65 6e 5b 69 5d 20 3d 20 30  Cur->aLen[i] = 0
4790: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ;.  }.}../*.** T
47a0: 68 65 20 78 43 6f 6e 6e 65 63 74 20 61 6e 64 20  he xConnect and 
47b0: 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 73 20  xCreate methods 
47c0: 64 6f 20 74 68 65 20 73 61 6d 65 20 74 68 69 6e  do the same thin
47d0: 67 2c 20 62 75 74 20 74 68 65 79 20 6d 75 73 74  g, but they must
47e0: 20 62 65 0a 2a 2a 20 64 69 66 66 65 72 65 6e 74   be.** different
47f0: 20 73 6f 20 74 68 61 74 20 74 68 65 20 76 69 72   so that the vir
4800: 74 75 61 6c 20 74 61 62 6c 65 20 69 73 20 6e 6f  tual table is no
4810: 74 20 61 6e 20 65 70 6f 6e 79 6d 6f 75 73 20 76  t an eponymous v
4820: 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f  irtual table..*/
4830: 0a 73 74 61 74 69 63 20 69 6e 74 20 63 73 76 74  .static int csvt
4840: 61 62 43 72 65 61 74 65 28 0a 20 20 73 71 6c 69  abCreate(.  sqli
4850: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
4860: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
4870: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
4880: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c  onst*argv,.  sql
4890: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74  ite3_vtab **ppVt
48a0: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  ab,.  char **pzE
48b0: 72 72 0a 29 7b 0a 20 72 65 74 75 72 6e 20 63 73  rr.){. return cs
48c0: 76 74 61 62 43 6f 6e 6e 65 63 74 28 64 62 2c 20  vtabConnect(db, 
48d0: 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76  pAux, argc, argv
48e0: 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29  , ppVtab, pzErr)
48f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72  ;.}../*.** Destr
4900: 75 63 74 6f 72 20 66 6f 72 20 61 20 43 73 76 43  uctor for a CsvC
4910: 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  ursor..*/.static
4920: 20 69 6e 74 20 63 73 76 74 61 62 43 6c 6f 73 65   int csvtabClose
4930: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
4940: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 43 73  rsor *cur){.  Cs
4950: 76 43 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  vCursor *pCur = 
4960: 28 43 73 76 43 75 72 73 6f 72 2a 29 63 75 72 3b  (CsvCursor*)cur;
4970: 0a 20 20 63 73 76 74 61 62 43 75 72 73 6f 72 52  .  csvtabCursorR
4980: 6f 77 52 65 73 65 74 28 70 43 75 72 29 3b 0a 20  owReset(pCur);. 
4990: 20 63 73 76 5f 72 65 61 64 65 72 5f 72 65 73 65   csv_reader_rese
49a0: 74 28 26 70 43 75 72 2d 3e 72 64 72 29 3b 0a 20  t(&pCur->rdr);. 
49b0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 63 75   sqlite3_free(cu
49c0: 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  r);.  return SQL
49d0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
49e0: 20 43 6f 6e 73 74 72 75 63 74 6f 72 20 66 6f 72   Constructor for
49f0: 20 61 20 6e 65 77 20 43 73 76 54 61 62 6c 65 20   a new CsvTable 
4a00: 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a  cursor object..*
4a10: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 73 76  /.static int csv
4a20: 74 61 62 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  tabOpen(sqlite3_
4a30: 76 74 61 62 20 2a 70 2c 20 73 71 6c 69 74 65 33  vtab *p, sqlite3
4a40: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70  _vtab_cursor **p
4a50: 70 43 75 72 73 6f 72 29 7b 0a 20 20 43 73 76 54  pCursor){.  CsvT
4a60: 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 43 73  able *pTab = (Cs
4a70: 76 54 61 62 6c 65 2a 29 70 3b 0a 20 20 43 73 76  vTable*)p;.  Csv
4a80: 43 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20  Cursor *pCur;.  
4a90: 73 69 7a 65 5f 74 20 6e 42 79 74 65 3b 0a 20 20  size_t nByte;.  
4aa0: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 2a  nByte = sizeof(*
4ab0: 70 43 75 72 29 20 2b 20 28 73 69 7a 65 6f 66 28  pCur) + (sizeof(
4ac0: 63 68 61 72 2a 29 2b 73 69 7a 65 6f 66 28 69 6e  char*)+sizeof(in
4ad0: 74 29 29 2a 70 54 61 62 2d 3e 6e 43 6f 6c 3b 0a  t))*pTab->nCol;.
4ae0: 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33    pCur = sqlite3
4af0: 5f 6d 61 6c 6c 6f 63 36 34 28 20 6e 42 79 74 65  _malloc64( nByte
4b00: 20 29 3b 0a 20 20 69 66 28 20 70 43 75 72 3d 3d   );.  if( pCur==
4b10: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
4b20: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65  E_NOMEM;.  memse
4b30: 74 28 70 43 75 72 2c 20 30 2c 20 6e 42 79 74 65  t(pCur, 0, nByte
4b40: 29 3b 0a 20 20 70 43 75 72 2d 3e 61 7a 56 61 6c  );.  pCur->azVal
4b50: 20 3d 20 28 63 68 61 72 2a 2a 29 26 70 43 75 72   = (char**)&pCur
4b60: 5b 31 5d 3b 0a 20 20 70 43 75 72 2d 3e 61 4c 65  [1];.  pCur->aLe
4b70: 6e 20 3d 20 28 69 6e 74 2a 29 26 70 43 75 72 2d  n = (int*)&pCur-
4b80: 3e 61 7a 56 61 6c 5b 70 54 61 62 2d 3e 6e 43 6f  >azVal[pTab->nCo
4b90: 6c 5d 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20  l];.  *ppCursor 
4ba0: 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a 20  = &pCur->base;. 
4bb0: 20 69 66 28 20 63 73 76 5f 72 65 61 64 65 72 5f   if( csv_reader_
4bc0: 6f 70 65 6e 28 26 70 43 75 72 2d 3e 72 64 72 2c  open(&pCur->rdr,
4bd0: 20 70 54 61 62 2d 3e 7a 46 69 6c 65 6e 61 6d 65   pTab->zFilename
4be0: 2c 20 70 54 61 62 2d 3e 7a 44 61 74 61 29 20 29  , pTab->zData) )
4bf0: 7b 0a 20 20 20 20 63 73 76 5f 78 66 65 72 5f 65  {.    csv_xfer_e
4c00: 72 72 6f 72 28 70 54 61 62 2c 20 26 70 43 75 72  rror(pTab, &pCur
4c10: 2d 3e 72 64 72 29 3b 0a 20 20 20 20 72 65 74 75  ->rdr);.    retu
4c20: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
4c30: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51  .  }.  return SQ
4c40: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a  LITE_OK;.}.../*.
4c50: 2a 2a 20 41 64 76 61 6e 63 65 20 61 20 43 73 76  ** Advance a Csv
4c60: 43 75 72 73 6f 72 20 74 6f 20 69 74 73 20 6e 65  Cursor to its ne
4c70: 78 74 20 72 6f 77 20 6f 66 20 69 6e 70 75 74 2e  xt row of input.
4c80: 0a 2a 2a 20 53 65 74 20 74 68 65 20 45 4f 46 20  .** Set the EOF 
4c90: 6d 61 72 6b 65 72 20 69 66 20 77 65 20 72 65 61  marker if we rea
4ca0: 63 68 20 74 68 65 20 65 6e 64 20 6f 66 20 69 6e  ch the end of in
4cb0: 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  put..*/.static i
4cc0: 6e 74 20 63 73 76 74 61 62 4e 65 78 74 28 73 71  nt csvtabNext(sq
4cd0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4ce0: 72 20 2a 63 75 72 29 7b 0a 20 20 43 73 76 43 75  r *cur){.  CsvCu
4cf0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 43 73  rsor *pCur = (Cs
4d00: 76 43 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20  vCursor*)cur;.  
4d10: 43 73 76 54 61 62 6c 65 20 2a 70 54 61 62 20 3d  CsvTable *pTab =
4d20: 20 28 43 73 76 54 61 62 6c 65 2a 29 63 75 72 2d   (CsvTable*)cur-
4d30: 3e 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 69 20  >pVtab;.  int i 
4d40: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a  = 0;.  char *z;.
4d50: 20 20 64 6f 7b 0a 20 20 20 20 7a 20 3d 20 63 73    do{.    z = cs
4d60: 76 5f 72 65 61 64 5f 6f 6e 65 5f 66 69 65 6c 64  v_read_one_field
4d70: 28 26 70 43 75 72 2d 3e 72 64 72 29 3b 0a 20 20  (&pCur->rdr);.  
4d80: 20 20 69 66 28 20 7a 3d 3d 30 20 29 7b 0a 20 20    if( z==0 ){.  
4d90: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d      break;.    }
4da0: 0a 20 20 20 20 69 66 28 20 69 3c 70 54 61 62 2d  .    if( i<pTab-
4db0: 3e 6e 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 69  >nCol ){.      i
4dc0: 66 28 20 70 43 75 72 2d 3e 61 4c 65 6e 5b 69 5d  f( pCur->aLen[i]
4dd0: 20 3c 20 70 43 75 72 2d 3e 72 64 72 2e 6e 2b 31   < pCur->rdr.n+1
4de0: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72   ){.        char
4df0: 20 2a 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33   *zNew = sqlite3
4e00: 5f 72 65 61 6c 6c 6f 63 36 34 28 70 43 75 72 2d  _realloc64(pCur-
4e10: 3e 61 7a 56 61 6c 5b 69 5d 2c 20 70 43 75 72 2d  >azVal[i], pCur-
4e20: 3e 72 64 72 2e 6e 2b 31 29 3b 0a 20 20 20 20 20  >rdr.n+1);.     
4e30: 20 20 20 69 66 28 20 7a 4e 65 77 3d 3d 30 20 29     if( zNew==0 )
4e40: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 73 76 5f  {.          csv_
4e50: 65 72 72 6d 73 67 28 26 70 43 75 72 2d 3e 72 64  errmsg(&pCur->rd
4e60: 72 2c 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72  r, "out of memor
4e70: 79 22 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63  y");.          c
4e80: 73 76 5f 78 66 65 72 5f 65 72 72 6f 72 28 70 54  sv_xfer_error(pT
4e90: 61 62 2c 20 26 70 43 75 72 2d 3e 72 64 72 29 3b  ab, &pCur->rdr);
4ea0: 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
4eb0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
4ec0: 20 20 20 20 70 43 75 72 2d 3e 61 7a 56 61 6c 5b      pCur->azVal[
4ed0: 69 5d 20 3d 20 7a 4e 65 77 3b 0a 20 20 20 20 20  i] = zNew;.     
4ee0: 20 20 20 70 43 75 72 2d 3e 61 4c 65 6e 5b 69 5d     pCur->aLen[i]
4ef0: 20 3d 20 70 43 75 72 2d 3e 72 64 72 2e 6e 2b 31   = pCur->rdr.n+1
4f00: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
4f10: 6d 65 6d 63 70 79 28 70 43 75 72 2d 3e 61 7a 56  memcpy(pCur->azV
4f20: 61 6c 5b 69 5d 2c 20 7a 2c 20 70 43 75 72 2d 3e  al[i], z, pCur->
4f30: 72 64 72 2e 6e 2b 31 29 3b 0a 20 20 20 20 20 20  rdr.n+1);.      
4f40: 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 77 68  i++;.    }.  }wh
4f50: 69 6c 65 28 20 70 43 75 72 2d 3e 72 64 72 2e 63  ile( pCur->rdr.c
4f60: 54 65 72 6d 3d 3d 27 2c 27 20 29 3b 0a 20 20 69  Term==',' );.  i
4f70: 66 28 20 7a 3d 3d 30 20 7c 7c 20 28 70 43 75 72  f( z==0 || (pCur
4f80: 2d 3e 72 64 72 2e 63 54 65 72 6d 3d 3d 45 4f 46  ->rdr.cTerm==EOF
4f90: 20 26 26 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c   && i<pTab->nCol
4fa0: 29 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e 69  ) ){.    pCur->i
4fb0: 52 6f 77 69 64 20 3d 20 2d 31 3b 0a 20 20 7d 65  Rowid = -1;.  }e
4fc0: 6c 73 65 7b 0a 20 20 20 20 70 43 75 72 2d 3e 69  lse{.    pCur->i
4fd0: 52 6f 77 69 64 2b 2b 3b 0a 20 20 20 20 77 68 69  Rowid++;.    whi
4fe0: 6c 65 28 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c  le( i<pTab->nCol
4ff0: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
5000: 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 61 7a 56  3_free(pCur->azV
5010: 61 6c 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70 43  al[i]);.      pC
5020: 75 72 2d 3e 61 7a 56 61 6c 5b 69 5d 20 3d 20 30  ur->azVal[i] = 0
5030: 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 61 4c  ;.      pCur->aL
5040: 65 6e 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20  en[i] = 0;.     
5050: 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   i++;.    }.  }.
5060: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5070: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  OK;.}../*.** Ret
5080: 75 72 6e 20 76 61 6c 75 65 73 20 6f 66 20 63 6f  urn values of co
5090: 6c 75 6d 6e 73 20 66 6f 72 20 74 68 65 20 72 6f  lumns for the ro
50a0: 77 20 61 74 20 77 68 69 63 68 20 74 68 65 20 43  w at which the C
50b0: 73 76 43 75 72 73 6f 72 0a 2a 2a 20 69 73 20 63  svCursor.** is c
50c0: 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 69 6e  urrently pointin
50d0: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
50e0: 20 63 73 76 74 61 62 43 6f 6c 75 6d 6e 28 0a 20   csvtabColumn(. 
50f0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
5100: 72 73 6f 72 20 2a 63 75 72 2c 20 20 20 2f 2a 20  rsor *cur,   /* 
5110: 54 68 65 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  The cursor */.  
5120: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
5130: 2a 63 74 78 2c 20 20 20 20 20 20 20 2f 2a 20 46  *ctx,       /* F
5140: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 6f  irst argument to
5150: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
5160: 2e 2e 2e 28 29 20 2a 2f 0a 20 20 69 6e 74 20 69  ...() */.  int i
5170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5180: 20 20 20 20 20 20 20 2f 2a 20 57 68 69 63 68 20         /* Which 
5190: 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 74 75 72 6e  column to return
51a0: 20 2a 2f 0a 29 7b 0a 20 20 43 73 76 43 75 72 73   */.){.  CsvCurs
51b0: 6f 72 20 2a 70 43 75 72 20 3d 20 28 43 73 76 43  or *pCur = (CsvC
51c0: 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 43 73  ursor*)cur;.  Cs
51d0: 76 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28  vTable *pTab = (
51e0: 43 73 76 54 61 62 6c 65 2a 29 63 75 72 2d 3e 70  CsvTable*)cur->p
51f0: 56 74 61 62 3b 0a 20 20 69 66 28 20 69 3e 3d 30  Vtab;.  if( i>=0
5200: 20 26 26 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c   && i<pTab->nCol
5210: 20 26 26 20 70 43 75 72 2d 3e 61 7a 56 61 6c 5b   && pCur->azVal[
5220: 69 5d 21 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c  i]!=0 ){.    sql
5230: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
5240: 28 63 74 78 2c 20 70 43 75 72 2d 3e 61 7a 56 61  (ctx, pCur->azVa
5250: 6c 5b 69 5d 2c 20 2d 31 2c 20 53 51 4c 49 54 45  l[i], -1, SQLITE
5260: 5f 53 54 41 54 49 43 29 3b 0a 20 20 7d 0a 20 20  _STATIC);.  }.  
5270: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5280: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
5290: 6e 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72 20  n the rowid for 
52a0: 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77 2e  the current row.
52b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63  .*/.static int c
52c0: 73 76 74 61 62 52 6f 77 69 64 28 73 71 6c 69 74  svtabRowid(sqlit
52d0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
52e0: 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  cur, sqlite_int6
52f0: 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 43 73  4 *pRowid){.  Cs
5300: 76 43 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  vCursor *pCur = 
5310: 28 43 73 76 43 75 72 73 6f 72 2a 29 63 75 72 3b  (CsvCursor*)cur;
5320: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 70 43 75  .  *pRowid = pCu
5330: 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 72 65 74  r->iRowid;.  ret
5340: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5350: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54  ../*.** Return T
5360: 52 55 45 20 69 66 20 74 68 65 20 63 75 72 73 6f  RUE if the curso
5370: 72 20 68 61 73 20 62 65 65 6e 20 6d 6f 76 65 64  r has been moved
5380: 20 6f 66 66 20 6f 66 20 74 68 65 20 6c 61 73 74   off of the last
5390: 0a 2a 2a 20 72 6f 77 20 6f 66 20 6f 75 74 70 75  .** row of outpu
53a0: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
53b0: 20 63 73 76 74 61 62 45 6f 66 28 73 71 6c 69 74   csvtabEof(sqlit
53c0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
53d0: 63 75 72 29 7b 0a 20 20 43 73 76 43 75 72 73 6f  cur){.  CsvCurso
53e0: 72 20 2a 70 43 75 72 20 3d 20 28 43 73 76 43 75  r *pCur = (CsvCu
53f0: 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 72 65 74  rsor*)cur;.  ret
5400: 75 72 6e 20 70 43 75 72 2d 3e 69 52 6f 77 69 64  urn pCur->iRowid
5410: 3c 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 6c  <0;.}../*.** Onl
5420: 79 20 61 20 66 75 6c 6c 20 74 61 62 6c 65 20 73  y a full table s
5430: 63 61 6e 20 69 73 20 73 75 70 70 6f 72 74 65 64  can is supported
5440: 2e 20 20 53 6f 20 78 46 69 6c 74 65 72 20 73 69  .  So xFilter si
5450: 6d 70 6c 79 20 72 65 77 69 6e 64 73 20 74 6f 0a  mply rewinds to.
5460: 2a 2a 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  ** the beginning
5470: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
5480: 63 73 76 74 61 62 46 69 6c 74 65 72 28 0a 20 20  csvtabFilter(.  
5490: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
54a0: 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72  sor *pVtabCursor
54b0: 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  , .  int idxNum,
54c0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
54d0: 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Str,.  int argc,
54e0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
54f0: 2a 61 72 67 76 0a 29 7b 0a 20 20 43 73 76 43 75  *argv.){.  CsvCu
5500: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 43 73  rsor *pCur = (Cs
5510: 76 43 75 72 73 6f 72 2a 29 70 56 74 61 62 43 75  vCursor*)pVtabCu
5520: 72 73 6f 72 3b 0a 20 20 43 73 76 54 61 62 6c 65  rsor;.  CsvTable
5530: 20 2a 70 54 61 62 20 3d 20 28 43 73 76 54 61 62   *pTab = (CsvTab
5540: 6c 65 2a 29 70 56 74 61 62 43 75 72 73 6f 72 2d  le*)pVtabCursor-
5550: 3e 70 56 74 61 62 3b 0a 20 20 70 43 75 72 2d 3e  >pVtab;.  pCur->
5560: 69 52 6f 77 69 64 20 3d 20 30 3b 0a 20 20 69 66  iRowid = 0;.  if
5570: 28 20 70 43 75 72 2d 3e 72 64 72 2e 69 6e 3d 3d  ( pCur->rdr.in==
5580: 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  0 ){.    assert(
5590: 20 70 43 75 72 2d 3e 72 64 72 2e 7a 49 6e 3d 3d   pCur->rdr.zIn==
55a0: 70 54 61 62 2d 3e 7a 44 61 74 61 20 29 3b 0a 20  pTab->zData );. 
55b0: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d     assert( pTab-
55c0: 3e 69 53 74 61 72 74 3e 3d 30 20 29 3b 0a 20 20  >iStart>=0 );.  
55d0: 20 20 61 73 73 65 72 74 28 20 28 73 69 7a 65 5f    assert( (size_
55e0: 74 29 70 54 61 62 2d 3e 69 53 74 61 72 74 3c 3d  t)pTab->iStart<=
55f0: 70 43 75 72 2d 3e 72 64 72 2e 6e 49 6e 20 29 3b  pCur->rdr.nIn );
5600: 0a 20 20 20 20 70 43 75 72 2d 3e 72 64 72 2e 69  .    pCur->rdr.i
5610: 49 6e 20 3d 20 70 54 61 62 2d 3e 69 53 74 61 72  In = pTab->iStar
5620: 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  t;.  }else{.    
5630: 66 73 65 65 6b 28 70 43 75 72 2d 3e 72 64 72 2e  fseek(pCur->rdr.
5640: 69 6e 2c 20 70 54 61 62 2d 3e 69 53 74 61 72 74  in, pTab->iStart
5650: 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 20 20 20  , SEEK_SET);.   
5660: 20 70 43 75 72 2d 3e 72 64 72 2e 69 49 6e 20 3d   pCur->rdr.iIn =
5670: 20 30 3b 0a 20 20 20 20 70 43 75 72 2d 3e 72 64   0;.    pCur->rd
5680: 72 2e 6e 49 6e 20 3d 20 30 3b 0a 20 20 7d 0a 20  r.nIn = 0;.  }. 
5690: 20 72 65 74 75 72 6e 20 63 73 76 74 61 62 4e 65   return csvtabNe
56a0: 78 74 28 70 56 74 61 62 43 75 72 73 6f 72 29 3b  xt(pVtabCursor);
56b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 6c 79 20 61  .}../*.** Only a
56c0: 20 66 6f 72 77 61 72 64 20 66 75 6c 6c 20 74 61   forward full ta
56d0: 62 6c 65 20 73 63 61 6e 20 69 73 20 73 75 70 70  ble scan is supp
56e0: 6f 72 74 65 64 2e 20 20 78 42 65 73 74 49 6e 64  orted.  xBestInd
56f0: 65 78 20 69 73 20 6d 6f 73 74 6c 79 0a 2a 2a 20  ex is mostly.** 
5700: 61 20 6e 6f 2d 6f 70 2e 20 20 49 66 20 43 53 56  a no-op.  If CSV
5710: 54 45 53 54 5f 46 49 44 58 20 69 73 20 73 65 74  TEST_FIDX is set
5720: 2c 20 74 68 65 6e 20 74 68 65 20 70 72 65 73 65  , then the prese
5730: 6e 63 65 20 6f 66 20 65 71 75 61 6c 69 74 79 0a  nce of equality.
5740: 2a 2a 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 6c  ** constraints l
5750: 6f 77 65 72 73 20 74 68 65 20 65 73 74 69 6d 61  owers the estima
5760: 74 65 64 20 63 6f 73 74 2c 20 77 68 69 63 68 20  ted cost, which 
5770: 69 73 20 66 69 63 74 69 6f 6e 2c 20 62 75 74 20  is fiction, but 
5780: 69 73 20 75 73 65 66 75 6c 0a 2a 2a 20 66 6f 72  is useful.** for
5790: 20 74 65 73 74 69 6e 67 20 63 65 72 74 61 69 6e   testing certain
57a0: 20 6b 69 6e 64 73 20 6f 66 20 76 69 72 74 75 61   kinds of virtua
57b0: 6c 20 74 61 62 6c 65 20 62 65 68 61 76 69 6f 72  l table behavior
57c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
57d0: 63 73 76 74 61 62 42 65 73 74 49 6e 64 65 78 28  csvtabBestIndex(
57e0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
57f0: 2a 74 61 62 2c 0a 20 20 73 71 6c 69 74 65 33 5f  *tab,.  sqlite3_
5800: 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78  index_info *pIdx
5810: 49 6e 66 6f 0a 29 7b 0a 20 20 70 49 64 78 49 6e  Info.){.  pIdxIn
5820: 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73  fo->estimatedCos
5830: 74 20 3d 20 31 30 30 30 30 30 30 3b 0a 23 69 66  t = 1000000;.#if
5840: 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a  def SQLITE_TEST.
5850: 20 20 69 66 28 20 28 28 28 43 73 76 54 61 62 6c    if( (((CsvTabl
5860: 65 2a 29 74 61 62 29 2d 3e 74 73 74 46 6c 61 67  e*)tab)->tstFlag
5870: 73 20 26 20 43 53 56 54 45 53 54 5f 46 49 44 58  s & CSVTEST_FIDX
5880: 29 21 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 54  )!=0 ){.    /* T
5890: 68 65 20 75 73 75 61 6c 20 28 61 6e 64 20 73 65  he usual (and se
58a0: 6e 73 69 62 6c 65 29 20 63 61 73 65 20 69 73 20  nsible) case is 
58b0: 74 6f 20 61 6c 77 61 79 73 20 64 6f 20 61 20 66  to always do a f
58c0: 75 6c 6c 20 74 61 62 6c 65 20 73 63 61 6e 2e 0a  ull table scan..
58d0: 20 20 20 20 2a 2a 20 54 68 65 20 63 6f 64 65 20      ** The code 
58e0: 69 6e 20 74 68 69 73 20 62 72 61 6e 63 68 20 6f  in this branch o
58f0: 6e 6c 79 20 72 75 6e 73 20 77 68 65 6e 20 74 65  nly runs when te
5900: 73 74 66 6c 61 67 73 3d 31 2e 20 20 54 68 69 73  stflags=1.  This
5910: 20 63 6f 64 65 0a 20 20 20 20 2a 2a 20 67 65 6e   code.    ** gen
5920: 65 72 61 74 65 73 20 61 6e 20 61 72 74 69 66 69  erates an artifi
5930: 63 61 6c 20 61 6e 64 20 75 6e 72 65 61 6c 69 73  cal and unrealis
5940: 74 69 63 20 70 6c 61 6e 20 77 68 69 63 68 20 69  tic plan which i
5950: 73 20 75 73 65 66 75 6c 0a 20 20 20 20 2a 2a 20  s useful.    ** 
5960: 66 6f 72 20 74 65 73 74 69 6e 67 20 76 69 72 74  for testing virt
5970: 75 61 6c 20 74 61 62 6c 65 20 6c 6f 67 69 63 20  ual table logic 
5980: 62 75 74 20 69 73 20 6e 6f 74 20 68 65 6c 70 66  but is not helpf
5990: 75 6c 20 74 6f 20 72 65 61 6c 20 61 70 70 6c 69  ul to real appli
59a0: 63 61 74 69 6f 6e 73 2e 0a 20 20 20 20 2a 2a 0a  cations..    **.
59b0: 20 20 20 20 2a 2a 20 41 6e 79 20 3d 3d 2c 20 4c      ** Any ==, L
59c0: 49 4b 45 2c 20 6f 72 20 47 4c 4f 42 20 63 6f 6e  IKE, or GLOB con
59d0: 73 74 72 61 69 6e 74 20 69 73 20 6d 61 72 6b 65  straint is marke
59e0: 64 20 61 73 20 75 73 61 62 6c 65 20 62 79 20 74  d as usable by t
59f0: 68 65 20 76 69 72 74 75 61 6c 0a 20 20 20 20 2a  he virtual.    *
5a00: 2a 20 74 61 62 6c 65 20 28 65 76 65 6e 20 74 68  * table (even th
5a10: 6f 75 67 68 20 69 74 20 69 73 20 6e 6f 74 29 20  ough it is not) 
5a20: 61 6e 64 20 74 68 65 20 63 6f 73 74 20 6f 66 20  and the cost of 
5a30: 72 75 6e 6e 69 6e 67 20 74 68 65 20 76 69 72 74  running the virt
5a40: 75 61 6c 20 74 61 62 6c 65 0a 20 20 20 20 2a 2a  ual table.    **
5a50: 20 69 73 20 72 65 64 75 63 65 64 20 66 72 6f 6d   is reduced from
5a60: 20 31 20 6d 69 6c 6c 69 6f 6e 20 74 6f 20 6a 75   1 million to ju
5a70: 73 74 20 31 30 2e 20 20 54 68 65 20 63 6f 6e 73  st 10.  The cons
5a80: 74 72 61 69 6e 74 73 20 61 72 65 20 2a 6e 6f 74  traints are *not
5a90: 2a 20 6d 61 72 6b 65 64 0a 20 20 20 20 2a 2a 20  * marked.    ** 
5aa0: 61 73 20 6f 6d 69 74 74 61 62 6c 65 2c 20 68 6f  as omittable, ho
5ab0: 77 65 76 65 72 2c 20 73 6f 20 74 68 65 20 71 75  wever, so the qu
5ac0: 65 72 79 20 70 6c 61 6e 6e 65 72 20 73 68 6f 75  ery planner shou
5ad0: 6c 64 20 73 74 69 6c 6c 20 67 65 6e 65 72 61 74  ld still generat
5ae0: 65 20 61 0a 20 20 20 20 2a 2a 20 70 6c 61 6e 20  e a.    ** plan 
5af0: 74 68 61 74 20 67 69 76 65 73 20 61 20 63 6f 72  that gives a cor
5b00: 72 65 63 74 20 61 6e 73 77 65 72 2c 20 65 76 65  rect answer, eve
5b10: 6e 20 69 66 20 74 68 65 79 20 70 6c 61 6e 20 69  n if they plan i
5b20: 73 20 6e 6f 74 20 6f 70 74 69 6d 61 6c 2e 0a 20  s not optimal.. 
5b30: 20 20 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 3b     */.    int i;
5b40: 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6e 73 74 20  .    int nConst 
5b50: 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  = 0;.    for(i=0
5b60: 3b 20 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43  ; i<pIdxInfo->nC
5b70: 6f 6e 73 74 72 61 69 6e 74 3b 20 69 2b 2b 29 7b  onstraint; i++){
5b80: 0a 20 20 20 20 20 20 75 6e 73 69 67 6e 65 64 20  .      unsigned 
5b90: 63 68 61 72 20 6f 70 3b 0a 20 20 20 20 20 20 69  char op;.      i
5ba0: 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f  f( pIdxInfo->aCo
5bb0: 6e 73 74 72 61 69 6e 74 5b 69 5d 2e 75 73 61 62  nstraint[i].usab
5bc0: 6c 65 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65  le==0 ) continue
5bd0: 3b 0a 20 20 20 20 20 20 6f 70 20 3d 20 70 49 64  ;.      op = pId
5be0: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
5bf0: 6e 74 5b 69 5d 2e 6f 70 3b 0a 20 20 20 20 20 20  nt[i].op;.      
5c00: 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 49  if( op==SQLITE_I
5c10: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
5c20: 45 51 20 0a 20 20 20 20 20 20 20 7c 7c 20 6f 70  EQ .       || op
5c30: 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  ==SQLITE_INDEX_C
5c40: 4f 4e 53 54 52 41 49 4e 54 5f 4c 49 4b 45 0a 20  ONSTRAINT_LIKE. 
5c50: 20 20 20 20 20 20 7c 7c 20 6f 70 3d 3d 53 51 4c        || op==SQL
5c60: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
5c70: 41 49 4e 54 5f 47 4c 4f 42 0a 20 20 20 20 20 20  AINT_GLOB.      
5c80: 29 7b 0a 20 20 20 20 20 20 20 20 70 49 64 78 49  ){.        pIdxI
5c90: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
5ca0: 73 74 20 3d 20 31 30 3b 0a 20 20 20 20 20 20 20  st = 10;.       
5cb0: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73   pIdxInfo->aCons
5cc0: 74 72 61 69 6e 74 55 73 61 67 65 5b 6e 43 6f 6e  traintUsage[nCon
5cd0: 73 74 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20  st].argvIndex = 
5ce0: 6e 43 6f 6e 73 74 2b 31 3b 0a 20 20 20 20 20 20  nConst+1;.      
5cf0: 20 20 6e 43 6f 6e 73 74 2b 2b 3b 0a 20 20 20 20    nConst++;.    
5d00: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65    }.    }.  }.#e
5d10: 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 53 51  ndif.  return SQ
5d20: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 73 74 61  LITE_OK;.}...sta
5d30: 74 69 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75  tic sqlite3_modu
5d40: 6c 65 20 43 73 76 4d 6f 64 75 6c 65 20 3d 20 7b  le CsvModule = {
5d50: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
5d60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
5d70: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 63 73 76  Version */.  csv
5d80: 74 61 62 43 72 65 61 74 65 2c 20 20 20 20 20 20  tabCreate,      
5d90: 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65        /* xCreate
5da0: 20 2a 2f 0a 20 20 63 73 76 74 61 62 43 6f 6e 6e   */.  csvtabConn
5db0: 65 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ect,           /
5dc0: 2a 20 78 43 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20  * xConnect */.  
5dd0: 63 73 76 74 61 62 42 65 73 74 49 6e 64 65 78 2c  csvtabBestIndex,
5de0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73           /* xBes
5df0: 74 49 6e 64 65 78 20 2a 2f 0a 20 20 63 73 76 74  tIndex */.  csvt
5e00: 61 62 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20  abDisconnect,   
5e10: 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e       /* xDisconn
5e20: 65 63 74 20 2a 2f 0a 20 20 63 73 76 74 61 62 44  ect */.  csvtabD
5e30: 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20  isconnect,      
5e40: 20 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f    /* xDestroy */
5e50: 0a 20 20 63 73 76 74 61 62 4f 70 65 6e 2c 20 20  .  csvtabOpen,  
5e60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5e70: 4f 70 65 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75  Open - open a cu
5e80: 72 73 6f 72 20 2a 2f 0a 20 20 63 73 76 74 61 62  rsor */.  csvtab
5e90: 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20  Close,          
5ea0: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63     /* xClose - c
5eb0: 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  lose a cursor */
5ec0: 0a 20 20 63 73 76 74 61 62 46 69 6c 74 65 72 2c  .  csvtabFilter,
5ed0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5ee0: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
5ef0: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
5f00: 6e 74 73 20 2a 2f 0a 20 20 63 73 76 74 61 62 4e  nts */.  csvtabN
5f10: 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  ext,            
5f20: 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76    /* xNext - adv
5f30: 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  ance a cursor */
5f40: 0a 20 20 63 73 76 74 61 62 45 6f 66 2c 20 20 20  .  csvtabEof,   
5f50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5f60: 45 6f 66 20 2d 20 63 68 65 63 6b 20 66 6f 72 20  Eof - check for 
5f70: 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a 20  end of scan */. 
5f80: 20 63 73 76 74 61 62 43 6f 6c 75 6d 6e 2c 20 20   csvtabColumn,  
5f90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
5fa0: 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61  lumn - read data
5fb0: 20 2a 2f 0a 20 20 63 73 76 74 61 62 52 6f 77 69   */.  csvtabRowi
5fc0: 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  d,             /
5fd0: 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20  * xRowid - read 
5fe0: 64 61 74 61 20 2a 2f 0a 20 20 30 2c 20 20 20 20  data */.  0,    
5ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6000: 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f     /* xUpdate */
6010: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
6020: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6030: 42 65 67 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20  Begin */.  0,   
6040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6050: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a      /* xSync */.
6060: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
6070: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
6080: 6f 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20  ommit */.  0,   
6090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60a0: 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b      /* xRollback
60b0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
60c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
60d0: 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f  * xFindMethod */
60e0: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
60f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6100: 52 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 0a 23 69  Rename */.};..#i
6110: 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54  fdef SQLITE_TEST
6120: 0a 2f 2a 0a 2a 2a 20 46 6f 72 20 76 69 72 74 75  ./*.** For virtu
6130: 61 6c 20 74 61 62 6c 65 20 74 65 73 74 69 6e 67  al table testing
6140: 2c 20 6d 61 6b 65 20 61 20 76 65 72 73 69 6f 6e  , make a version
6150: 20 6f 66 20 74 68 65 20 43 53 56 20 76 69 72 74   of the CSV virt
6160: 75 61 6c 20 74 61 62 6c 65 0a 2a 2a 20 61 76 61  ual table.** ava
6170: 69 6c 61 62 6c 65 20 74 68 61 74 20 68 61 73 20  ilable that has 
6180: 61 6e 20 78 55 70 64 61 74 65 20 66 75 6e 63 74  an xUpdate funct
6190: 69 6f 6e 2e 20 20 42 75 74 20 74 68 65 20 78 55  ion.  But the xU
61a0: 70 64 61 74 65 20 61 6c 77 61 79 73 20 72 65 74  pdate always ret
61b0: 75 72 6e 73 0a 2a 2a 20 53 51 4c 49 54 45 5f 52  urns.** SQLITE_R
61c0: 45 41 44 4f 4e 4c 59 20 73 69 6e 63 65 20 74 68  EADONLY since th
61d0: 65 20 43 53 56 20 66 69 6c 65 20 69 73 20 6e 6f  e CSV file is no
61e0: 74 20 72 65 61 6c 6c 79 20 77 72 69 74 61 62 6c  t really writabl
61f0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
6200: 20 63 73 76 74 61 62 55 70 64 61 74 65 28 73 71   csvtabUpdate(sq
6210: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 2c 69 6e  lite3_vtab *p,in
6220: 74 20 6e 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75  t n,sqlite3_valu
6230: 65 2a 2a 76 2c 73 71 6c 69 74 65 33 5f 69 6e 74  e**v,sqlite3_int
6240: 36 34 2a 78 29 7b 0a 20 20 72 65 74 75 72 6e 20  64*x){.  return 
6250: 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b  SQLITE_READONLY;
6260: 0a 7d 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  .}.static sqlite
6270: 33 5f 6d 6f 64 75 6c 65 20 43 73 76 4d 6f 64 75  3_module CsvModu
6280: 6c 65 46 61 75 78 57 72 69 74 65 20 3d 20 7b 0a  leFauxWrite = {.
6290: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
62a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56             /* iV
62b0: 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 63 73 76 74  ersion */.  csvt
62c0: 61 62 43 72 65 61 74 65 2c 20 20 20 20 20 20 20  abCreate,       
62d0: 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20       /* xCreate 
62e0: 2a 2f 0a 20 20 63 73 76 74 61 62 43 6f 6e 6e 65  */.  csvtabConne
62f0: 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ct,           /*
6300: 20 78 43 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 63   xConnect */.  c
6310: 73 76 74 61 62 42 65 73 74 49 6e 64 65 78 2c 20  svtabBestIndex, 
6320: 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73 74          /* xBest
6330: 49 6e 64 65 78 20 2a 2f 0a 20 20 63 73 76 74 61  Index */.  csvta
6340: 62 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20  bDisconnect,    
6350: 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65      /* xDisconne
6360: 63 74 20 2a 2f 0a 20 20 63 73 76 74 61 62 44 69  ct */.  csvtabDi
6370: 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20 20  sconnect,       
6380: 20 2f 2a 20 78 44 65 73 74 72 6f 79 20 2a 2f 0a   /* xDestroy */.
6390: 20 20 63 73 76 74 61 62 4f 70 65 6e 2c 20 20 20    csvtabOpen,   
63a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f             /* xO
63b0: 70 65 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72  pen - open a cur
63c0: 73 6f 72 20 2a 2f 0a 20 20 63 73 76 74 61 62 43  sor */.  csvtabC
63d0: 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20  lose,           
63e0: 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c    /* xClose - cl
63f0: 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  ose a cursor */.
6400: 20 20 63 73 76 74 61 62 46 69 6c 74 65 72 2c 20    csvtabFilter, 
6410: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
6420: 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72  ilter - configur
6430: 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e  e scan constrain
6440: 74 73 20 2a 2f 0a 20 20 63 73 76 74 61 62 4e 65  ts */.  csvtabNe
6450: 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  xt,             
6460: 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61   /* xNext - adva
6470: 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  nce a cursor */.
6480: 20 20 63 73 76 74 61 62 45 6f 66 2c 20 20 20 20    csvtabEof,    
6490: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45             /* xE
64a0: 6f 66 20 2d 20 63 68 65 63 6b 20 66 6f 72 20 65  of - check for e
64b0: 6e 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20  nd of scan */.  
64c0: 63 73 76 74 61 62 43 6f 6c 75 6d 6e 2c 20 20 20  csvtabColumn,   
64d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c           /* xCol
64e0: 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20  umn - read data 
64f0: 2a 2f 0a 20 20 63 73 76 74 61 62 52 6f 77 69 64  */.  csvtabRowid
6500: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
6510: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
6520: 61 74 61 20 2a 2f 0a 20 20 63 73 76 74 61 62 55  ata */.  csvtabU
6530: 70 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  pdate,          
6540: 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f 0a    /* xUpdate */.
6550: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
6560: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42             /* xB
6570: 65 67 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20  egin */.  0,    
6580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6590: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20     /* xSync */. 
65a0: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
65b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
65c0: 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20 20  mmit */.  0,    
65d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65e0: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20     /* xRollback 
65f0: 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20  */.  0,         
6600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6610: 20 78 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a   xFindMethod */.
6620: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
6630: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
6640: 65 6e 61 6d 65 20 2a 2f 0a 7d 3b 0a 23 65 6e 64  ename */.};.#end
6650: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 54 45 53  if /* SQLITE_TES
6660: 54 20 2a 2f 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  T */..#endif /* 
6670: 21 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f  !defined(SQLITE_
6680: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
6690: 45 29 20 2a 2f 0a 0a 0a 23 69 66 64 65 66 20 5f  E) */...#ifdef _
66a0: 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65 63  WIN32.__declspec
66b0: 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e 64  (dllexport).#end
66c0: 69 66 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 72  if./* .** This r
66d0: 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64  outine is called
66e0: 20 77 68 65 6e 20 74 68 65 20 65 78 74 65 6e 73   when the extens
66f0: 69 6f 6e 20 69 73 20 6c 6f 61 64 65 64 2e 20 20  ion is loaded.  
6700: 54 68 65 20 6e 65 77 0a 2a 2a 20 43 53 56 20 76  The new.** CSV v
6710: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
6720: 75 6c 65 20 69 73 20 72 65 67 69 73 74 65 72 65  ule is registere
6730: 64 20 77 69 74 68 20 74 68 65 20 63 61 6c 6c 69  d with the calli
6740: 6e 67 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63  ng database.** c
6750: 6f 6e 6e 65 63 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e  onnection..*/.in
6760: 74 20 73 71 6c 69 74 65 33 5f 63 73 76 5f 69 6e  t sqlite3_csv_in
6770: 69 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  it(.  sqlite3 *d
6780: 62 2c 20 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  b, .  char **pzE
6790: 72 72 4d 73 67 2c 20 0a 20 20 63 6f 6e 73 74 20  rrMsg, .  const 
67a0: 73 71 6c 69 74 65 33 5f 61 70 69 5f 72 6f 75 74  sqlite3_api_rout
67b0: 69 6e 65 73 20 2a 70 41 70 69 0a 29 7b 0a 23 69  ines *pApi.){.#i
67c0: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
67d0: 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 09 0a  T_VIRTUALTABLE..
67e0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 53 51 4c 49    int rc;.  SQLI
67f0: 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49  TE_EXTENSION_INI
6800: 54 32 28 70 41 70 69 29 3b 0a 20 20 72 63 20 3d  T2(pApi);.  rc =
6810: 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f   sqlite3_create_
6820: 6d 6f 64 75 6c 65 28 64 62 2c 20 22 63 73 76 22  module(db, "csv"
6830: 2c 20 26 43 73 76 4d 6f 64 75 6c 65 2c 20 30 29  , &CsvModule, 0)
6840: 3b 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ;.#ifdef SQLITE_
6850: 54 45 53 54 0a 20 20 69 66 28 20 72 63 3d 3d 53  TEST.  if( rc==S
6860: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6870: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65  rc = sqlite3_cre
6880: 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22  ate_module(db, "
6890: 63 73 76 5f 77 72 22 2c 20 26 43 73 76 4d 6f 64  csv_wr", &CsvMod
68a0: 75 6c 65 46 61 75 78 57 72 69 74 65 2c 20 30 29  uleFauxWrite, 0)
68b0: 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 72  ;.  }.#endif.  r
68c0: 65 74 75 72 6e 20 72 63 3b 0a 23 65 6c 73 65 0a  eturn rc;.#else.
68d0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
68e0: 4f 4b 3b 0a 23 65 6e 64 69 66 0a 7d 0a           OK;.#endif.}.